MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
any.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_UTILITY_ANY_HPP__
2#define MSTL_CORE_UTILITY_ANY_HPP__
3
10
12#include <initializer_list>
13#include <typeinfo>
15
16class MSTL_API any;
17
19
21
22struct any_cast_true_tag {};
23struct any_cast_false_tag {};
24
32template <typename T, typename U>
33const T* __any_cast_aux_dispatch_impl(const _MSTL any* value, any_cast_true_tag) noexcept;
34
37
43
49MSTL_ERROR_BUILD_DERIVED_CLASS(anycast_exception, typecast_exception, "Cast From any Type Failed.")
50
51 // Exceptions
52
53
58
59
66class MSTL_API any {
73 union storage_internal {
74 storage_internal() = default;
75 storage_internal(const storage_internal&) = delete;
76 storage_internal& operator =(const storage_internal&) = delete;
77
78 void* ptr_ = nullptr;
79 aligned_storage_t<sizeof(ptr_), alignof(void*)> buffer_;
80 };
81
88 enum any_operation {
89 ACCESS,
90 GET_TYPE_INFO,
91 COPY,
92 DESTROY,
93 SWAP
94 };
95
102 union ArgT {
103 void* obj_ptr_;
104 const std::type_info* type_ptr_;
105 any* any_ptr_;
106 };
107
115 template <typename T>
116 struct internal_manage {
123 static void manage(any_operation op, const any* value, ArgT* arg);
124
131 template <typename... Args>
132 static void create(storage_internal& storage, Args&&... args) {
133 void* ptr = &storage.buffer_;
134 new (ptr) T(_MSTL forward<Args>(args)...);
135 }
136
142 static T* access(const storage_internal& storage) {
143 const void* ptr = &storage.buffer_;
144 return static_cast<T*>(const_cast<void*>(ptr));
145 }
146 };
147
155 template <typename T>
156 struct external_manage {
163 static void manage(any_operation op, const any* value, ArgT* arg);
164
171 template <typename... Args>
172 static void create(storage_internal& storage, Args&&... args) {
173 storage.ptr_ = new T(_MSTL forward<Args>(args)...);
174 }
175
181 static T* access(const storage_internal& storage) {
182 return static_cast<T*>(storage.ptr_);
183 }
184 };
185
192 template <typename T>
193 using manage_t = conditional_t<
194 is_nothrow_move_constructible_v<T> &&
195 sizeof(T) <= sizeof(storage_internal) &&
196 alignof(T) <= alignof(storage_internal)
197 , internal_manage<T>, external_manage<T>>;
198
199 using manage_func = void (*)(any_operation, const any*, ArgT*);
200
201 manage_func manage_ = nullptr;
202 storage_internal storage_{};
203
204 template <typename T, typename U>
205 friend const T* _INNER __any_cast_aux_dispatch_impl(const any* value, _INNER any_cast_true_tag) noexcept;
206
214 template <typename T, typename... Args, typename Manager = manage_t<T>>
215 void try_emplace(Args&&... args) {
216 any::reset();
217 Manager::create(storage_, _MSTL forward<Args>(args)...);
218 manage_ = &Manager::manage;
219 }
220
230 template <typename T, typename U, typename... Args, typename Manager = manage_t<T>>
231 void try_emplace(std::initializer_list<U> ilist, Args&&... args) {
232 any::reset();
233 Manager::create(storage_, ilist, _MSTL forward<Args>(args)...);
234 manage_ = &Manager::manage;
235 }
236
237public:
241 any() noexcept {}
242
247 any(const any& other);
248
255 any& operator =(const any& other) {
256 *this = any(other);
257 return *this;
258 }
259
264 any(any&& other) noexcept;
265
271 any& operator =(any&& other) noexcept;
272
278 template <typename T, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
279 enable_if_t<is_copy_constructible_v<VT> && !is_same_v<inplace_construct_tag, VT> && !is_same_v<VT, any>, int> = 0>
280 explicit any(T&& value) : manage_(&Manager::manage) {
281 Manager::create(storage_, _MSTL forward<T>(value));
282 }
283
290 template <typename T, typename VT = decay_t<T>,
291 enable_if_t<!is_same_v<VT, any> && is_copy_constructible_v<VT>, int> = 0>
292 any& operator =(T&& value) {
293 *this = any(_MSTL forward<T>(value));
294 return *this;
295 }
296
303 template <typename T, typename... Args, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
305 explicit any(inplace_construct_tag, Args&&... args) : manage_(&Manager::manage) {
306 Manager::create(storage_, _MSTL forward<Args>(args)...);
307 }
308
317 template <typename T, typename U, typename... Args, typename VT = decay_t<T>, typename Manager = manage_t<VT>,
319 explicit any(inplace_construct_tag, std::initializer_list<U> ilist, Args&&... args) : manage_(&Manager::manage) {
320 Manager::create(storage_, ilist, _MSTL forward<Args>(args)...);
321 }
322
326 ~any() {
327 reset();
328 }
329
337 template <typename T, typename... Args, typename DT = decay_t<T>,
339 const DT& emplace(Args&&... args) {
340 any::try_emplace<DT>(_MSTL forward<Args>(args)...);
341 return *manage_t<DT>::access(storage_);
342 }
343
353 template <typename T, typename U, typename... Args, typename DT = decay_t<T>,
355 const DT& emplace(std::initializer_list<U> ilist, Args&&... args) {
356 any::try_emplace<DT, U>(ilist, _MSTL forward<Args>(args)...);
357 return *manage_t<DT>::access(storage_);
358 }
359
363 void reset() noexcept {
364 if (has_value()) {
365 manage_(DESTROY, this, nullptr);
366 manage_ = nullptr;
367 }
368 }
369
374 MSTL_NODISCARD bool has_value() const noexcept {
375 return manage_ != nullptr;
376 }
377
382 MSTL_NODISCARD const std::type_info& type() const noexcept;
383
388 void swap(any& rhs) noexcept;
389};
390
398template <typename T, typename... Args,
399 enable_if_t<is_constructible_v<any, inplace_construct_tag, Args...>, int> = 0>
400any make_any(Args&&... args) {
401 return any(inplace_construct_tag{}, _MSTL forward<Args>(args)...);
402}
403
413template <typename T, typename U, typename... Args,
415any make_any(std::initializer_list<U> ilist, Args&&... args) {
416 return any(inplace_construct_tag{}, ilist, _MSTL forward<Args>(args)...);
417}
418
421
422template <typename T, typename U>
423const T* __any_cast_aux_dispatch_impl(const any* value, any_cast_true_tag) noexcept {
424 if (value->manage_ == &any::manage_t<U>::manage || value->type() == typeid(T))
425 return static_cast<const T*>(any::manage_t<U>::access(value->storage_));
426 return nullptr;
427}
428
429template <typename T, typename U>
430const T* __any_cast_aux_dispatch_impl(const any*, any_cast_false_tag) noexcept {
431 return nullptr;
432}
433
434template <typename T, typename U>
435const T* __any_cast_aux_dispatch(const any* value) noexcept {
436 using tag = conditional_t<
437 (is_same_v<decay_t<U>, U> || is_copy_constructible_v<U>),
438 any_cast_true_tag, any_cast_false_tag
439 >;
440 return _INNER __any_cast_aux_dispatch_impl<T, U>(value, tag{});
441}
442
443template <typename T, enable_if_t<is_object_v<T>, int> = 0>
444const T* __any_cast_aux(const any* value) noexcept {
445 if (value)
446 return __any_cast_aux_dispatch<T, remove_cv_t<T>>(value);
447 return nullptr;
448}
449
450template <typename T, enable_if_t<!is_object_v<T>, int> = 0>
451const T* __any_cast_aux(const any*) noexcept {
452 return nullptr;
453}
454
457
464template <typename T>
465const T* any_cast(const any* value) noexcept {
466 return _INNER __any_cast_aux<T>(value);
467}
468
475template <typename T>
476T* any_cast(any* value) noexcept {
477 return const_cast<T*>(any_cast<T>(const_cast<const any*>(value)));
478}
479
487template <typename T>
488T any_cast(const any& value) {
489 using U = remove_cvref_t<T>;
490 static_assert(
491 disjunction_v<
495 "type T must be valid to cast from any.");
496
497 auto ptr = any_cast<U>(&value);
498 if (ptr) {
499 return static_cast<T>(*ptr);
500 }
501 throw_exception(anycast_exception());
502 MSTL_UNREACHABLE;
503}
504
505template <typename T>
506void any::internal_manage<T>::manage(const any_operation op, const any* value, ArgT* arg) {
507 auto ptr = reinterpret_cast<const T*>(&value->storage_.buffer_);
508 switch (op) {
509 case ACCESS: {
510 arg->obj_ptr_ = const_cast<T*>(ptr);
511 break;
512 }
513 case GET_TYPE_INFO: {
514 arg->type_ptr_ = &typeid(T);
515 break;
516 }
517 case COPY: {
518 ::new(&arg->any_ptr_->storage_.buffer_) T(*ptr);
519 arg->any_ptr_->manage_ = value->manage_;
520 break;
521 }
522 case DESTROY: {
523 ptr->~T();
524 break;
525 }
526 case SWAP: {
527 ::new(&arg->any_ptr_->storage_.buffer_) T(_MSTL move(*const_cast<T*>(ptr)));
528 ptr->~T();
529 arg->any_ptr_->manage_ = value->manage_;
530 const_cast<any*>(value)->manage_ = nullptr;
531 break;
532 }
533 default: {
534 MSTL_UNREACHABLE;
535 }
536 }
537}
538
539template <typename T>
540void any::external_manage<T>::manage(const any_operation op, const any* value, ArgT* arg) {
541 auto ptr = static_cast<const T*>(value->storage_.ptr_);
542 switch (op) {
543 case ACCESS: {
544 arg->obj_ptr_ = const_cast<T*>(ptr);
545 break;
546 }
547 case GET_TYPE_INFO: {
548 arg->type_ptr_ = &typeid(T);
549 break;
550 }
551 case COPY: {
552 arg->any_ptr_->storage_.ptr_ = ::new T(*ptr);
553 arg->any_ptr_->manage_ = value->manage_;
554 break;
555 }
556 case DESTROY: {
557 delete ptr;
558 break;
559 }
560 case SWAP: {
561 arg->any_ptr_->storage_.ptr_ = value->storage_.ptr_;
562 arg->any_ptr_->manage_ = value->manage_;
563 const_cast<any*>(value)->manage_ = nullptr;
564 break;
565 }
566 default: {
567 MSTL_UNREACHABLE;
568 }
569 }
570}
571 // Any
573
575#endif // MSTL_CORE_UTILITY_ANY_HPP__
任意类型容器
MSTL异常处理框架
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对象
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
#define MSTL_ERROR_BUILD_DERIVED_CLASS(THIS, BASE, INFO)
构建可派生的异常类宏
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
void swap()=delete
删除无参数的swap重载
typename decay< T >::type decay_t
decay的便捷别名
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
any转换异常
原位构造标签
判断类型是否可以使用指定参数构造
判断类型是否可复制构造
判断类型是否为引用类型