20 #include <type_traits>
26 #if !defined(__cpp_exceptions) && !defined(ANY_IMPL_NO_EXCEPTIONS) && !defined(ANY_IMPL_EXCEPTIONS)
27 # define ANY_IMPL_NO_EXCEPTIONS
35 #if !defined(__cpp_rtti) && !defined(ANY_IMPL_NO_RTTI) && !defined(ANY_IMPL_RTTI)
36 # define ANY_IMPL_NO_RTTI
52 #if defined (__cpp_variable_templates) || defined(_MSC_VER)
60 const char*
what() const noexcept
override
62 return "bad any cast";
92 rhs.vtable->
move(rhs.storage, this->storage);
107 template<typename ValueType, typename = typename std::enable_if<!std::is_same<typename std::decay<ValueType>::type,
any>::value>
::type>
110 static_assert(std::is_copy_constructible<
typename std::decay<ValueType>::type>::value,
111 "T shall satisfy the CopyConstructible requirements.");
112 this->
construct(std::forward<ValueType>(value));
115 template <
typename ValueType,
typename... Args>
118 this->emplace_construct<ValueType>(std::forward<Args>(args)...);
121 template <
typename ValueType,
typename U,
typename... Args>
124 this->emplace_construct<ValueType>(il, std::forward<Args>(args)...);
129 any(rhs).swap(*
this);
139 std::move(rhs).
swap(*
this);
147 template<typename ValueType, typename = typename std::enable_if<!std::is_same<typename std::decay<ValueType>::type,
any>::value>
::type>
150 static_assert(std::is_copy_constructible<
typename std::decay<ValueType>::type>::value,
151 "T shall satisfy the CopyConstructible requirements.");
152 any(std::forward<ValueType>(value)).swap(*
this);
169 return this->
vtable ==
nullptr;
172 #ifndef ANY_IMPL_NO_RTTI
173 const std::type_info&
type() const noexcept
183 if(this->
vtable != rhs.vtable)
185 any tmp(std::move(rhs));
188 rhs.vtable = this->
vtable;
189 if(this->
vtable !=
nullptr)
205 if(this->
vtable !=
nullptr)
226 #ifndef ANY_IMPL_NO_RTTI
227 const std::type_info& (*type)() noexcept;
251 #ifndef ANY_IMPL_NO_RTTI
252 static const std::type_info&
type() noexcept
271 dest.dynamic = src.dynamic;
272 src.dynamic =
nullptr;
286 #ifndef ANY_IMPL_NO_RTTI
287 static const std::type_info&
type() noexcept
300 new (&dest.
stack) T(
reinterpret_cast<const T&
>(src.
stack));
307 new (&dest.stack) T(std::move(
reinterpret_cast<T&
>(src.stack)));
314 move(rhs, tmp_storage);
316 move(tmp_storage, lhs);
323 std::integral_constant<bool,
324 !(std::is_nothrow_move_constructible<T>::value
325 && sizeof(T) <= sizeof(storage_union::stack)
326 && std::alignment_of<T>::value <= std::alignment_of<storage_union::stack_storage_t>::value)>
331 static vtable_type* vtable_for_type()
333 using VTableType = typename std::conditional<requires_allocation<T>::value, vtable_dynamic<T>, vtable_stack<T>>::type;
334 static vtable_type table = {
335 #ifndef ANY_IMPL_NO_RTTI
339 VTableType::copy, VTableType::move,
347 friend const T* any_cast(const any* operand) noexcept;
349 friend T* any_cast(any* operand) noexcept;
351 #ifndef ANY_IMPL_NO_RTTI
353 bool is_typed(const std::type_info& t) const
355 return is_same(this->type(), t);
359 #ifndef ANY_IMPL_NO_RTTI
366 static bool is_same(const std::type_info& a, const std::type_info& b)
368 #ifdef ANY_IMPL_FAST_TYPE_INFO_COMPARE
378 const T* cast() const noexcept
380 return requires_allocation<typename std::decay<T>::type>::value?
381 reinterpret_cast<const T*>(storage.dynamic) :
382 reinterpret_cast<const T*>(&storage.stack);
389 return requires_allocation<typename std::decay<T>::type>::value?
390 reinterpret_cast<T*>(storage.dynamic) :
391 reinterpret_cast<T*>(&storage.stack);
395 storage_union storage;
398 template <typename T, typename... Args>
399 typename std::enable_if<requires_allocation<T>::value>::type do_emplace(Args&&... args)
401 storage.dynamic = new T(std::forward<Args>(args)...);
404 template <typename T, typename... Args>
405 typename std::enable_if<!requires_allocation<T>::value>::type do_emplace(Args&&... args)
407 new (&storage.stack) T(std::forward<Args>(args)...);
410 template <typename ValueType, typename... Args>
411 void emplace_construct(Args&&... args)
413 using T = typename std::decay<ValueType>::type;
420 template<typename ValueType, typename T>
427 template<
typename ValueType,
typename T>
436 template<
typename ValueType>
439 using T =
typename std::decay<ValueType>::type;
441 this->
vtable = vtable_for_type<T>();
443 do_construct<ValueType,T>(std::forward<ValueType>(value));
451 template<
typename ValueType>
454 return std::move(*
p);
457 template<
typename ValueType>
465 template<
typename ValueType>
468 auto p = any_cast<typename std::add_const<typename std::remove_reference<ValueType>::type>::type>(&operand);
469 #ifndef ANY_IMPL_NO_EXCEPTIONS
476 template<
typename ValueType>
479 auto p = any_cast<typename std::remove_reference<ValueType>::type>(&operand);
480 #ifndef ANY_IMPL_NO_EXCEPTIONS
491 template<
typename ValueType>
494 using can_move = std::integral_constant<bool,
498 auto p = any_cast<typename std::remove_reference<ValueType>::type>(&operand);
499 #ifndef ANY_IMPL_NO_EXCEPTIONS
502 return detail::any_cast_move_if_true<ValueType>(
p, can_move());
507 template<
typename ValueType>
510 using T =
typename std::decay<ValueType>::type;
512 #ifndef ANY_IMPL_NO_RTTI
513 if (operand && operand->is_typed(
typeid(T)))
515 if (operand && operand->vtable == any::vtable_for_type<T>())
517 return operand->cast<ValueType>();
524 template<
typename ValueType>
527 using T =
typename std::decay<ValueType>::type;
529 #ifndef ANY_IMPL_NO_RTTI
530 if (operand && operand->is_typed(
typeid(T)))
532 if (operand && operand->vtable == any::vtable_for_type<T>())
534 return operand->cast<ValueType>();
544 template <
typename T,
typename... Args>
550 template <
typename T,
typename U,
typename... Args>