🛰️航天仿真算法库 SpaceAST 0.3.1
载入中...
搜索中...
未找到
Any.hpp
浏览该文件的文档.
1
20
21#pragma once
22
23#include "AstGlobal.h"
24#include <cstddef>
25#include <new>
26#include <type_traits>
27#include <typeinfo>
28#include <utility>
29
30AST_NAMESPACE_BEGIN
31
37// Any 是重度模板/类型擦除的运行时容器(含 SFINAE 构造),SWIG 无法解析其签名,
38#ifndef SWIG
39
41class bad_any_cast : public std::bad_cast
42{
43public:
44 const char* what() const noexcept override
45 {
46 return "bad_any_cast";
47 }
48};
49
50
70class Any
71{
72public:
73 // ============================================================
74 // 构造 / 析构
75 // ============================================================
76
78 Any() noexcept = default;
79
81 Any(const Any& other)
82 {
83 copyFrom(other);
84 }
85
87 Any(Any&& other) noexcept
88 {
89 stealFrom(other);
90 }
91
92 ~Any() { reset(); }
93
95 template<typename ValueType,
96 typename D = typename std::decay<ValueType>::type,
97 typename std::enable_if<!std::is_same<D, Any>::value &&
98 std::is_copy_constructible<D>::value, int>::type = 0>
99 Any(ValueType&& value)
100 {
101 emplace<D>(std::forward<ValueType>(value));
102 }
103
104 // ============================================================
105 // 赋值
106 // ============================================================
107
109 Any& operator=(const Any& other)
110 {
111 if (this != &other)
112 {
113 Any tmp(other);
114 swap(tmp);
115 }
116 return *this;
117 }
118
120 Any& operator=(Any&& other) noexcept
121 {
122 if (this != &other)
123 {
124 reset();
125 stealFrom(other);
126 }
127 return *this;
128 }
129
131 template<typename ValueType,
132 typename D = typename std::decay<ValueType>::type,
133 typename std::enable_if<!std::is_same<D, Any>::value &&
134 std::is_copy_constructible<D>::value, int>::type = 0>
135 Any& operator=(ValueType&& value)
136 {
137 emplace<D>(std::forward<ValueType>(value));
138 return *this;
139 }
140
141 // ============================================================
142 // 观察
143 // ============================================================
144
146 bool has_value() const noexcept { return data_ != nullptr; }
147
149 const std::type_info& type() const noexcept
150 {
151 return data_ ? *ops_->type : typeid(void);
152 }
153
154 // ============================================================
155 // 修改
156 // ============================================================
157
159 void reset() noexcept
160 {
161 if (data_)
162 {
163 ops_->destroy(data_);
164 ::operator delete(data_);
165 data_ = nullptr;
166 ops_ = nullptr;
167 }
168 }
169
171 template<typename T, typename... Args>
172 typename std::enable_if<!std::is_reference<T>::value, T&>::type
173 emplace(Args&&... args)
174 {
175 reset();
176 void* storage = ::operator new(sizeof(T));
177 try
178 {
179 ::new (storage) T(std::forward<Args>(args)...);
180 }
181 catch (...)
182 {
183 ::operator delete(storage);
184 throw;
185 }
186 ops_ = &opsFor<T>();
187 data_ = storage;
188 return *static_cast<T*>(data_);
189 }
190
192 void swap(Any& other) noexcept
193 {
194 std::swap(ops_, other.ops_);
195 std::swap(data_, other.data_);
196 }
197
198private:
199 // ---- 类型擦除操作表 ----
200 struct TypeOps
201 {
202 void (*destroy)(void*);
203 void (*copyConstruct)(void* dst, const void* src);
204 const std::type_info* type;
205 size_t size;
206 };
207
208 template<typename T>
209 static const TypeOps& opsFor()
210 {
211 static const TypeOps ops = {
212 [](void* p) { static_cast<T*>(p)->~T(); },
213 [](void* dst, const void* src) { ::new (dst) T(*static_cast<const T*>(src)); },
214 &typeid(T),
215 sizeof(T),
216 };
217 return ops;
218 }
219
220 void copyFrom(const Any& other)
221 {
222 if (!other.data_)
223 return;
224 void* storage = ::operator new(other.ops_->size);
225 try
226 {
227 other.ops_->copyConstruct(storage, other.data_);
228 }
229 catch (...)
230 {
231 ::operator delete(storage);
232 throw;
233 }
234 ops_ = other.ops_;
235 data_ = storage;
236 }
237
238 void stealFrom(Any& other) noexcept
239 {
240 ops_ = other.ops_;
241 data_ = other.data_;
242 other.ops_ = nullptr;
243 other.data_ = nullptr;
244 }
245
246 // ---- 成员 ----
247 const TypeOps* ops_{nullptr};
248 void* data_{nullptr};
249
250 // 允许 any_cast 家族访问私有数据
251 template<typename T> friend const T* any_cast(const Any*) noexcept;
252 template<typename T> friend T* any_cast(Any*) noexcept;
253 template<typename T> friend T any_cast(const Any&);
254 template<typename T> friend T any_cast(Any&);
255 template<typename T> friend T any_cast(Any&&);
256};
257
258
259// ================================================================
260// any_cast — 类型安全的取回
261// ================================================================
262
264template<typename T>
265inline const T* any_cast(const Any* operand) noexcept
266{
267 using U = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
268 if (operand && operand->type() == typeid(U))
269 return static_cast<const T*>(operand->data_);
270 return nullptr;
271}
272
274template<typename T>
275inline T* any_cast(Any* operand) noexcept
276{
277 using U = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
278 if (operand && operand->type() == typeid(U))
279 return static_cast<T*>(operand->data_);
280 return nullptr;
281}
282
284template<typename T>
285inline T any_cast(const Any& operand)
286{
287 using U = typename std::decay<T>::type;
288 const U* p = any_cast<U>(&operand);
289 if (!p)
290 throw bad_any_cast();
291 return *p;
292}
293
295template<typename T>
296inline T any_cast(Any& operand)
297{
298 using U = typename std::decay<T>::type;
299 U* p = any_cast<U>(&operand);
300 if (!p)
301 throw bad_any_cast();
302 return *p;
303}
304
306template<typename T>
307inline T any_cast(Any&& operand)
308{
309 using U = typename std::decay<T>::type;
310 U* p = any_cast<U>(&operand);
311 if (!p)
312 throw bad_any_cast();
313 return static_cast<U&&>(*p);
314}
315
316
317// ================================================================
318// make_any — 便捷构造
319// ================================================================
320
322template<typename T, typename... Args>
323inline Any make_any(Args&&... args)
324{
325 Any a;
326 a.emplace<T>(std::forward<Args>(args)...);
327 return a;
328}
329
330#endif // SWIG
331
334AST_NAMESPACE_END
类型擦除的值容器,与 C++17 的 std::any 接口兼容
定义 Any.hpp:71
void swap(Any &other) noexcept
与之交换内容(常量时间,noexcept)
定义 Any.hpp:192
std::enable_if<!std::is_reference< T >::value, T & >::type emplace(Args &&... args)
以给定参数就地构造 T 并替换当前值;返回新值的引用
定义 Any.hpp:173
Any & operator=(Any &&other) noexcept
移动赋值:接管 other 的内容,other 变为空
定义 Any.hpp:120
const std::type_info & type() const noexcept
当前持有值的类型信息;空时返回 typeid(void)
定义 Any.hpp:149
Any & operator=(const Any &other)
拷贝赋值(copy-and-swap,强异常安全)
定义 Any.hpp:109
Any(ValueType &&value)
从任意可拷贝构造类型构造(类型被 decay)
定义 Any.hpp:99
Any(Any &&other) noexcept
移动构造:接管 other 的内容,other 变为空
定义 Any.hpp:87
Any() noexcept=default
默认构造:空
bool has_value() const noexcept
是否持有任一值
定义 Any.hpp:146
Any & operator=(ValueType &&value)
从任意可拷贝构造类型赋值(类型被 decay)
定义 Any.hpp:135
void reset() noexcept
丢弃当前值并置为空
定义 Any.hpp:159
any_cast 失败时抛出的异常
定义 Any.hpp:42
const T * any_cast(const Any *operand) noexcept
探测式取回(const):类型匹配时返回指针,否则 nullptr
定义 Any.hpp:265
Any make_any(Args &&... args)
生成一个持有 T 的 Any
定义 Any.hpp:323
A_ALWAYS_INLINE void swap(Thread &lhs, Thread &rhs) noexcept
交换两个线程对象
定义 Thread.hpp:82
Unit T
特斯拉
定义 Unit.cpp:492