NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
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.", const char* type = static_type,
51 const int code = 0) noexcept :
52 typecast_exception(info, type, code) {}
53
54 explicit anycast_exception(const exception& e) :
55 typecast_exception(e) {}
56
57 ~anycast_exception() override = default;
58
59 static constexpr auto static_type = "anycast_exception";
60};
61 // Exceptions
63
69
77class NEFORCE_API any {
84 union storage_internal {
85 storage_internal() = default;
86 storage_internal(const storage_internal&) = delete;
87 storage_internal& operator=(const storage_internal&) = delete;
88
89 void* ptr_ = nullptr;
90 aligned_storage_t<sizeof(ptr_), alignof(void*)> buffer_;
91 };
92
99 enum any_operation {
100 ACCESS,
101 GET_TYPE_INFO,
102 COPY,
103 DESTROY,
104 SWAP
105 };
106
113 union ArgT {
114 void* obj_ptr_;
115 const std::type_info* type_ptr_;
116 any* any_ptr_;
117 };
118
126 template <typename T>
127 struct internal_manage {
134 static void manage(any_operation op, const any* value, ArgT* arg);
135
142 template <typename... Args>
143 static void create(storage_internal& storage, Args&&... args) {
144 void* ptr = &storage.buffer_;
145 new (ptr) T(_NEFORCE forward<Args>(args)...);
146 }
147
153 static T* access(const storage_internal& storage) {
154 const void* ptr = &storage.buffer_;
155 return static_cast<T*>(const_cast<void*>(ptr));
156 }
157 };
158
166 template <typename T>
167 struct external_manage {
174 static void manage(any_operation op, const any* value, ArgT* arg);
175
182 template <typename... Args>
183 static void create(storage_internal& storage, Args&&... args) {
184 storage.ptr_ = new T(_NEFORCE forward<Args>(args)...);
185 }
186
192 static T* access(const storage_internal& storage) { return static_cast<T*>(storage.ptr_); }
193 };
194
201 template <typename T>
202 using manage_t = conditional_t<is_nothrow_move_constructible_v<T> && sizeof(T) <= sizeof(storage_internal) &&
203 alignof(T) <= alignof(storage_internal),
204 internal_manage<T>, external_manage<T>>;
205
206 using manage_func = void (*)(any_operation, const any*, ArgT*);
207
208 manage_func manage_ = nullptr;
209 storage_internal storage_;
210
211 template <typename T, typename U>
212 friend const T* inner::__any_cast_aux_dispatch_impl(const any* value, inner::any_cast_true_tag /*unused*/) noexcept;
213
221 template <typename T, typename... Args, typename Manager = manage_t<T>>
222 void try_emplace(Args&&... args) {
223 any::reset();
224 Manager::create(storage_, _NEFORCE forward<Args>(args)...);
225 manage_ = &Manager::manage;
226 }
227
237 template <typename T, typename U, typename... Args, typename Manager = manage_t<T>>
238 void try_emplace(std::initializer_list<U> ilist, Args&&... args) {
239 any::reset();
240 Manager::create(storage_, ilist, _NEFORCE forward<Args>(args)...);
241 manage_ = &Manager::manage;
242 }
243
244public:
248 any() noexcept = default;
249
254 any(const any& other);
255
262 any& operator=(const any& other) {
263 *this = any(other);
264 return *this;
265 }
266
271 any(any&& other) noexcept;
272
278 any& operator=(any&& other) noexcept;
279
285 template <typename T, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
286 enable_if_t<is_copy_constructible_v<VT> && !is_same_v<inplace_construct_tag, VT> && !is_same_v<VT, any>,
287 int> = 0>
288 explicit any(T&& value) :
289 manage_(&Manager::manage) {
290 Manager::create(storage_, _NEFORCE forward<T>(value));
291 }
292
299 template <typename T, typename VT = decay_t<T>,
300 enable_if_t<!is_same_v<VT, any> && is_copy_constructible_v<VT>, int> = 0>
301 any& operator=(T&& value) {
302 *this = any(_NEFORCE forward<T>(value));
303 return *this;
304 }
305
312 template <typename T, typename... Args, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
314 explicit any(pass_template_construct_tag<T> /*unused*/, Args&&... args) :
315 manage_(&Manager::manage) {
316 Manager::create(storage_, _NEFORCE forward<Args>(args)...);
317 }
318
319 template <typename T, typename U, typename... Args, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
322 int> = 0>
323 explicit any(pass_template_construct_tag<T> /*unused*/, std::initializer_list<U> ilist, Args&&... args) :
324 manage_(&Manager::manage) {
325 Manager::create(storage_, ilist, _NEFORCE forward<Args>(args)...);
326 }
327
331 ~any() { reset(); }
332
340 template <typename T, typename... Args, typename DT = decay_t<T>,
342 DT& emplace(Args&&... args) {
343 any::try_emplace<DT>(_NEFORCE forward<Args>(args)...);
344 return *manage_t<DT>::access(storage_);
345 }
346
356 template <typename T, typename U, typename... Args, typename DT = decay_t<T>,
359 int> = 0>
360 DT& emplace(std::initializer_list<U> ilist, Args&&... args) {
361 any::try_emplace<DT, U>(ilist, _NEFORCE forward<Args>(args)...);
362 return *manage_t<DT>::access(storage_);
363 }
364
368 void reset() noexcept {
369 if (has_value()) {
370 manage_(DESTROY, this, nullptr);
371 manage_ = nullptr;
372 }
373 }
374
379 NEFORCE_NODISCARD bool has_value() const noexcept { return manage_ != nullptr; }
380
385 NEFORCE_NODISCARD const std::type_info& type() const noexcept;
386
391 void swap(any& rhs) noexcept;
392};
393
401template <typename T, typename... Args,
403any make_any(Args&&... args) {
404 return any(pass_template_construct_tag<T>{}, _NEFORCE forward<Args>(args)...);
405}
406
408NEFORCE_BEGIN_INNER__
409
410template <typename T, typename U>
411const T* __any_cast_aux_dispatch_impl(const any* value, any_cast_true_tag /*unused*/) noexcept {
412 if (value->manage_ == &any::manage_t<U>::manage) {
413 return static_cast<const T*>(any::manage_t<U>::access(value->storage_));
414 }
415 return nullptr;
416}
417
418template <typename T, typename U>
419const T* __any_cast_aux_dispatch_impl(const any* /*unused*/, any_cast_false_tag /*unused*/) noexcept {
420 return nullptr;
421}
422
423template <typename T, typename U>
424const T* __any_cast_aux_dispatch(const any* value) noexcept {
425 using tag = conditional_t<(is_same_v<decay_t<U>, U> || is_copy_constructible_v<U>), any_cast_true_tag,
426 any_cast_false_tag>;
427 return inner::__any_cast_aux_dispatch_impl<T, U>(value, tag{});
428}
429
430template <typename T, enable_if_t<is_object_v<T>, int> = 0>
431const T* __any_cast_aux(const any* value) noexcept {
432 if (value) {
433 return __any_cast_aux_dispatch<T, remove_cv_t<T>>(value);
434 }
435 return nullptr;
436}
437
438template <typename T, enable_if_t<!is_object_v<T>, int> = 0>
439const T* __any_cast_aux(const any* /*unused*/) noexcept {
440 return nullptr;
441}
442
443NEFORCE_END_INNER__
445
452template <typename T>
453const T* any_cast(const any* value) noexcept {
454 return inner::__any_cast_aux<T>(value);
455}
456
463template <typename T>
464T* any_cast(any* value) noexcept {
465 return const_cast<T*>(any_cast<T>(const_cast<const any*>(value)));
466}
467
475template <typename T>
476T any_cast(const any& value) {
477 using U = remove_cvref_t<T>;
479 "type T must be valid to cast from any.");
480
481 auto ptr = any_cast<U>(&value);
482 if (ptr != nullptr) {
483 return static_cast<T>(*ptr);
484 }
485 NEFORCE_THROW_EXCEPTION(anycast_exception());
486 unreachable();
487}
488
489
491
492template <typename T>
493void any::internal_manage<T>::manage(const any_operation op, const any* value, ArgT* arg) {
494 auto ptr = reinterpret_cast<const T*>(&value->storage_.buffer_);
495 switch (op) {
496 case ACCESS: {
497 arg->obj_ptr_ = const_cast<T*>(ptr);
498 break;
499 }
500 case GET_TYPE_INFO: {
501 arg->type_ptr_ = &typeid(T);
502 break;
503 }
504 case COPY: {
505 ::new (&arg->any_ptr_->storage_.buffer_) T(*ptr);
506 arg->any_ptr_->manage_ = value->manage_;
507 break;
508 }
509 case DESTROY: {
510 ptr->~T();
511 break;
512 }
513 case SWAP: {
514 ::new (&arg->any_ptr_->storage_.buffer_) T(_NEFORCE move(*const_cast<T*>(ptr)));
515 ptr->~T();
516 arg->any_ptr_->manage_ = value->manage_;
517 const_cast<any*>(value)->manage_ = nullptr;
518 break;
519 }
520 default: {
521 unreachable();
522 }
523 }
524}
525
526template <typename T>
527void any::external_manage<T>::manage(const any_operation op, const any* value, ArgT* arg) {
528 auto ptr = static_cast<const T*>(value->storage_.ptr_);
529 switch (op) {
530 case ACCESS: {
531 arg->obj_ptr_ = const_cast<T*>(ptr);
532 break;
533 }
534 case GET_TYPE_INFO: {
535 arg->type_ptr_ = &typeid(T);
536 break;
537 }
538 case COPY: {
539 arg->any_ptr_->storage_.ptr_ = ::new T(*ptr);
540 arg->any_ptr_->manage_ = value->manage_;
541 break;
542 }
543 case DESTROY: {
544 delete ptr;
545 break;
546 }
547 case SWAP: {
548 arg->any_ptr_->storage_.ptr_ = value->storage_.ptr_;
549 arg->any_ptr_->manage_ = value->manage_;
550 const_cast<any*>(value)->manage_ = nullptr;
551 break;
552 }
553 default: {
554 unreachable();
555 }
556 }
557}
558
560 // Any
562
563NEFORCE_END_NAMESPACE__
564#endif // NEFORCE_CORE_UTILITY_ANY_HPP__
调试断点和断言工具
任意类型容器
DT & emplace(Args &&... args)
就地构造值
~any()
析构函数
any(T &&value)
从值构造
any & operator=(any &&other) noexcept
移动赋值运算符
any & operator=(const any &other)
复制赋值运算符
void reset() noexcept
重置any对象为空
any() noexcept=default
默认构造函数
void swap(any &rhs) noexcept
交换两个any对象
any(any &&other) noexcept
移动构造函数
const std::type_info & type() const noexcept
获取存储值的类型信息
any & operator=(T &&value)
从值赋值
DT & emplace(std::initializer_list< U > ilist, Args &&... args)
使用初始化列表就地构造
bool has_value() const noexcept
检查是否包含值
any(pass_template_construct_tag< T >, 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
完美转发左值
NEFORCE_NORETURN void unreachable() noexcept
标记不可达代码路径
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
typename decay< T >::type decay_t
decay的便捷别名
constexpr bool is_copy_constructible_v
is_copy_constructible的便捷变量模板
constexpr bool is_constructible_v
is_constructible的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
constexpr bool is_same_v
is_same的便捷变量模板
constexpr bool disjunction_v
disjunction的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
exception(const char *info=static_type, const char *type=static_type, const int code=0)
构造函数
const char * type() const noexcept
获取异常类型
int code() const noexcept
获取异常码
判断类型是否可以使用指定参数构造
判断类型是否可复制构造
传递模板参数构造标签