NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
utility/any.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_UTILITY_ANY_HPP__
2#define NEFORCE_CORE_UTILITY_ANY_HPP__
3
10
11#include <initializer_list>
12#include <typeinfo>
15NEFORCE_BEGIN_NAMESPACE__
16
17class NEFORCE_API any;
18
20
21NEFORCE_BEGIN_INNER__
22
23struct any_cast_true_tag {};
24struct any_cast_false_tag {};
25
33template <typename T, typename U>
34const T* __any_cast_aux_dispatch_impl(const _NEFORCE any* value, any_cast_true_tag /*unused*/) noexcept;
35
36NEFORCE_END_INNER__
38
44
49struct anycast_exception final : typecast_exception {
50 explicit anycast_exception(const char* info = "Cast From any Type Failed.") noexcept :
51 typecast_exception(info) {}
52
53 explicit anycast_exception(const exception& e) :
54 typecast_exception(e) {}
55
56 ~anycast_exception() override = default;
57
58 NEFORCE_NODISCARD const char* type() const noexcept override { return "anycast_exception"; }
59};
60 // Exceptions
62
68
76class NEFORCE_API any {
83 union storage_internal {
84 storage_internal() = default;
85 storage_internal(const storage_internal&) = delete;
86 storage_internal& operator=(const storage_internal&) = delete;
87
88 void* ptr_ = nullptr;
89 aligned_storage_t<sizeof(ptr_), alignof(void*)> buffer_;
90 };
91
98 enum any_operation {
99 ACCESS,
100 GET_TYPE_INFO,
101 COPY,
102 DESTROY,
103 SWAP
104 };
105
112 union ArgT {
113 void* obj_ptr_;
114 const std::type_info* type_ptr_;
115 any* any_ptr_;
116 };
117
125 template <typename T>
126 struct internal_manage {
133 static void manage(any_operation op, const any* value, ArgT* arg);
134
141 template <typename... Args>
142 static void create(storage_internal& storage, Args&&... args) {
143 void* ptr = &storage.buffer_;
144 new (ptr) T(_NEFORCE forward<Args>(args)...);
145 }
146
152 static T* access(const storage_internal& storage) {
153 const void* ptr = &storage.buffer_;
154 return static_cast<T*>(const_cast<void*>(ptr));
155 }
156 };
157
165 template <typename T>
166 struct external_manage {
173 static void manage(any_operation op, const any* value, ArgT* arg);
174
181 template <typename... Args>
182 static void create(storage_internal& storage, Args&&... args) {
183 storage.ptr_ = new T(_NEFORCE forward<Args>(args)...);
184 }
185
191 static T* access(const storage_internal& storage) { return static_cast<T*>(storage.ptr_); }
192 };
193
200 template <typename T>
201 using manage_t = conditional_t<is_nothrow_move_constructible_v<T> && sizeof(T) <= sizeof(storage_internal) &&
202 alignof(T) <= alignof(storage_internal),
203 internal_manage<T>, external_manage<T>>;
204
205 using manage_func = void (*)(any_operation, const any*, ArgT*);
206
207 manage_func manage_ = nullptr;
208 storage_internal storage_;
209
210 template <typename T, typename U>
211 friend const T* inner::__any_cast_aux_dispatch_impl(const any* value, inner::any_cast_true_tag /*unused*/) noexcept;
212
220 template <typename T, typename... Args, typename Manager = manage_t<T>>
221 void try_emplace(Args&&... args) {
222 any::reset();
223 Manager::create(storage_, _NEFORCE forward<Args>(args)...);
224 manage_ = &Manager::manage;
225 }
226
236 template <typename T, typename U, typename... Args, typename Manager = manage_t<T>>
237 void try_emplace(std::initializer_list<U> ilist, Args&&... args) {
238 any::reset();
239 Manager::create(storage_, ilist, _NEFORCE forward<Args>(args)...);
240 manage_ = &Manager::manage;
241 }
242
243public:
247 any() noexcept = default;
248
253 any(const any& other);
254
261 any& operator=(const any& other) {
262 *this = any(other);
263 return *this;
264 }
265
270 any(any&& other) noexcept;
271
277 any& operator=(any&& other) noexcept;
278
284 template <typename T, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
285 enable_if_t<is_copy_constructible_v<VT> && !is_same_v<inplace_construct_tag, VT> && !is_same_v<VT, any>,
286 int> = 0>
287 explicit any(T&& value) :
288 manage_(&Manager::manage) {
289 Manager::create(storage_, _NEFORCE forward<T>(value));
290 }
291
298 template <typename T, typename VT = decay_t<T>,
299 enable_if_t<!is_same_v<VT, any> && is_copy_constructible_v<VT>, int> = 0>
300 any& operator=(T&& value) {
301 *this = any(_NEFORCE forward<T>(value));
302 return *this;
303 }
304
311 template <typename T, typename... Args, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
313 explicit any(pass_template_construct_tag<T> /*unused*/, Args&&... args) :
314 manage_(&Manager::manage) {
315 Manager::create(storage_, _NEFORCE forward<Args>(args)...);
316 }
317
318 template <typename T, typename U, typename... Args, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
321 int> = 0>
322 explicit any(pass_template_construct_tag<T> /*unused*/, std::initializer_list<U> ilist, Args&&... args) :
323 manage_(&Manager::manage) {
324 Manager::create(storage_, ilist, _NEFORCE forward<Args>(args)...);
325 }
326
330 ~any() { reset(); }
331
339 template <typename T, typename... Args, typename DT = decay_t<T>,
341 DT& emplace(Args&&... args) {
342 any::try_emplace<DT>(_NEFORCE forward<Args>(args)...);
343 return *manage_t<DT>::access(storage_);
344 }
345
355 template <typename T, typename U, typename... Args, typename DT = decay_t<T>,
358 int> = 0>
359 DT& emplace(std::initializer_list<U> ilist, Args&&... args) {
360 any::try_emplace<DT, U>(ilist, _NEFORCE forward<Args>(args)...);
361 return *manage_t<DT>::access(storage_);
362 }
363
367 void reset() noexcept {
368 if (has_value()) {
369 manage_(DESTROY, this, nullptr);
370 manage_ = nullptr;
371 }
372 }
373
378 NEFORCE_NODISCARD bool has_value() const noexcept { return manage_ != nullptr; }
379
384 NEFORCE_NODISCARD const std::type_info& type() const noexcept;
385
390 void swap(any& rhs) noexcept;
391};
392
400template <typename T, typename... Args,
402any make_any(Args&&... args) {
403 return any(pass_template_construct_tag<T>{}, _NEFORCE forward<Args>(args)...);
404}
405
407NEFORCE_BEGIN_INNER__
408
409template <typename T, typename U>
410const T* __any_cast_aux_dispatch_impl(const any* value, any_cast_true_tag /*unused*/) noexcept {
411 if (value->manage_ == &any::manage_t<U>::manage) {
412 return static_cast<const T*>(any::manage_t<U>::access(value->storage_));
413 }
414 return nullptr;
415}
416
417template <typename T, typename U>
418const T* __any_cast_aux_dispatch_impl(const any* /*unused*/, any_cast_false_tag /*unused*/) noexcept {
419 return nullptr;
420}
421
422template <typename T, typename U>
423const T* __any_cast_aux_dispatch(const any* value) noexcept {
424 using tag = conditional_t<(is_same_v<decay_t<U>, U> || is_copy_constructible_v<U>), any_cast_true_tag,
425 any_cast_false_tag>;
426 return inner::__any_cast_aux_dispatch_impl<T, U>(value, tag{});
427}
428
429template <typename T, enable_if_t<is_object_v<T>, int> = 0>
430const T* __any_cast_aux(const any* value) noexcept {
431 if (value) {
432 return __any_cast_aux_dispatch<T, remove_cv_t<T>>(value);
433 }
434 return nullptr;
435}
436
437template <typename T, enable_if_t<!is_object_v<T>, int> = 0>
438const T* __any_cast_aux(const any* /*unused*/) noexcept {
439 return nullptr;
440}
441
442NEFORCE_END_INNER__
444
451template <typename T>
452const T* any_cast(const any* value) noexcept {
453 return inner::__any_cast_aux<T>(value);
454}
455
462template <typename T>
463T* any_cast(any* value) noexcept {
464 return const_cast<T*>(any_cast<T>(const_cast<const any*>(value)));
465}
466
474template <typename T>
475T any_cast(const any& value) {
476 using U = remove_cvref_t<T>;
478 "type T must be valid to cast from any.");
479
480 auto ptr = any_cast<U>(&value);
481 if (ptr != nullptr) {
482 return static_cast<T>(*ptr);
483 }
484 NEFORCE_THROW_EXCEPTION(anycast_exception());
485 unreachable();
486}
487
488
490
491template <typename T>
492void any::internal_manage<T>::manage(const any_operation op, const any* value, ArgT* arg) {
493 auto ptr = reinterpret_cast<const T*>(&value->storage_.buffer_);
494 switch (op) {
495 case ACCESS: {
496 arg->obj_ptr_ = const_cast<T*>(ptr);
497 break;
498 }
499 case GET_TYPE_INFO: {
500 arg->type_ptr_ = &typeid(T);
501 break;
502 }
503 case COPY: {
504 ::new (&arg->any_ptr_->storage_.buffer_) T(*ptr);
505 arg->any_ptr_->manage_ = value->manage_;
506 break;
507 }
508 case DESTROY: {
509 ptr->~T();
510 break;
511 }
512 case SWAP: {
513 ::new (&arg->any_ptr_->storage_.buffer_) T(_NEFORCE move(*const_cast<T*>(ptr)));
514 ptr->~T();
515 arg->any_ptr_->manage_ = value->manage_;
516 const_cast<any*>(value)->manage_ = nullptr;
517 break;
518 }
519 default: {
520 unreachable();
521 }
522 }
523}
524
525template <typename T>
526void any::external_manage<T>::manage(const any_operation op, const any* value, ArgT* arg) {
527 auto ptr = static_cast<const T*>(value->storage_.ptr_);
528 switch (op) {
529 case ACCESS: {
530 arg->obj_ptr_ = const_cast<T*>(ptr);
531 break;
532 }
533 case GET_TYPE_INFO: {
534 arg->type_ptr_ = &typeid(T);
535 break;
536 }
537 case COPY: {
538 arg->any_ptr_->storage_.ptr_ = ::new T(*ptr);
539 arg->any_ptr_->manage_ = value->manage_;
540 break;
541 }
542 case DESTROY: {
543 delete ptr;
544 break;
545 }
546 case SWAP: {
547 arg->any_ptr_->storage_.ptr_ = value->storage_.ptr_;
548 arg->any_ptr_->manage_ = value->manage_;
549 const_cast<any*>(value)->manage_ = nullptr;
550 break;
551 }
552 default: {
553 unreachable();
554 }
555 }
556}
557
559 // Any
561
562NEFORCE_END_NAMESPACE__
563#endif // NEFORCE_CORE_UTILITY_ANY_HPP__
任意类型容器
DT & emplace(std::initializer_list< U > ilist, Args &&... args)
使用初始化列表就地构造
any & operator=(any &&other) noexcept
移动赋值运算符
void reset() noexcept
重置any对象为空
const std::type_info & type() const noexcept
获取存储值的类型信息
bool has_value() const noexcept
检查是否包含值
any & operator=(T &&value)
从值赋值
any() noexcept=default
默认构造函数
~any()
析构函数
any(T &&value)
从值构造
void swap(any &rhs) noexcept
交换两个any对象
any & operator=(const any &other)
复制赋值运算符
any(any &&other) noexcept
移动构造函数
any(pass_template_construct_tag< T >, Args &&... args)
就地构造
DT & emplace(Args &&... args)
就地构造值
调试断点和断言工具
异常处理框架
typename aligned_storage< Len, Align >::type aligned_storage_t
aligned_storage的便捷别名
const T * any_cast(const any *value) noexcept
从any对象转换常量值
any make_any(Args &&... args)
创建any对象
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
void unreachable() noexcept
标记不可达代码路径
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
typename decay< T >::type decay_t
decay的便捷别名
constexpr bool is_constructible_v
is_constructible的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
constexpr bool disjunction_v
disjunction的便捷变量模板
const char * type() const noexcept override
获取异常类型
判断类型是否可以使用指定参数构造
判断类型是否可复制构造