33 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
35 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
37 #include "detail/config.hpp"
42 #include <initializer_list>
46 BPSTD_COMPILER_DIAGNOSTIC_PREAMBLE
58 const char* what()
const noexcept
override;
109 template<
typename ValueType,
110 typename=enable_if_t<!is_same<decay_t<ValueType>,
any>::value &&
111 is_copy_constructible<decay_t<ValueType>>::value>>
113 any(ValueType&& value);
122 template<
typename ValueType,
typename...Args,
123 typename=enable_if_t<is_constructible<decay_t<ValueType>,Args...>::value &&
124 is_copy_constructible<decay_t<ValueType>>::value>>
135 template<
typename ValueType,
typename U,
typename...Args,
136 typename=enable_if_t<is_constructible<decay_t<ValueType>,std::initializer_list<U>,Args...>::value &&
137 is_copy_constructible<decay_t<ValueType>>::value>>
139 std::initializer_list<U> il,
164 template<
typename ValueType,
165 typename=enable_if_t<!is_same<decay_t<ValueType>,
any>::value &&
166 is_copy_constructible<decay_t<ValueType>>::value>>
181 template<
typename ValueType,
typename...Args,
182 typename=enable_if_t<is_constructible<decay_t<ValueType>,Args...>::value &&
183 is_copy_constructible<decay_t<ValueType>>::value>>
184 decay_t<ValueType>&
emplace(Args&&...args);
185 template<
typename ValueType,
typename U,
typename...Args,
186 typename=enable_if_t<is_constructible<decay_t<ValueType>,std::initializer_list<U>,Args...>::value &&
187 is_copy_constructible<decay_t<ValueType>>::value>>
188 decay_t<ValueType>&
emplace(std::initializer_list<U> il, Args&&...args );
193 void reset() noexcept;
201 void swap(
any& other) noexcept;
217 const std::type_info&
type()
const noexcept;
225 static constexpr
auto buffer_size = 4u *
sizeof(
void*);
226 static constexpr
auto buffer_align =
alignof(
void*);
233 internal_buffer
internal;
241 using requires_internal_storage = bool_constant<
242 (
sizeof(T) <= buffer_size) &&
243 ((buffer_align %
alignof(T)) == 0) &&
244 is_nothrow_move_constructible<T>::value
250 struct internal_storage_handler;
253 struct external_storage_handler;
256 using storage_handler = conditional_t<
257 requires_internal_storage<T>::value,
258 internal_storage_handler<T>,
259 external_storage_handler<T>
275 using storage_handler_ptr =
const void*(*)(operation,
const storage*,
const storage*);
288 storage_handler_ptr m_storage_handler;
338 const char* bpstd::bad_any_cast::what()
341 return "bad_any_cast";
349 struct bpstd::any::internal_storage_handler
351 template<
typename...Args>
352 static T* construct(storage& s, Args&&...args);
354 template<
typename U,
typename...Args>
355 static T* construct(storage& s, std::initializer_list<U> il, Args&&...args);
357 static void destroy(storage& s);
359 static const void* handle(operation op,
361 const storage* other);
369 template<
typename...Args>
370 inline BPSTD_INLINE_VISIBILITY
371 T* bpstd::any::internal_storage_handler<T>
372 ::construct(storage& s, Args&&...args)
374 return ::new(&s.internal) T(bpstd::forward<Args>(args)...);
378 template<typename U, typename...Args>
379 inline BPSTD_INLINE_VISIBILITY
380 T* bpstd::any::internal_storage_handler<T>
381 ::construct(storage& s, std::initializer_list<U> il, Args&&...args)
383 return ::new(&s.internal) T(il, bpstd::forward<Args>(args)...);
387 inline BPSTD_INLINE_VISIBILITY
388 void bpstd::any::internal_storage_handler<T>
389 ::destroy(storage& s)
391 auto* t =
static_cast<T*
>(
static_cast<void*
>(&s.internal));
396 inline BPSTD_INLINE_VISIBILITY
397 const void* bpstd::any::internal_storage_handler<T>
398 ::handle(operation op,
400 const storage* other)
404 case operation::destroy:
406 assert(
self !=
nullptr);
409 destroy(
const_cast<storage&
>(*
self));
413 case operation::copy:
415 assert(
self !=
nullptr);
416 assert(other !=
nullptr);
419 const auto* p =
reinterpret_cast<const T*
>(&other->internal);
420 construct(
const_cast<storage&
>(*
self), *p);
424 case operation::move:
426 assert(
self !=
nullptr);
427 assert(other !=
nullptr);
430 const auto* p =
reinterpret_cast<const T*
>(&other->internal);
431 construct(
const_cast<storage&
>(*
self), bpstd::move(*
const_cast<T*
>(p)));
435 case operation::value:
437 assert(
self !=
nullptr);
445 const auto* p =
reinterpret_cast<const T*
>(&
self->internal);
446 return static_cast<const void*
>(p);
449 case operation::type:
454 return static_cast<const void*
>(&
typeid(T));
465 struct bpstd::any::external_storage_handler
467 template<
typename...Args>
468 static T* construct(storage& s, Args&&...args);
470 template<
typename U,
typename...Args>
471 static T* construct(storage& s, std::initializer_list<U> il, Args&&...args);
473 static void destroy(storage& s);
475 static const void* handle(operation op,
477 const storage* other);
486 template<
typename...Args>
487 inline BPSTD_INLINE_VISIBILITY
488 T* bpstd::any::external_storage_handler<T>
489 ::construct(storage& s, Args&&...args)
491 s.external =
new T(bpstd::forward<Args>(args)...);
492 return static_cast<T*
>(s.external);
496 template<
typename U,
typename...Args>
497 inline BPSTD_INLINE_VISIBILITY
498 T* bpstd::any::external_storage_handler<T>
499 ::construct(storage& s, std::initializer_list<U> il, Args&&...args)
501 s.external =
new T(il, bpstd::forward<Args>(args)...);
502 return static_cast<T*
>(s.external);
506 inline BPSTD_INLINE_VISIBILITY
507 void bpstd::any::external_storage_handler<T>
508 ::destroy(storage& s)
510 delete static_cast<T*
>(s.external);
514 inline BPSTD_INLINE_VISIBILITY
515 const void* bpstd::any::external_storage_handler<T>
516 ::handle( operation op,
518 const storage* other )
522 case operation::destroy:
524 assert(
self !=
nullptr);
527 destroy(
const_cast<storage&
>(*
self));
531 case operation::copy:
533 assert(
self !=
nullptr);
534 assert(other !=
nullptr);
537 construct(
const_cast<storage&
>(*
self),
538 *
static_cast<const T*
>(other->external));
542 case operation::move:
544 BPSTD_UNUSED(
self !=
nullptr);
545 assert(other !=
nullptr);
547 const auto p =
static_cast<const T*
>(other->external);
549 construct(
const_cast<storage&
>(*
self), bpstd::move(*
const_cast<T*
>(p)));
553 case operation::value:
555 assert(
self !=
nullptr);
560 return self->external;
563 case operation::type:
582 inline BPSTD_INLINE_VISIBILITY
586 m_storage_handler{
nullptr}
591 inline BPSTD_INLINE_VISIBILITY
595 m_storage_handler{other.m_storage_handler}
597 if (m_storage_handler !=
nullptr) {
598 m_storage_handler(operation::move, &m_storage, &other.m_storage);
602 inline BPSTD_INLINE_VISIBILITY
605 m_storage_handler{
nullptr}
608 if (other.m_storage_handler !=
nullptr) {
610 const auto handler = other.m_storage_handler;
612 handler(operation::copy, &m_storage, &other.m_storage);
613 m_storage_handler = handler;
617 template<
typename ValueType,
typename>
618 inline BPSTD_INLINE_VISIBILITY
621 m_storage_handler{
nullptr}
624 using handler_type = storage_handler<decay_t<ValueType>>;
626 handler_type::construct(m_storage, bpstd::forward<ValueType>(value));
627 m_storage_handler = &handler_type::handle;
630 template<
typename ValueType,
typename...Args,
typename>
631 inline BPSTD_INLINE_VISIBILITY
634 m_storage_handler{
nullptr}
637 using handler_type = storage_handler<decay_t<ValueType>>;
639 handler_type::construct(m_storage, bpstd::forward<Args>(args)...);
640 m_storage_handler = &handler_type::handle;
643 template<
typename ValueType,
typename U,
typename...Args,
typename>
644 inline BPSTD_INLINE_VISIBILITY
646 std::initializer_list<U> il,
649 m_storage_handler{
nullptr}
652 using handler_type = storage_handler<decay_t<ValueType>>;
654 handler_type::construct(m_storage, il, bpstd::forward<Args>(args)...);
655 m_storage_handler = &handler_type::handle;
660 inline BPSTD_INLINE_VISIBILITY
668 inline BPSTD_INLINE_VISIBILITY
674 if (other.m_storage_handler !=
nullptr) {
675 m_storage_handler = other.m_storage_handler;
676 m_storage_handler(operation::move, &m_storage, &other.m_storage);
682 inline BPSTD_INLINE_VISIBILITY
687 if (other.m_storage_handler !=
nullptr) {
689 const auto handler = other.m_storage_handler;
691 handler(operation::copy, &m_storage, &other.m_storage);
692 m_storage_handler = handler;
698 template<
typename ValueType,
typename>
699 inline BPSTD_INLINE_VISIBILITY
702 using handler_type = storage_handler<decay_t<ValueType>>;
706 handler_type::construct(m_storage, bpstd::forward<ValueType>(value));
707 m_storage_handler = &handler_type::handle;
716 template<
typename ValueType,
typename...Args,
typename>
717 inline BPSTD_INLINE_VISIBILITY
718 bpstd::decay_t<ValueType>&
721 using handler_type = storage_handler<decay_t<ValueType>>;
725 auto& result = *handler_type::construct(m_storage,
726 bpstd::forward<Args>(args)...);
727 m_storage_handler = &handler_type::handle;
732 template<
typename ValueType,
typename U,
typename...Args,
typename>
733 inline BPSTD_INLINE_VISIBILITY
734 bpstd::decay_t<ValueType>&
738 using handler_type = storage_handler<decay_t<ValueType>>;
742 auto& result = *handler_type::construct(m_storage,
744 bpstd::forward<Args>(args)...);
745 m_storage_handler = &handler_type::handle;
750 inline BPSTD_INLINE_VISIBILITY
754 if (m_storage_handler !=
nullptr) {
755 m_storage_handler(operation::destroy, &m_storage,
nullptr);
756 m_storage_handler =
nullptr;
760 inline BPSTD_INLINE_VISIBILITY
766 if (m_storage_handler !=
nullptr && other.m_storage_handler !=
nullptr)
771 tmp.m_storage_handler = m_storage_handler;
772 m_storage_handler(operation::move, &tmp.m_storage, &m_storage);
773 m_storage_handler(operation::destroy, &m_storage,
nullptr);
776 m_storage_handler = other.m_storage_handler;
777 m_storage_handler(operation::move, &m_storage, &other.m_storage);
778 m_storage_handler(operation::destroy, &other.m_storage,
nullptr);
781 other.m_storage_handler = tmp.m_storage_handler;
782 other.m_storage_handler(operation::move, &other.m_storage, &tmp.m_storage);
784 else if (other.m_storage_handler !=
nullptr)
786 swap(m_storage_handler, other.m_storage_handler);
789 m_storage_handler(operation::move, &m_storage, &other.m_storage);
790 m_storage_handler(operation::destroy, &other.m_storage,
nullptr);
792 else if (m_storage_handler !=
nullptr)
794 swap(m_storage_handler, other.m_storage_handler);
797 other.m_storage_handler(operation::move, &other.m_storage, &m_storage);
798 other.m_storage_handler(operation::destroy, &m_storage,
nullptr);
806 inline BPSTD_INLINE_VISIBILITY
810 return m_storage_handler !=
nullptr;
813 inline BPSTD_INLINE_VISIBILITY
818 auto* p = m_storage_handler(operation::type,
nullptr,
nullptr);
819 return (*
static_cast<const std::type_info*
>(p));
832 inline BPSTD_INLINE_VISIBILITY
844 inline BPSTD_INLINE_VISIBILITY
845 T bpstd::any_cast(any& operand)
847 using underlying_type = remove_cvref_t<T>;
850 is_constructible<T, underlying_type&>::value,
851 "A program is ill-formed if T is not constructible from U&"
854 auto* p = any_cast<underlying_type>(&operand);
856 throw bad_any_cast{};
858 return static_cast<T
>(*p);
862 inline BPSTD_INLINE_VISIBILITY
865 using underlying_type = remove_cvref_t<T>;
868 is_constructible<T, underlying_type>::value,
869 "A program is ill-formed if T is not constructible from U"
872 auto* p = any_cast<underlying_type>(&operand);
874 throw bad_any_cast{};
876 return static_cast<T
>(bpstd::move(*p));
880 inline BPSTD_INLINE_VISIBILITY
883 using underlying_type = remove_cvref_t<T>;
886 is_constructible<T, const underlying_type&>::value,
887 "A program is ill-formed if T is not constructible from const U&"
890 const auto* p = any_cast<underlying_type>(&operand);
892 throw bad_any_cast{};
894 return static_cast<T
>(*p);
898 inline BPSTD_INLINE_VISIBILITY
905 if (operand->type() !=
typeid(T)) {
909 auto p = operand->m_storage_handler(any::operation::value,
912 return const_cast<T*
>(
static_cast<const T*
>(p));
916 inline BPSTD_INLINE_VISIBILITY
923 if (operand->type() !=
typeid(T)) {
927 auto* p = operand->m_storage_handler(any::operation::value,
930 return static_cast<const T*
>(p);
933 BPSTD_COMPILER_DIAGNOSTIC_POSTAMBLE