20 #include <type_traits>
25 #if !defined(__cpp_exceptions) && !defined(ANY_IMPL_NO_EXCEPTIONS) && !defined(ANY_IMPL_EXCEPTIONS)
26 # define ANY_IMPL_NO_EXCEPTIONS
34 #if !defined(__cpp_rtti) && !defined(ANY_IMPL_NO_RTTI) && !defined(ANY_IMPL_RTTI)
35 # define ANY_IMPL_NO_RTTI
49 const char*
what() const noexcept
override
51 return "bad any cast";
81 rhs.vtable->
move(rhs.storage, this->storage);
97 any(ValueType&& value)
100 "T shall satisfy the CopyConstructible requirements.");
101 this->
construct(std::forward<ValueType>(value));
107 any(rhs).swap(*
this);
117 any(std::move(rhs)).swap(*
this);
129 "T shall satisfy the CopyConstructible requirements.");
130 any(std::forward<ValueType>(value)).swap(*
this);
147 return this->
vtable ==
nullptr;
150 #ifndef ANY_IMPL_NO_RTTI
151 const std::type_info&
type() const noexcept
161 if(this->
vtable != rhs.vtable)
163 any tmp(std::move(rhs));
166 rhs.vtable = this->
vtable;
167 if(this->
vtable !=
nullptr)
183 if(this->
vtable !=
nullptr)
192 using stack_storage_t =
typename std::aligned_storage<2 *
sizeof(
void*), std::alignment_of<void*>::value>::
type;
204 #ifndef ANY_IMPL_NO_RTTI
205 const std::type_info& (*type)() noexcept;
229 #ifndef ANY_IMPL_NO_RTTI
230 static const std::type_info&
type() noexcept
249 dest.dynamic = src.dynamic;
250 src.dynamic =
nullptr;
264 #ifndef ANY_IMPL_NO_RTTI
265 static const std::type_info&
type() noexcept
278 new (&dest.
stack) T(
reinterpret_cast<const T&
>(src.
stack));
285 new (&dest.stack) T(std::move(
reinterpret_cast<T&
>(src.stack)));
292 move(rhs, tmp_storage);
294 move(tmp_storage, lhs);
301 std::integral_constant<bool,
302 !(std::is_nothrow_move_constructible<T>::value
303 && sizeof(T) <= sizeof(storage_union::stack)
304 && std::alignment_of<T>::value <= std::alignment_of<storage_union::stack_storage_t>::value)>
309 static vtable_type* vtable_for_type()
311 using VTableType = typename std::conditional<requires_allocation<T>::value, vtable_dynamic<T>, vtable_stack<T>>::type;
312 static vtable_type table = {
313 #ifndef ANY_IMPL_NO_RTTI
317 VTableType::copy, VTableType::move,
325 friend const T* any_cast(const any* operand) noexcept;
327 friend T* any_cast(any* operand) noexcept;
329 #ifndef ANY_IMPL_NO_RTTI
331 bool is_typed(const std::type_info& t) const
333 return is_same(this->type(), t);
337 #ifndef ANY_IMPL_NO_RTTI
344 static bool is_same(const std::type_info& a, const std::type_info& b)
346 #ifdef ANY_IMPL_FAST_TYPE_INFO_COMPARE
356 const T* cast() const noexcept
358 return requires_allocation<typename std::decay<T>::type>::value?
359 reinterpret_cast<const T*>(storage.dynamic) :
360 reinterpret_cast<const T*>(&storage.stack);
367 return requires_allocation<typename std::decay<T>::type>::value?
368 reinterpret_cast<T*>(storage.dynamic) :
369 reinterpret_cast<T*>(&storage.stack);
373 storage_union storage;
376 template<typename ValueType, typename T>
377 typename std::enable_if<requires_allocation<T>::value>::type
378 do_construct(ValueType&& value)
380 storage.dynamic = new T(std::forward<ValueType>(value));
383 template<typename ValueType, typename T>
384 typename std::enable_if<!requires_allocation<T>::value>::type
385 do_construct(ValueType&& value)
387 new (&storage.stack) T(std::forward<ValueType>(value));
392 template<typename ValueType>
393 void construct(ValueType&& value)
395 using T = typename std::decay<ValueType>::type;
399 do_construct<ValueType,T>(std::forward<ValueType>(value));
407 template<
typename ValueType>
410 return std::move(*p);
413 template<
typename ValueType>
421 template<
typename ValueType>
425 #ifndef ANY_IMPL_NO_EXCEPTIONS
432 template<
typename ValueType>
436 #ifndef ANY_IMPL_NO_EXCEPTIONS
447 template<
typename ValueType>
450 using can_move = std::integral_constant<bool,
451 std::is_move_constructible<ValueType>::value
452 && !std::is_lvalue_reference<ValueType>::value>;
455 #ifndef ANY_IMPL_NO_EXCEPTIONS
458 return detail::any_cast_move_if_true<ValueType>(p, can_move());
463 template<
typename ValueType>
468 #ifndef ANY_IMPL_NO_RTTI
469 if (operand && operand->is_typed(
typeid(T)))
471 if (operand && operand->vtable == any::vtable_for_type<T>())
473 return operand->cast<ValueType>();
480 template<
typename ValueType>
485 #ifndef ANY_IMPL_NO_RTTI
486 if (operand && operand->is_typed(
typeid(T)))
488 if (operand && operand->vtable == any::vtable_for_type<T>())
490 return operand->cast<ValueType>();