2 //===------------------------------ any -----------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
19 class bad_any_cast : public bad_cast
22 virtual const char* what() const noexcept;
29 // 6.3.1 any construct/destruct
32 any(const any& other);
33 any(any&& other) noexcept;
35 template <class ValueType>
36 any(ValueType&& value);
40 // 6.3.2 any assignments
41 any& operator=(const any& rhs);
42 any& operator=(any&& rhs) noexcept;
44 template <class ValueType>
45 any& operator=(ValueType&& rhs);
47 // 6.3.3 any modifiers
48 template <class ValueType, class... Args>
49 decay_t<ValueType>& emplace(Args&&... args);
50 template <class ValueType, class U, class... Args>
51 decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
52 void reset() noexcept;
53 void swap(any& rhs) noexcept;
55 // 6.3.4 any observers
56 bool has_value() const noexcept;
57 const type_info& type() const noexcept;
60 // 6.4 Non-member functions
61 void swap(any& x, any& y) noexcept;
63 template <class T, class ...Args>
64 any make_any(Args&& ...args);
65 template <class T, class U, class ...Args>
66 any make_any(initializer_list<U>, Args&& ...args);
68 template<class ValueType>
69 ValueType any_cast(const any& operand);
70 template<class ValueType>
71 ValueType any_cast(any& operand);
72 template<class ValueType>
73 ValueType any_cast(any&& operand);
75 template<class ValueType>
76 const ValueType* any_cast(const any* operand) noexcept;
77 template<class ValueType>
78 ValueType* any_cast(any* operand) noexcept;
84 #include <experimental/__config>
88 #include <type_traits>
92 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
93 #pragma GCC system_header
97 class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
100 virtual const char* what() const _NOEXCEPT;
104 _LIBCPP_BEGIN_NAMESPACE_STD
106 #if _LIBCPP_STD_VER > 14
108 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
109 _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
110 void __throw_bad_any_cast()
112 #ifndef _LIBCPP_NO_EXCEPTIONS
113 throw bad_any_cast();
119 // Forward declarations
120 class _LIBCPP_TEMPLATE_VIS any;
122 template <class _ValueType>
123 _LIBCPP_INLINE_VISIBILITY
124 add_pointer_t<add_const_t<_ValueType>>
125 any_cast(any const *) _NOEXCEPT;
127 template <class _ValueType>
128 _LIBCPP_INLINE_VISIBILITY
129 add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
133 using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
136 using _IsSmallObject = integral_constant<bool
137 , sizeof(_Tp) <= sizeof(_Buffer)
138 && alignment_of<_Buffer>::value
139 % alignment_of<_Tp>::value == 0
140 && is_nothrow_move_constructible<_Tp>::value
151 template <class _Tp> struct _SmallHandler;
152 template <class _Tp> struct _LargeHandler;
155 struct _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; };
156 template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
159 inline _LIBCPP_INLINE_VISIBILITY
160 constexpr const void* __get_fallback_typeid() {
161 return &__unique_typeinfo<decay_t<_Tp>>::__id;
165 inline _LIBCPP_INLINE_VISIBILITY
166 bool __compare_typeid(type_info const* __id, const void* __fallback_id)
168 #if !defined(_LIBCPP_NO_RTTI)
169 if (__id && *__id == typeid(_Tp))
172 if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
178 using _Handler = conditional_t<
179 _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
181 } // namespace __any_imp
183 class _LIBCPP_TEMPLATE_VIS any
186 // construct/destruct
187 _LIBCPP_INLINE_VISIBILITY
188 constexpr any() _NOEXCEPT : __h(nullptr) {}
190 _LIBCPP_INLINE_VISIBILITY
191 any(any const & __other) : __h(nullptr)
193 if (__other.__h) __other.__call(_Action::_Copy, this);
196 _LIBCPP_INLINE_VISIBILITY
197 any(any && __other) _NOEXCEPT : __h(nullptr)
199 if (__other.__h) __other.__call(_Action::_Move, this);
204 , class _Tp = decay_t<_ValueType>
205 , class = enable_if_t<
206 !is_same<_Tp, any>::value &&
207 !__is_inplace_type<_ValueType>::value &&
208 is_copy_constructible<_Tp>::value>
210 _LIBCPP_INLINE_VISIBILITY
211 any(_ValueType && __value);
213 template <class _ValueType, class ..._Args,
214 class _Tp = decay_t<_ValueType>,
216 is_constructible<_Tp, _Args...>::value &&
217 is_copy_constructible<_Tp>::value
220 _LIBCPP_INLINE_VISIBILITY
221 explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
223 template <class _ValueType, class _Up, class ..._Args,
224 class _Tp = decay_t<_ValueType>,
226 is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
227 is_copy_constructible<_Tp>::value>
229 _LIBCPP_INLINE_VISIBILITY
230 explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
232 _LIBCPP_INLINE_VISIBILITY
233 ~any() { this->reset(); }
236 _LIBCPP_INLINE_VISIBILITY
237 any & operator=(any const & __rhs) {
238 any(__rhs).swap(*this);
242 _LIBCPP_INLINE_VISIBILITY
243 any & operator=(any && __rhs) _NOEXCEPT {
244 any(_VSTD::move(__rhs)).swap(*this);
250 , class _Tp = decay_t<_ValueType>
251 , class = enable_if_t<
252 !is_same<_Tp, any>::value
253 && is_copy_constructible<_Tp>::value>
255 _LIBCPP_INLINE_VISIBILITY
256 any & operator=(_ValueType && __rhs);
258 template <class _ValueType, class ..._Args,
259 class _Tp = decay_t<_ValueType>,
261 is_constructible<_Tp, _Args...>::value &&
262 is_copy_constructible<_Tp>::value>
264 _LIBCPP_INLINE_VISIBILITY
265 _Tp& emplace(_Args&&... args);
267 template <class _ValueType, class _Up, class ..._Args,
268 class _Tp = decay_t<_ValueType>,
270 is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
271 is_copy_constructible<_Tp>::value>
273 _LIBCPP_INLINE_VISIBILITY
274 _Tp& emplace(initializer_list<_Up>, _Args&&...);
276 // 6.3.3 any modifiers
277 _LIBCPP_INLINE_VISIBILITY
278 void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); }
280 _LIBCPP_INLINE_VISIBILITY
281 void swap(any & __rhs) _NOEXCEPT;
283 // 6.3.4 any observers
284 _LIBCPP_INLINE_VISIBILITY
285 bool has_value() const _NOEXCEPT { return __h != nullptr; }
287 #if !defined(_LIBCPP_NO_RTTI)
288 _LIBCPP_INLINE_VISIBILITY
289 const type_info & type() const _NOEXCEPT {
291 return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
299 typedef __any_imp::_Action _Action;
300 using _HandleFuncPtr = void* (*)(_Action, any const *, any *, const type_info *,
301 const void* __fallback_info);
304 constexpr _Storage() : __ptr(nullptr) {}
306 __any_imp::_Buffer __buf;
309 _LIBCPP_INLINE_VISIBILITY
310 void * __call(_Action __a, any * __other = nullptr,
311 type_info const * __info = nullptr,
312 const void* __fallback_info = nullptr) const
314 return __h(__a, this, __other, __info, __fallback_info);
317 _LIBCPP_INLINE_VISIBILITY
318 void * __call(_Action __a, any * __other = nullptr,
319 type_info const * __info = nullptr,
320 const void* __fallback_info = nullptr)
322 return __h(__a, this, __other, __info, __fallback_info);
326 friend struct __any_imp::_SmallHandler;
328 friend struct __any_imp::_LargeHandler;
330 template <class _ValueType>
331 friend add_pointer_t<add_const_t<_ValueType>>
332 any_cast(any const *) _NOEXCEPT;
334 template <class _ValueType>
335 friend add_pointer_t<_ValueType>
336 any_cast(any *) _NOEXCEPT;
338 _HandleFuncPtr __h = nullptr;
345 struct _LIBCPP_TEMPLATE_VIS _SmallHandler
347 _LIBCPP_INLINE_VISIBILITY
348 static void* __handle(_Action __act, any const * __this, any * __other,
349 type_info const * __info, const void* __fallback_info)
353 case _Action::_Destroy:
354 __destroy(const_cast<any &>(*__this));
357 __copy(*__this, *__other);
360 __move(const_cast<any &>(*__this), *__other);
363 return __get(const_cast<any &>(*__this), __info, __fallback_info);
364 case _Action::_TypeInfo:
365 return __type_info();
369 template <class ..._Args>
370 _LIBCPP_INLINE_VISIBILITY
371 static _Tp& __create(any & __dest, _Args&&... __args) {
372 _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
373 __dest.__h = &_SmallHandler::__handle;
378 _LIBCPP_INLINE_VISIBILITY
379 static void __destroy(any & __this) {
380 _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
382 __this.__h = nullptr;
385 _LIBCPP_INLINE_VISIBILITY
386 static void __copy(any const & __this, any & __dest) {
387 _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
388 static_cast<void const *>(&__this.__s.__buf)));
391 _LIBCPP_INLINE_VISIBILITY
392 static void __move(any & __this, any & __dest) {
393 _SmallHandler::__create(__dest, _VSTD::move(
394 *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
398 _LIBCPP_INLINE_VISIBILITY
399 static void* __get(any & __this,
400 type_info const * __info,
401 const void* __fallback_id)
403 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
404 return static_cast<void*>(&__this.__s.__buf);
408 _LIBCPP_INLINE_VISIBILITY
409 static void* __type_info()
411 #if !defined(_LIBCPP_NO_RTTI)
412 return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
420 struct _LIBCPP_TEMPLATE_VIS _LargeHandler
422 _LIBCPP_INLINE_VISIBILITY
423 static void* __handle(_Action __act, any const * __this,
424 any * __other, type_info const * __info,
425 void const* __fallback_info)
429 case _Action::_Destroy:
430 __destroy(const_cast<any &>(*__this));
433 __copy(*__this, *__other);
436 __move(const_cast<any &>(*__this), *__other);
439 return __get(const_cast<any &>(*__this), __info, __fallback_info);
440 case _Action::_TypeInfo:
441 return __type_info();
445 template <class ..._Args>
446 _LIBCPP_INLINE_VISIBILITY
447 static _Tp& __create(any & __dest, _Args&&... __args) {
448 typedef allocator<_Tp> _Alloc;
449 typedef __allocator_destructor<_Alloc> _Dp;
451 unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
452 _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...);
453 __dest.__s.__ptr = __hold.release();
454 __dest.__h = &_LargeHandler::__handle;
460 _LIBCPP_INLINE_VISIBILITY
461 static void __destroy(any & __this){
462 delete static_cast<_Tp*>(__this.__s.__ptr);
463 __this.__h = nullptr;
466 _LIBCPP_INLINE_VISIBILITY
467 static void __copy(any const & __this, any & __dest) {
468 _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
471 _LIBCPP_INLINE_VISIBILITY
472 static void __move(any & __this, any & __dest) {
473 __dest.__s.__ptr = __this.__s.__ptr;
474 __dest.__h = &_LargeHandler::__handle;
475 __this.__h = nullptr;
478 _LIBCPP_INLINE_VISIBILITY
479 static void* __get(any & __this, type_info const * __info,
480 void const* __fallback_info)
482 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
483 return static_cast<void*>(__this.__s.__ptr);
488 _LIBCPP_INLINE_VISIBILITY
489 static void* __type_info()
491 #if !defined(_LIBCPP_NO_RTTI)
492 return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
499 } // namespace __any_imp
502 template <class _ValueType, class _Tp, class>
503 any::any(_ValueType && __v) : __h(nullptr)
505 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
508 template <class _ValueType, class ..._Args, class _Tp, class>
509 any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
510 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
513 template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
514 any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
515 __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
518 template <class _ValueType, class, class>
519 inline _LIBCPP_INLINE_VISIBILITY
520 any & any::operator=(_ValueType && __v)
522 any(_VSTD::forward<_ValueType>(__v)).swap(*this);
526 template <class _ValueType, class ..._Args, class _Tp, class>
527 inline _LIBCPP_INLINE_VISIBILITY
528 _Tp& any::emplace(_Args&&... __args) {
530 return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
533 template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
534 inline _LIBCPP_INLINE_VISIBILITY
535 _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
537 return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
540 inline _LIBCPP_INLINE_VISIBILITY
541 void any::swap(any & __rhs) _NOEXCEPT
545 if (__h && __rhs.__h) {
547 __rhs.__call(_Action::_Move, &__tmp);
548 this->__call(_Action::_Move, &__rhs);
549 __tmp.__call(_Action::_Move, this);
552 this->__call(_Action::_Move, &__rhs);
554 else if (__rhs.__h) {
555 __rhs.__call(_Action::_Move, this);
559 // 6.4 Non-member functions
561 inline _LIBCPP_INLINE_VISIBILITY
562 void swap(any & __lhs, any & __rhs) _NOEXCEPT
567 template <class _Tp, class ..._Args>
568 inline _LIBCPP_INLINE_VISIBILITY
569 any make_any(_Args&&... __args) {
570 return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...);
573 template <class _Tp, class _Up, class ..._Args>
574 inline _LIBCPP_INLINE_VISIBILITY
575 any make_any(initializer_list<_Up> __il, _Args&&... __args) {
576 return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
579 template <class _ValueType>
580 inline _LIBCPP_INLINE_VISIBILITY
581 _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
582 _ValueType any_cast(any const & __v)
584 using _RawValueType = __uncvref_t<_ValueType>;
585 static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
586 "ValueType is required to be a const lvalue reference "
587 "or a CopyConstructible type");
588 auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
589 if (__tmp == nullptr)
590 __throw_bad_any_cast();
591 return static_cast<_ValueType>(*__tmp);
594 template <class _ValueType>
595 inline _LIBCPP_INLINE_VISIBILITY
596 _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
597 _ValueType any_cast(any & __v)
599 using _RawValueType = __uncvref_t<_ValueType>;
600 static_assert(is_constructible<_ValueType, _RawValueType &>::value,
601 "ValueType is required to be an lvalue reference "
602 "or a CopyConstructible type");
603 auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
604 if (__tmp == nullptr)
605 __throw_bad_any_cast();
606 return static_cast<_ValueType>(*__tmp);
609 template <class _ValueType>
610 inline _LIBCPP_INLINE_VISIBILITY
611 _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
612 _ValueType any_cast(any && __v)
614 using _RawValueType = __uncvref_t<_ValueType>;
615 static_assert(is_constructible<_ValueType, _RawValueType>::value,
616 "ValueType is required to be an rvalue reference "
617 "or a CopyConstructible type");
618 auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
619 if (__tmp == nullptr)
620 __throw_bad_any_cast();
621 return static_cast<_ValueType>(_VSTD::move(*__tmp));
624 template <class _ValueType>
625 inline _LIBCPP_INLINE_VISIBILITY
626 add_pointer_t<add_const_t<_ValueType>>
627 any_cast(any const * __any) _NOEXCEPT
629 static_assert(!is_reference<_ValueType>::value,
630 "_ValueType may not be a reference.");
631 return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
634 template <class _RetType>
635 inline _LIBCPP_INLINE_VISIBILITY
636 _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
637 return static_cast<_RetType>(__p);
640 template <class _RetType>
641 inline _LIBCPP_INLINE_VISIBILITY
642 _RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
646 template <class _ValueType>
647 add_pointer_t<_ValueType>
648 any_cast(any * __any) _NOEXCEPT
650 using __any_imp::_Action;
651 static_assert(!is_reference<_ValueType>::value,
652 "_ValueType may not be a reference.");
653 typedef typename add_pointer<_ValueType>::type _ReturnType;
654 if (__any && __any->__h) {
655 void *__p = __any->__call(_Action::_Get, nullptr,
656 #if !defined(_LIBCPP_NO_RTTI)
661 __any_imp::__get_fallback_typeid<_ValueType>());
662 return _VSTD::__pointer_or_func_cast<_ReturnType>(
663 __p, is_function<_ValueType>{});
668 #endif // _LIBCPP_STD_VER > 14
670 _LIBCPP_END_NAMESPACE_STD
672 #endif // _LIBCPP_ANY