🛰️航天仿真算法库 SpaceAST 0.0.1
载入中...
搜索中...
未找到
VariantVector.hpp
浏览该文件的文档.
1
21
22#pragma once
23
24#include "AstGlobal.h"
25#include "Span.hpp"
26
27#include <typeinfo>
28#include <new>
29#include <cassert>
30#include <stdexcept>
31#include <utility>
32#include <cstddef>
33#include <climits>
34#include <vector>
35
36AST_NAMESPACE_BEGIN
37
58class AST_UTIL_API VariantVector
59{
60public:
61 // ---- 类型操作表(前置声明,定义见类外)----
62 struct TypeOps;
63
64private:
65 // ---- 分配头:嵌入在 data_ 指向的分配块前方 ----
66 struct alignas(std::max_align_t) Header
67 {
68 const TypeOps* ops;
69 const std::type_info* typeInfo;
70 size_t elementSize;
71 };
72
73 static constexpr size_t kHeaderSize = sizeof(Header);
74
75 // ---- 成员 ----
76 void* data_{nullptr};
77 size_t size_{0};
78 size_t capacity_{0};
79
80public:
81 // ============================================================
82 // 构造 / 析构
83 // ============================================================
84
85 VariantVector() noexcept = default;
87
88 VariantVector(const VariantVector& other);
89 VariantVector& operator=(const VariantVector& other);
90
91 VariantVector(VariantVector&& other) noexcept;
92 VariantVector& operator=(VariantVector&& other) noexcept;
93
94 // ============================================================
95 // 容量
96 // ============================================================
97
98 size_t size() const noexcept { return size_; }
99 size_t capacity() const noexcept { return capacity_; }
100 bool empty() const noexcept { return size_ == 0; }
101
102 // ============================================================
103 // 类型信息
104 // ============================================================
105
107 const std::type_info& elementType() const noexcept;
108
110 bool hasType() const noexcept { return data_ != nullptr; }
111
113 size_t elementSize() const noexcept
114 {
115 return data_ ? header()->elementSize : 0;
116 }
117
119 const TypeOps* ops() const noexcept
120 {
121 return data_ ? header()->ops : nullptr;
122 }
123
124 // ============================================================
125 // 原始数据访问
126 // ============================================================
127
128 void* data() noexcept { return data_; }
129 const void* data() const noexcept { return data_; }
130
131 // ============================================================
132 // 修改器(模板,首次调用捕获类型)
133 // ============================================================
134
135 template<typename T>
136 void reserve(size_t n);
137
138 template<typename T>
139 void resize(size_t n);
140
141 template<typename T>
142 void resize(size_t n, const T& value);
143
145 template<typename T>
146 void reset(size_t n);
147
149 template<typename T>
150 void reset(size_t n, const T& value);
151
152 template<typename T>
153 void pushBack(const T& value);
154
155 template<typename T, typename... Args>
156 void emplaceBack(Args&&... args);
157
158 void clear();
159 void shrinkToFit();
160
161 // ============================================================
162 // 元素访问(模板,运行时校验类型)
163 // ============================================================
164
170 template<typename T>
171 T* as();
172
173 template<typename T>
174 const T* as() const;
175
181 template<typename T>
182 Span<T> asSpan();
183
184 template<typename T>
185 Span<const T> asSpan() const;
186
188 template<typename T>
189 T& at(size_t i);
190
191 template<typename T>
192 const T& at(size_t i) const;
193
194 // ============================================================
195 // 迭代器(模板)
196 // ============================================================
197
198 template<typename T>
199 T* begin();
200
201 template<typename T>
202 const T* begin() const;
203
204 template<typename T>
205 T* end();
206
207 template<typename T>
208 const T* end() const;
209
210 // ============================================================
211 // 交换
212 // ============================================================
213
214 void swap(VariantVector& other) noexcept;
215
216 // ============================================================
217 // 便捷构造
218 // ============================================================
219
220 template<typename T>
221 static VariantVector fromVector(const std::vector<T>& vec);
222
223private:
224 // ---- 底层操作 ----
225
226 void destroy() noexcept;
227 void copyFrom(const VariantVector& other);
228 void moveFrom(VariantVector& other) noexcept;
229
230 Header* header() noexcept;
231 const Header* header() const noexcept;
232
236 template<typename T>
237 void ensureType();
238};
239
240
241// ================================================================
242// TypeOps — 类型擦除操作表
243// ================================================================
244
246{
247 void (*destroy)(void* data, size_t count);
248 void (*copyConstruct)(void* dst, const void* src, size_t count);
249 void (*moveConstruct)(void* dst, void* src, size_t count);
250
252 template<typename T>
253 static const TypeOps& forType()
254 {
255 static const TypeOps ops = {
256 // destroy — 析构 count 个元素
257 [](void* data, size_t count) {
258 T* p = static_cast<T*>(data);
259 for (size_t i = 0; i < count; ++i)
260 p[i].~T();
261 },
262 // copyConstruct — 从 src 拷贝构造 count 个元素到 dst
263 [](void* dst, const void* src, size_t count) {
264 const T* s = static_cast<const T*>(src);
265 T* d = static_cast<T*>(dst);
266 for (size_t i = 0; i < count; ++i)
267 ::new (static_cast<void*>(&d[i])) T(s[i]);
268 },
269 // moveConstruct — 从 src 移动构造 count 个元素到 dst
270 [](void* dst, void* src, size_t count) {
271 T* s = static_cast<T*>(src);
272 T* d = static_cast<T*>(dst);
273 for (size_t i = 0; i < count; ++i)
274 ::new (static_cast<void*>(&d[i])) T(std::move(s[i]));
275 },
276 };
277 return ops;
278 }
279};
280
281
282// ================================================================
283// Header 内联访问器
284// ================================================================
285
286inline VariantVector::Header* VariantVector::header() noexcept
287{
288 assert(data_ != nullptr);
289 return reinterpret_cast<Header*>(static_cast<char*>(data_) - kHeaderSize);
290}
291
292inline const VariantVector::Header* VariantVector::header() const noexcept
293{
294 assert(data_ != nullptr);
295 return reinterpret_cast<const Header*>(static_cast<const char*>(data_) - kHeaderSize);
296}
297
298
299// ================================================================
300// 模板方法实现
301// ================================================================
302
303// ---- ensureType ----
304
305template<typename T>
306inline void VariantVector::ensureType()
307{
308 if (data_ != nullptr)
309 {
310 // 已有类型:校验一致(operator== 语义比较,跨 DLL 安全)
311 assert(*header()->typeInfo == typeid(T) && "VariantVector: type mismatch");
312 return;
313 }
314
315 // 首次确定类型:仅分配 Header,尚无元素空间
316 const TypeOps& typeOps = TypeOps::forType<T>();
317 void* block = ::operator new(kHeaderSize);
318 ::new (block) Header{&typeOps, &typeid(T), sizeof(T)};
319 data_ = static_cast<char*>(block) + kHeaderSize;
320 // size_ 和 capacity_ 保持 0(由默认构造保证)
321}
322
323// ---- reserve ----
324
325template<typename T>
326inline void VariantVector::reserve(size_t n)
327{
328 ensureType<T>();
329
330 if (n <= capacity_)
331 return;
332
333 const Header* oldHeader = header();
334 size_t elemSize = oldHeader->elementSize;
335
336 // 检查整数溢出:n * elemSize 不能超过 SIZE_MAX - kHeaderSize
337 if (n > (SIZE_MAX - kHeaderSize) / elemSize)
338 throw std::length_error("VariantVector::reserve: requested size exceeds max_size");
339
340 size_t offset = kHeaderSize;
341 size_t newBlockSize = offset + n * elemSize;
342 char* newBlock = static_cast<char*>(::operator new(newBlockSize));
343
344 // 拷贝 Header 到新块
345 ::new (newBlock) Header(*oldHeader);
346
347 // move 已有元素到新块
348 char* newDataPtr = newBlock + offset;
349 if (size_ > 0)
350 {
351 try
352 {
353 oldHeader->ops->moveConstruct(newDataPtr, data_, size_);
354 }
355 catch (...)
356 {
357 ::operator delete(static_cast<void*>(newBlock));
358 throw;
359 }
360 }
361
362 // 析构旧元素并释放旧块
363 char* oldBlock = static_cast<char*>(data_) - offset;
364 if (size_ > 0)
365 oldHeader->ops->destroy(data_, size_);
366 ::operator delete(static_cast<void*>(oldBlock));
367
368 // 更新指针
369 data_ = newDataPtr;
370 capacity_ = n;
371}
372
373// ---- resize (n) ----
374
375template<typename T>
376inline void VariantVector::resize(size_t n)
377{
378 ensureType<T>();
379 reserve<T>(n);
380
381 if (n > size_)
382 {
383 // 默认构造新增元素(每成功构造一个立即递增 size_,异常安全)
384 T* p = static_cast<T*>(data_);
385 while (size_ < n)
386 {
387 ::new (static_cast<void*>(&p[size_])) T();
388 ++size_;
389 }
390 }
391 else if (n < size_)
392 {
393 // 析构多余元素
394 T* p = static_cast<T*>(data_);
395 for (size_t i = n; i < size_; ++i)
396 p[i].~T();
397 size_ = n;
398 }
399}
400
401// ---- resize (n, value) ----
402
403template<typename T>
404inline void VariantVector::resize(size_t n, const T& value)
405{
406 ensureType<T>();
407 reserve<T>(n);
408
409 if (n > size_)
410 {
411 // 拷贝构造新增元素(每成功构造一个立即递增 size_,异常安全)
412 T* p = static_cast<T*>(data_);
413 while (size_ < n)
414 {
415 ::new (static_cast<void*>(&p[size_])) T(value);
416 ++size_;
417 }
418 }
419 else if (n < size_)
420 {
421 // 析构多余元素
422 T* p = static_cast<T*>(data_);
423 for (size_t i = n; i < size_; ++i)
424 p[i].~T();
425 size_ = n;
426 }
427}
428
429// ---- reset ----
430
431template<typename T>
432inline void VariantVector::reset(size_t n)
433{
434 destroy();
435 ensureType<T>();
436 reserve<T>(n);
437
438 T* p = static_cast<T*>(data_);
439 while (size_ < n)
440 {
441 ::new (static_cast<void*>(&p[size_])) T();
442 ++size_;
443 }
444}
445
446template<typename T>
447inline void VariantVector::reset(size_t n, const T& value)
448{
449 destroy();
450 ensureType<T>();
451 reserve<T>(n);
452
453 T* p = static_cast<T*>(data_);
454 while (size_ < n)
455 {
456 ::new (static_cast<void*>(&p[size_])) T(value);
457 ++size_;
458 }
459}
460
461// ---- pushBack ----
462
463template<typename T>
464inline void VariantVector::pushBack(const T& value)
465{
466 ensureType<T>();
467
468 if (size_ >= capacity_)
469 {
470 size_t newCap = (capacity_ == 0) ? 1 :
471 (capacity_ > SIZE_MAX / 2) ? SIZE_MAX : capacity_ * 2;
472 reserve<T>(newCap);
473 }
474
475 T* p = static_cast<T*>(data_);
476 ::new (static_cast<void*>(&p[size_])) T(value);
477 ++size_;
478}
479
480// ---- emplaceBack ----
481
482template<typename T, typename... Args>
483inline void VariantVector::emplaceBack(Args&&... args)
484{
485 ensureType<T>();
486
487 if (size_ >= capacity_)
488 {
489 size_t newCap = (capacity_ == 0) ? 1 :
490 (capacity_ > SIZE_MAX / 2) ? SIZE_MAX : capacity_ * 2;
491 reserve<T>(newCap);
492 }
493
494 T* p = static_cast<T*>(data_);
495 ::new (static_cast<void*>(&p[size_])) T(std::forward<Args>(args)...);
496 ++size_;
497}
498
499// ---- at ----
500
501template<typename T>
502inline T& VariantVector::at(size_t i)
503{
504 if (data_ == nullptr)
505 throw std::logic_error("VariantVector::at: vector has no type set");
506
507 if (*header()->typeInfo != typeid(T))
508 throw std::logic_error("VariantVector::at: type mismatch");
509
510 if (i >= size_)
511 throw std::out_of_range("VariantVector::at: index out of range");
512
513 return static_cast<T*>(data_)[i];
514}
515
516template<typename T>
517inline const T& VariantVector::at(size_t i) const
518{
519 if (data_ == nullptr)
520 throw std::logic_error("VariantVector::at: vector has no type set");
521
522 if (*header()->typeInfo != typeid(T))
523 throw std::logic_error("VariantVector::at: type mismatch");
524
525 if (i >= size_)
526 throw std::out_of_range("VariantVector::at: index out of range");
527
528 return static_cast<const T*>(data_)[i];
529}
530
531// ---- as ----
532
533template<typename T>
534inline T* VariantVector::as()
535{
536 if (data_ == nullptr) return nullptr;
537 if (*header()->typeInfo != typeid(T)) return nullptr;
538 return static_cast<T*>(data_);
539}
540
541template<typename T>
542inline const T* VariantVector::as() const
543{
544 if (data_ == nullptr) return nullptr;
545 if (*header()->typeInfo != typeid(T)) return nullptr;
546 return static_cast<const T*>(data_);
547}
548
549// ---- asSpan ----
550
551template<typename T>
552inline Span<T> VariantVector::asSpan()
553{
554 if (data_ == nullptr) return Span<T>();
555 if (*header()->typeInfo != typeid(T)) return Span<T>();
556 return Span<T>(static_cast<T*>(data_), size_);
557}
558
559template<typename T>
560inline Span<const T> VariantVector::asSpan() const
561{
562 if (data_ == nullptr) return Span<const T>();
563 if (*header()->typeInfo != typeid(T)) return Span<const T>();
564 return Span<const T>(static_cast<const T*>(data_), size_);
565}
566
567// ---- begin / end ----
568
569template<typename T>
570inline T* VariantVector::begin()
571{
572 if (data_ == nullptr) return nullptr;
573 if (*header()->typeInfo != typeid(T)) return nullptr;
574 return static_cast<T*>(data_);
575}
576
577template<typename T>
578inline const T* VariantVector::begin() const
579{
580 if (data_ == nullptr) return nullptr;
581 if (*header()->typeInfo != typeid(T)) return nullptr;
582 return static_cast<const T*>(data_);
583}
584
585template<typename T>
586inline T* VariantVector::end()
587{
588 if (data_ == nullptr) return nullptr;
589 if (*header()->typeInfo != typeid(T)) return nullptr;
590 return static_cast<T*>(data_) + size_;
591}
592
593template<typename T>
594inline const T* VariantVector::end() const
595{
596 if (data_ == nullptr) return nullptr;
597 if (*header()->typeInfo != typeid(T)) return nullptr;
598 return static_cast<const T*>(data_) + size_;
599}
600
601// ---- fromVector ----
602
603template<typename T>
604inline VariantVector VariantVector::fromVector(const std::vector<T>& vec)
605{
606 VariantVector v;
607 v.ensureType<T>();
608 v.reserve<T>(vec.size());
609
610 // 拷贝构造每个元素(只构造一次)
611 T* dst = static_cast<T*>(v.data_);
612 for (size_t i = 0; i < vec.size(); ++i)
613 {
614 ::new (static_cast<void*>(&dst[i])) T(vec[i]);
615 ++v.size_;
616 }
617 return v;
618}
619
620
623AST_NAMESPACE_END
Unit s
定义 Unit.cpp:435
非拥有的连续对象序列视图
定义 Span.hpp:71
变类型向量容器
定义 VariantVector.hpp:59
const TypeOps * ops() const noexcept
获取 TypeOps 指针(未设置类型时返回 nullptr)
定义 VariantVector.hpp:119
bool hasType() const noexcept
是否已设置类型(即 data_ != nullptr)
定义 VariantVector.hpp:110
size_t elementSize() const noexcept
元素大小(未设置类型时返回 0)
定义 VariantVector.hpp:113
定义 VariantVector.hpp:246
static const TypeOps & forType()
获取类型 T 对应的 TypeOps 单例
定义 VariantVector.hpp:253