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.",
const char*
type = static_type,
51 const int code = 0) noexcept :
52 typecast_exception(info,
type,
code) {}
54 explicit anycast_exception(
const exception& e) :
55 typecast_exception(e) {}
57 ~anycast_exception()
override =
default;
59 static constexpr auto static_type =
"anycast_exception";
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;
115 const std::type_info* type_ptr_;
126 template <
typename T>
127 struct internal_manage {
134 static void manage(any_operation op,
const any* value, ArgT* arg);
142 template <
typename... Args>
143 static void create(storage_internal& storage, Args&&... args) {
144 void* ptr = &storage.buffer_;
153 static T* access(
const storage_internal& storage) {
154 const void* ptr = &storage.buffer_;
155 return static_cast<T*
>(
const_cast<void*
>(ptr));
166 template <
typename T>
167 struct external_manage {
174 static void manage(any_operation op,
const any* value, ArgT* arg);
182 template <
typename... Args>
183 static void create(storage_internal& storage, Args&&... args) {
192 static T* access(
const storage_internal& storage) {
return static_cast<T*
>(storage.ptr_); }
201 template <
typename T>
203 alignof(T) <=
alignof(storage_internal),
204 internal_manage<T>, external_manage<T>>;
206 using manage_func = void (*)(any_operation,
const any*, ArgT*);
208 manage_func manage_ =
nullptr;
209 storage_internal storage_{};
211 template <
typename T,
typename U>
212 friend const T* inner::__any_cast_aux_dispatch_impl(
const any* value, inner::any_cast_true_tag)
noexcept;
221 template <
typename T,
typename... Args,
typename Manager = manage_t<T>>
222 void try_emplace(Args&&... args) {
225 manage_ = &Manager::manage;
237 template <
typename T,
typename U,
typename... Args,
typename Manager = manage_t<T>>
238 void try_emplace(std::initializer_list<U> ilist, Args&&... args) {
240 Manager::create(storage_, ilist, _NEFORCE
forward<Args>(args)...);
241 manage_ = &Manager::manage;
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>,
289 manage_(&Manager::manage) {
290 Manager::create(storage_, _NEFORCE
forward<T>(value));
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>
312 template <
typename T,
typename... Args,
typename VT =
decay_t<T>,
typename Manager = manage_t<VT>,
315 manage_(&Manager::manage) {
327 template <
typename T,
typename U,
typename... Args,
typename VT =
decay_t<T>,
typename Manager = manage_t<VT>,
332 manage_(&Manager::manage) {
333 Manager::create(storage_, ilist, _NEFORCE
forward<Args>(args)...);
348 template <
typename T,
typename... Args,
typename DT =
decay_t<T>,
352 return *manage_t<DT>::access(storage_);
364 template <
typename T,
typename U,
typename... Args,
typename DT =
decay_t<T>,
368 DT&
emplace(std::initializer_list<U> ilist, Args&&... args) {
369 any::try_emplace<DT, U>(ilist, _NEFORCE
forward<Args>(args)...);
370 return *manage_t<DT>::access(storage_);
378 manage_(DESTROY,
this,
nullptr);
387 NEFORCE_NODISCARD
bool has_value() const noexcept {
return manage_ !=
nullptr; }
393 NEFORCE_NODISCARD
const std::type_info&
type() const noexcept;
423template <
typename T,
typename U,
typename... Args,
432template <
typename T,
typename U>
433const T* __any_cast_aux_dispatch_impl(
const any* value, any_cast_true_tag)
noexcept {
434 if (value->manage_ == &any::manage_t<U>::manage) {
435 return static_cast<const T*
>(any::manage_t<U>::access(value->storage_));
440template <
typename T,
typename U>
441const T* __any_cast_aux_dispatch_impl(
const any*, any_cast_false_tag)
noexcept {
445template <
typename T,
typename U>
446const T* __any_cast_aux_dispatch(
const any* value)
noexcept {
449 return inner::__any_cast_aux_dispatch_impl<T, U>(value, tag{});
452template <
typename T, enable_if_t<is_
object_v<T>,
int> = 0>
453const T* __any_cast_aux(
const any* value)
noexcept {
455 return __any_cast_aux_dispatch<T, remove_cv_t<T>>(value);
460template <
typename T, enable_if_t<!is_
object_v<T>,
int> = 0>
461const T* __any_cast_aux(
const any*)
noexcept {
476 return inner::__any_cast_aux<T>(value);
487 return const_cast<T*
>(
any_cast<T>(
const_cast<const any*
>(value)));
501 "type T must be valid to cast from any.");
505 return static_cast<T
>(*ptr);
515void any::internal_manage<T>::manage(
const any_operation op,
const any* value, ArgT* arg) {
516 auto ptr =
reinterpret_cast<const T*
>(&value->storage_.buffer_);
519 arg->obj_ptr_ =
const_cast<T*
>(ptr);
522 case GET_TYPE_INFO: {
523 arg->type_ptr_ = &
typeid(T);
527 ::new (&arg->any_ptr_->storage_.buffer_) T(*ptr);
528 arg->any_ptr_->manage_ = value->manage_;
536 ::new (&arg->any_ptr_->storage_.buffer_) T(_NEFORCE
move(*const_cast<T*>(ptr)));
538 arg->any_ptr_->manage_ = value->manage_;
539 const_cast<any*>(value)->manage_ =
nullptr;
549void any::external_manage<T>::manage(
const any_operation op,
const any* value, ArgT* arg) {
550 auto ptr =
static_cast<const T*
>(value->storage_.ptr_);
553 arg->obj_ptr_ =
const_cast<T*
>(ptr);
556 case GET_TYPE_INFO: {
557 arg->type_ptr_ = &
typeid(T);
561 arg->any_ptr_->storage_.ptr_ = ::new T(*ptr);
562 arg->any_ptr_->manage_ = value->manage_;
570 arg->any_ptr_->storage_.ptr_ = value->storage_.ptr_;
571 arg->any_ptr_->manage_ = value->manage_;
572 const_cast<any*
>(value)->manage_ =
nullptr;
585NEFORCE_END_NAMESPACE__
NEFORCE_NODISCARD bool has_value() const noexcept
检查是否包含值
DT & emplace(Args &&... args)
就地构造值
any(const any &other)
复制构造函数
any & operator=(any &&other) noexcept
移动赋值运算符
NEFORCE_NODISCARD const std::type_info & type() const noexcept
获取存储值的类型信息
any(inplace_construct_tag, std::initializer_list< U > ilist, Args &&... args)
使用初始化列表就地构造
any & operator=(const any &other)
复制赋值运算符
void reset() noexcept
重置any对象为空
void swap(any &rhs) noexcept
交换两个any对象
any(any &&other) noexcept
移动构造函数
any & operator=(T &&value)
从值赋值
any(inplace_construct_tag, Args &&... args)
就地构造
DT & emplace(std::initializer_list< U > ilist, 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对象
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
NEFORCE_NORETURN NEFORCE_ALWAYS_INLINE_INLINE 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的便捷别名
NEFORCE_INLINE17 constexpr bool is_copy_constructible_v
is_copy_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_constructible_v
is_constructible的便捷变量模板
NEFORCE_INLINE17 constexpr bool disjunction_v
disjunction的便捷变量模板
NEFORCE_INLINE17 constexpr bool is_same_v
is_same的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
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)
构造函数
NEFORCE_NODISCARD int code() const noexcept
获取异常码
NEFORCE_NODISCARD const char * type() const noexcept
获取异常类型