27 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
31 #include <EASTL/internal/config.h>
32 #include <EASTL/internal/in_place_t.h>
33 #if EASTL_RTTI_ENABLED
36 #if EASTL_EXCEPTIONS_ENABLED
50 #if EASTL_EXCEPTIONS_ENABLED
51 struct bad_cast : std::exception
53 const char* what() const EA_NOEXCEPT EA_OVERRIDE
54 {
return "bad cast"; }
57 struct bad_any_cast :
public bad_cast
59 const char* what() const EA_NOEXCEPT EA_OVERRIDE
60 {
return "bad_any_cast"; }
67 inline void DoBadAnyCast()
69 #if EASTL_EXCEPTIONS_ENABLED
72 EASTL_ASSERT_MSG(
false,
"bad_any_cast\n");
78 *((
volatile int*)0) = 0xDEADC0DE;
82 template<
typename T,
typename... Args>
83 void* DefaultConstruct(Args&&... args)
85 auto* pMem = EASTLAllocatorDefault()->allocate(
sizeof(T),
alignof(T), 0);
87 return ::new(pMem) T(eastl::forward<Args>(args)...);
91 void DefaultDestroy(T* p)
95 EASTLAllocatorDefault()->deallocate(
static_cast<void*
>(p),
sizeof(T));
110 enum class storage_operation
130 void* external_storage =
nullptr;
131 internal_storage_t internal_storage;
140 template <
typename T>
144 && (
sizeof(T) <=
sizeof(storage)) &&
152 template <
class ValueType>
friend const ValueType* any_cast(
const any* pAny) EA_NOEXCEPT;
153 template <
class ValueType>
friend ValueType* any_cast(
any* pAny) EA_NOEXCEPT;
154 template <
class ValueType>
friend ValueType any_cast(
const any& operand);
155 template <
class ValueType>
friend ValueType any_cast(
any& operand);
156 template <
class ValueType>
friend ValueType any_cast(
any&& operand);
159 template <
class ValueType>
friend const ValueType* unsafe_any_cast(
const any* pAny) EA_NOEXCEPT;
160 template <
class ValueType>
friend ValueType* unsafe_any_cast(
any* pAny) EA_NOEXCEPT;
166 template <
typename T>
167 struct storage_handler_internal
169 template <
typename V>
170 static void construct(storage& s, V&& v)
172 ::new(&s.internal_storage) T(eastl::forward<V>(v));
175 template <
typename... Args>
176 static void construct_inplace(storage& s, Args... args)
178 ::new(&s.internal_storage) T(eastl::forward<Args>(args)...);
181 template <
class NT,
class U,
class... Args>
184 ::new(&s.internal_storage) NT(il, eastl::forward<Args>(args)...);
189 T& t = *
static_cast<T*
>(
static_cast<void*
>(&refAny.m_storage.internal_storage));
193 refAny.m_handler =
nullptr;
196 static void* handler_func(storage_operation op,
const any* pThis,
any* pOther)
200 case storage_operation::GET:
203 return (
void*)(&pThis->m_storage.internal_storage);
207 case storage_operation::DESTROY:
214 case storage_operation::COPY:
217 EASTL_ASSERT(pOther);
218 construct(pOther->m_storage, *(T*)(&pThis->m_storage.internal_storage));
222 case storage_operation::MOVE:
225 EASTL_ASSERT(pOther);
226 construct(pOther->m_storage,
eastl::move(*(T*)(&pThis->m_storage.internal_storage)));
231 case storage_operation::TYPE_INFO:
233 #if EASTL_RTTI_ENABLED
234 return (
void*)&
typeid(T);
241 EASTL_ASSERT_MSG(
false,
"unknown storage operation\n");
255 template <
typename T>
256 struct storage_handler_external
258 template <
typename V>
259 static inline void construct(storage& s, V&& v)
261 s.external_storage = Internal::DefaultConstruct<T>(eastl::forward<V>(v));
264 template <
typename... Args>
265 static inline void construct_inplace(storage& s, Args... args)
267 s.external_storage = Internal::DefaultConstruct<T>(eastl::forward<Args>(args)...);
270 template <
class NT,
class U,
class... Args>
273 s.external_storage = Internal::DefaultConstruct<NT>(il, eastl::forward<Args>(args)...);
278 Internal::DefaultDestroy(
static_cast<T*
>(refAny.m_storage.external_storage));
280 refAny.m_handler =
nullptr;
283 static void* handler_func(storage_operation op,
const any* pThis,
any* pOther)
287 case storage_operation::GET:
290 EASTL_ASSERT(pThis->m_storage.external_storage);
291 return static_cast<void*
>(pThis->m_storage.external_storage);
295 case storage_operation::DESTROY:
302 case storage_operation::COPY:
305 EASTL_ASSERT(pOther);
306 construct(pOther->m_storage, *
static_cast<T*
>(pThis->m_storage.external_storage));
310 case storage_operation::MOVE:
313 EASTL_ASSERT(pOther);
314 construct(pOther->m_storage,
eastl::move(*(T*)(pThis->m_storage.external_storage)));
319 case storage_operation::TYPE_INFO:
321 #if EASTL_RTTI_ENABLED
322 return (
void*)&
typeid(T);
329 EASTL_ASSERT_MSG(
false,
"unknown storage operation\n");
346 using storage_handler_ptr =
void* (*)(storage_operation,
const any*,
any*);
355 template <
typename T>
357 storage_handler_internal<T>,
358 storage_handler_external<T>>::type;
365 storage_handler_ptr m_handler;
368 #ifndef EA_COMPILER_GNUC
373 : m_storage(), m_handler(
nullptr) {}
375 any(
const any& other) : m_handler(
nullptr)
382 other.m_handler(storage_operation::COPY, &other,
this);
383 m_handler = other.m_handler;
387 any(
any&& other) EA_NOEXCEPT : m_handler(
nullptr)
396 other.m_handler(storage_operation::MOVE, &other,
this);
402 template <
class ValueType>
403 any(ValueType&& value,
406 typedef decay_t<ValueType> DecayedValueType;
408 storage_handler<DecayedValueType>::construct(m_storage, eastl::forward<ValueType>(value));
409 m_handler = &storage_handler<DecayedValueType>::handler_func;
412 template <
class T,
class... Args>
413 explicit any(in_place_type_t<T>, Args&&... args)
415 typedef storage_handler<decay_t<T>> StorageHandlerT;
418 StorageHandlerT::construct_inplace(m_storage, eastl::forward<Args>(args)...);
419 m_handler = &StorageHandlerT::handler_func;
422 template <
class T,
class U,
class... Args>
423 explicit any(in_place_type_t<T>,
429 typedef storage_handler<decay_t<T>> StorageHandlerT;
431 StorageHandlerT::construct_inplace(m_storage, il, eastl::forward<Args>(args)...);
432 m_handler = &StorageHandlerT::handler_func;
436 template <
class ValueType>
437 any& operator=(ValueType&& value)
439 static_assert(
is_copy_constructible<decay_t<ValueType>>::value,
"ValueType must be copy-constructible");
440 any(eastl::forward<ValueType>(value)).swap(*
this);
444 any& operator=(
const any& other)
446 any(other).swap(*
this);
450 any& operator=(
any&& other) EA_NOEXCEPT
457 #if EASTL_VARIADIC_TEMPLATES_ENABLED
458 template <
class T,
class... Args>
459 void emplace(Args&&... args)
461 typedef storage_handler<decay_t<T>> StorageHandlerT;
465 StorageHandlerT::construct_inplace(m_storage, eastl::forward<Args>(args)...);
466 m_handler = &StorageHandlerT::handler_func;
469 template <
class NT,
class U,
class... Args>
473 typedef storage_handler<decay_t<NT>> StorageHandlerT;
476 StorageHandlerT::construct_inplace(m_storage, il, eastl::forward<Args>(args)...);
477 m_handler = &StorageHandlerT::handler_func;
481 void reset() EA_NOEXCEPT
484 m_handler(storage_operation::DESTROY,
this,
nullptr);
487 void swap(
any& other) EA_NOEXCEPT
492 if(m_handler && other.m_handler)
495 tmp.m_handler = other.m_handler;
496 other.m_handler(storage_operation::MOVE, &other, &tmp);
498 other.m_handler = m_handler;
499 m_handler(storage_operation::MOVE,
this, &other);
501 m_handler = tmp.m_handler;
502 tmp.m_handler(storage_operation::MOVE, &tmp,
this);
504 else if (m_handler ==
nullptr && other.m_handler)
506 eastl::swap(m_handler, other.m_handler);
507 m_handler(storage_operation::MOVE, &other,
this);
509 else if(m_handler && other.m_handler ==
nullptr)
511 eastl::swap(m_handler, other.m_handler);
512 other.m_handler(storage_operation::MOVE,
this, &other);
521 bool has_value()
const EA_NOEXCEPT {
return m_handler !=
nullptr; }
523 #if EASTL_RTTI_ENABLED
524 inline const std::type_info& type()
const EA_NOEXCEPT
528 auto* pTypeInfo = m_handler(storage_operation::TYPE_INFO,
this,
nullptr);
529 return *
static_cast<const std::type_info*
>(pTypeInfo);
544 inline void swap(
any& rhs,
any& lhs) EA_NOEXCEPT { rhs.swap(lhs); }
550 template <
class ValueType>
551 inline ValueType any_cast(
const any& operand)
554 "ValueType must be a reference or copy constructible");
556 auto* p = any_cast<typename add_const<typename remove_reference<ValueType>::type>::type>(&operand);
559 Internal::DoBadAnyCast();
564 template <
class ValueType>
565 inline ValueType any_cast(any& operand)
568 "ValueType must be a reference or copy constructible");
570 auto* p = any_cast<typename remove_reference<ValueType>::type>(&operand);
573 Internal::DoBadAnyCast();
578 template <
class ValueType>
579 inline ValueType any_cast(any&& operand)
582 "ValueType must be a reference or copy constructible");
584 auto* p = any_cast<typename remove_reference<ValueType>::type>(&operand);
587 Internal::DoBadAnyCast();
596 template <
class ValueType>
597 inline const ValueType* any_cast(
const any* pAny) EA_NOEXCEPT
599 return (pAny && pAny->m_handler EASTL_IF_NOT_DLL(== &any::storage_handler<decay_t<ValueType>>::handler_func)
600 #
if EASTL_RTTI_ENABLED
601 && pAny->type() ==
typeid(
typename remove_reference<ValueType>::type)
604 static_cast<const ValueType*
>(pAny->m_handler(any::storage_operation::GET, pAny,
nullptr)) :
608 template <
class ValueType>
609 inline ValueType* any_cast(any* pAny) EA_NOEXCEPT
611 return (pAny && pAny->m_handler EASTL_IF_NOT_DLL(== &any::storage_handler<decay_t<ValueType>>::handler_func)
612 #
if EASTL_RTTI_ENABLED
613 && pAny->type() ==
typeid(
typename remove_reference<ValueType>::type)
616 static_cast<ValueType*
>(pAny->m_handler(any::storage_operation::GET, pAny,
nullptr)) :
621 template <
class ValueType>
622 inline const ValueType* unsafe_any_cast(
const any* pAny) EA_NOEXCEPT
624 return unsafe_any_cast<ValueType>(
const_cast<any*
>(pAny));
627 template <
class ValueType>
628 inline ValueType* unsafe_any_cast(any* pAny) EA_NOEXCEPT
630 return static_cast<ValueType*
>(pAny->m_handler(any::storage_operation::GET, pAny,
nullptr));
636 #if EASTL_VARIADIC_TEMPLATES_ENABLED
637 template <
class T,
class... Args>
638 inline any make_any(Args&&... args)
640 return any(eastl::in_place<T>, eastl::forward<Args>(args)...);
643 template <
class T,
class U,
class... Args>
646 return any(eastl::in_place<T>, il, eastl::forward<Args>(args)...);
Definition: initializer_list.h:38
EA Standard Template Library.
Definition: algorithm.h:288
OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
Definition: copy_help.h:170
void destroy(ForwardIterator first, ForwardIterator last)
Definition: memory.h:1395
Definition: type_properties.h:234
Definition: type_traits.h:473
Definition: type_traits.h:494
Definition: type_traits.h:442
Definition: type_traits.h:263
Definition: type_pod.h:792
Definition: type_pod.h:1175
Definition: type_pod.h:1934
Definition: type_traits.h:669
Definition: type_traits.h:604