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