1#ifndef NEFORCE_CORE_UTILITY_ANY_HPP__
2#define NEFORCE_CORE_UTILITY_ANY_HPP__
11#include <initializer_list>
15NEFORCE_BEGIN_NAMESPACE__
23struct any_cast_true_tag {};
24struct any_cast_false_tag {};
33template <
typename T,
typename U>
34const T* __any_cast_aux_dispatch_impl(
const _NEFORCE any* value, any_cast_true_tag )
noexcept;
49struct anycast_exception final : typecast_exception {
50 explicit anycast_exception(
const char* info =
"Cast From any Type Failed.") noexcept :
51 typecast_exception(info) {}
53 explicit anycast_exception(
const exception& e) :
54 typecast_exception(e) {}
56 ~anycast_exception()
override =
default;
58 NEFORCE_NODISCARD
const char*
type() const noexcept
override {
return "anycast_exception"; }
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;
114 const std::type_info* type_ptr_;
125 template <
typename T>
126 struct internal_manage {
133 static void manage(any_operation op,
const any* value, ArgT* arg);
141 template <
typename... Args>
142 static void create(storage_internal& storage, Args&&... args) {
143 void* ptr = &storage.buffer_;
152 static T* access(
const storage_internal& storage) {
153 const void* ptr = &storage.buffer_;
154 return static_cast<T*
>(
const_cast<void*
>(ptr));
165 template <
typename T>
166 struct external_manage {
173 static void manage(any_operation op,
const any* value, ArgT* arg);
181 template <
typename... Args>
182 static void create(storage_internal& storage, Args&&... args) {
191 static T* access(
const storage_internal& storage) {
return static_cast<T*
>(storage.ptr_); }
200 template <
typename T>
202 alignof(T) <=
alignof(storage_internal),
203 internal_manage<T>, external_manage<T>>;
205 using manage_func = void (*)(any_operation,
const any*, ArgT*);
207 manage_func manage_ =
nullptr;
208 storage_internal storage_;
210 template <
typename T,
typename U>
211 friend const T* inner::__any_cast_aux_dispatch_impl(
const any* value, inner::any_cast_true_tag )
noexcept;
220 template <
typename T,
typename... Args,
typename Manager = manage_t<T>>
221 void try_emplace(Args&&... args) {
224 manage_ = &Manager::manage;
236 template <
typename T,
typename U,
typename... Args,
typename Manager = manage_t<T>>
237 void try_emplace(std::initializer_list<U> ilist, Args&&... args) {
239 Manager::create(storage_, ilist, _NEFORCE
forward<Args>(args)...);
240 manage_ = &Manager::manage;
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>,
288 manage_(&Manager::manage) {
289 Manager::create(storage_, _NEFORCE
forward<T>(value));
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>
311 template <
typename T,
typename... Args,
typename VT =
decay_t<T>,
typename Manager = manage_t<VT>,
314 manage_(&Manager::manage) {
318 template <
typename T,
typename U,
typename... Args,
typename VT =
decay_t<T>,
typename Manager = manage_t<VT>,
323 manage_(&Manager::manage) {
324 Manager::create(storage_, ilist, _NEFORCE
forward<Args>(args)...);
339 template <
typename T,
typename... Args,
typename DT =
decay_t<T>,
343 return *manage_t<DT>::access(storage_);
355 template <
typename T,
typename U,
typename... Args,
typename DT =
decay_t<T>,
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_);
369 manage_(DESTROY,
this,
nullptr);
378 NEFORCE_NODISCARD
bool has_value() const noexcept {
return manage_ !=
nullptr; }
384 NEFORCE_NODISCARD
const std::type_info&
type() const noexcept;
400template <typename T, typename... Args,
409template <
typename T,
typename U>
410const T* __any_cast_aux_dispatch_impl(
const any* value, any_cast_true_tag )
noexcept {
411 if (value->manage_ == &any::manage_t<U>::manage) {
412 return static_cast<const T*
>(any::manage_t<U>::access(value->storage_));
417template <
typename T,
typename U>
418const T* __any_cast_aux_dispatch_impl(
const any* , any_cast_false_tag )
noexcept {
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,
426 return inner::__any_cast_aux_dispatch_impl<T, U>(value, tag{});
429template <
typename T, enable_if_t<is_
object_v<T>,
int> = 0>
430const T* __any_cast_aux(
const any* value)
noexcept {
432 return __any_cast_aux_dispatch<T, remove_cv_t<T>>(value);
437template <
typename T, enable_if_t<!is_
object_v<T>,
int> = 0>
438const T* __any_cast_aux(
const any* )
noexcept {
453 return inner::__any_cast_aux<T>(value);
464 return const_cast<T*
>(
any_cast<T>(
const_cast<const any*
>(value)));
478 "type T must be valid to cast from any.");
481 if (ptr !=
nullptr) {
482 return static_cast<T
>(*ptr);
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_);
496 arg->obj_ptr_ =
const_cast<T*
>(ptr);
499 case GET_TYPE_INFO: {
500 arg->type_ptr_ = &
typeid(T);
504 ::new (&arg->any_ptr_->storage_.buffer_) T(*ptr);
505 arg->any_ptr_->manage_ = value->manage_;
513 ::new (&arg->any_ptr_->storage_.buffer_) T(_NEFORCE move(*const_cast<T*>(ptr)));
515 arg->any_ptr_->manage_ = value->manage_;
516 const_cast<any*>(value)->manage_ =
nullptr;
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_);
530 arg->obj_ptr_ =
const_cast<T*
>(ptr);
533 case GET_TYPE_INFO: {
534 arg->type_ptr_ = &
typeid(T);
538 arg->any_ptr_->storage_.ptr_ = ::new T(*ptr);
539 arg->any_ptr_->manage_ = value->manage_;
547 arg->any_ptr_->storage_.ptr_ = value->storage_.ptr_;
548 arg->any_ptr_->manage_ = value->manage_;
549 const_cast<any*
>(value)->manage_ =
nullptr;
562NEFORCE_END_NAMESPACE__
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
默认构造函数
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
获取异常类型