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>
91 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
92 #pragma GCC system_header
96 class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
99 virtual const char* what() const _NOEXCEPT;
103 _LIBCPP_BEGIN_NAMESPACE_STD
105 #if _LIBCPP_STD_VER > 14
107 _LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
108 void __throw_bad_any_cast()
110 #ifndef _LIBCPP_NO_EXCEPTIONS
111 throw bad_any_cast();
117 // Forward declarations
118 class _LIBCPP_TEMPLATE_VIS any;
120 template <class _ValueType>
121 _LIBCPP_INLINE_VISIBILITY
122 add_pointer_t<add_const_t<_ValueType>>
123 any_cast(any const *) _NOEXCEPT;
125 template <class _ValueType>
126 _LIBCPP_INLINE_VISIBILITY
127 add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
131 using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
134 using _IsSmallObject = integral_constant<bool
135 , sizeof(_Tp) <= sizeof(_Buffer)
136 && alignment_of<_Buffer>::value
137 % alignment_of<_Tp>::value == 0
138 && is_nothrow_move_constructible<_Tp>::value
149 template <class _Tp> struct _SmallHandler;
150 template <class _Tp> struct _LargeHandler;
153 struct _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; };
154 template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
157 inline _LIBCPP_INLINE_VISIBILITY
158 constexpr const void* __get_fallback_typeid() {
159 return &__unique_typeinfo<decay_t<_Tp>>::__id;
163 inline _LIBCPP_INLINE_VISIBILITY
164 bool __compare_typeid(type_info const* __id, const void* __fallback_id)
166 #if !defined(_LIBCPP_NO_RTTI)
167 if (__id && *__id == typeid(_Tp))
170 if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
176 using _Handler = conditional_t<
177 _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
179 } // namespace __any_imp
181 class _LIBCPP_TEMPLATE_VIS any
184 // construct/destruct
185 _LIBCPP_INLINE_VISIBILITY
186 constexpr any() _NOEXCEPT : __h(nullptr) {}
188 _LIBCPP_INLINE_VISIBILITY
189 any(any const & __other) : __h(nullptr)
191 if (__other.__h) __other.__call(_Action::_Copy, this);
194 _LIBCPP_INLINE_VISIBILITY
195 any(any && __other) _NOEXCEPT : __h(nullptr)
197 if (__other.__h) __other.__call(_Action::_Move, this);
202 , class _Tp = decay_t<_ValueType>
203 , class = enable_if_t<
204 !is_same<_Tp, any>::value &&
205 !__is_inplace_type<_ValueType>::value &&
206 is_copy_constructible<_Tp>::value>
208 _LIBCPP_INLINE_VISIBILITY
209 any(_ValueType && __value);
211 template <class _ValueType, class ..._Args,
212 class _Tp = decay_t<_ValueType>,
214 is_constructible<_Tp, _Args...>::value &&
215 is_copy_constructible<_Tp>::value
218 _LIBCPP_INLINE_VISIBILITY
219 explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
221 template <class _ValueType, class _Up, class ..._Args,
222 class _Tp = decay_t<_ValueType>,
224 is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
225 is_copy_constructible<_Tp>::value>
227 _LIBCPP_INLINE_VISIBILITY
228 explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
230 _LIBCPP_INLINE_VISIBILITY
231 ~any() { this->reset(); }
234 _LIBCPP_INLINE_VISIBILITY
235 any & operator=(any const & __rhs) {
236 any(__rhs).swap(*this);
240 _LIBCPP_INLINE_VISIBILITY
241 any & operator=(any && __rhs) _NOEXCEPT {
242 any(_VSTD::move(__rhs)).swap(*this);
248 , class _Tp = decay_t<_ValueType>
249 , class = enable_if_t<
250 !is_same<_Tp, any>::value
251 && is_copy_constructible<_Tp>::value>
253 _LIBCPP_INLINE_VISIBILITY
254 any & operator=(_ValueType && __rhs);
256 template <class _ValueType, class ..._Args,
257 class _Tp = decay_t<_ValueType>,
259 is_constructible<_Tp, _Args...>::value &&
260 is_copy_constructible<_Tp>::value>
262 _LIBCPP_INLINE_VISIBILITY
263 _Tp& emplace(_Args&&... args);
265 template <class _ValueType, class _Up, class ..._Args,
266 class _Tp = decay_t<_ValueType>,
268 is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
269 is_copy_constructible<_Tp>::value>
271 _LIBCPP_INLINE_VISIBILITY
272 _Tp& emplace(initializer_list<_Up>, _Args&&...);
274 // 6.3.3 any modifiers
275 _LIBCPP_INLINE_VISIBILITY
276 void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); }
278 _LIBCPP_INLINE_VISIBILITY
279 void swap(any & __rhs) _NOEXCEPT;
281 // 6.3.4 any observers
282 _LIBCPP_INLINE_VISIBILITY
283 bool has_value() const _NOEXCEPT { return __h != nullptr; }
285 #if !defined(_LIBCPP_NO_RTTI)
286 _LIBCPP_INLINE_VISIBILITY
287 const type_info & type() const _NOEXCEPT {
289 return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
297 typedef __any_imp::_Action _Action;
298 using _HandleFuncPtr = void* (*)(_Action, any const *, any *, const type_info *,
299 const void* __fallback_info);
302 constexpr _Storage() : __ptr(nullptr) {}
304 __any_imp::_Buffer __buf;
307 _LIBCPP_ALWAYS_INLINE
308 void * __call(_Action __a, any * __other = nullptr,
309 type_info const * __info = nullptr,
310 const void* __fallback_info = nullptr) const
312 return __h(__a, this, __other, __info, __fallback_info);
315 _LIBCPP_ALWAYS_INLINE
316 void * __call(_Action __a, any * __other = nullptr,
317 type_info const * __info = nullptr,
318 const void* __fallback_info = nullptr)
320 return __h(__a, this, __other, __info, __fallback_info);
324 friend struct __any_imp::_SmallHandler;
326 friend struct __any_imp::_LargeHandler;
328 template <class _ValueType>
329 friend add_pointer_t<add_const_t<_ValueType>>
330 any_cast(any const *) _NOEXCEPT;
332 template <class _ValueType>
333 friend add_pointer_t<_ValueType>
334 any_cast(any *) _NOEXCEPT;
336 _HandleFuncPtr __h = nullptr;
343 struct _LIBCPP_TEMPLATE_VIS _SmallHandler
345 _LIBCPP_INLINE_VISIBILITY
346 static void* __handle(_Action __act, any const * __this, any * __other,
347 type_info const * __info, const void* __fallback_info)
351 case _Action::_Destroy:
352 __destroy(const_cast<any &>(*__this));
355 __copy(*__this, *__other);
358 __move(const_cast<any &>(*__this), *__other);
361 return __get(const_cast<any &>(*__this), __info, __fallback_info);
362 case _Action::_TypeInfo:
363 return __type_info();
367 template <class ..._Args>
368 _LIBCPP_INLINE_VISIBILITY
369 static _Tp& __create(any & __dest, _Args&&... __args) {
370 _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
371 __dest.__h = &_SmallHandler::__handle;
376 _LIBCPP_INLINE_VISIBILITY
377 static void __destroy(any & __this) {
378 _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
380 __this.__h = nullptr;
383 _LIBCPP_INLINE_VISIBILITY
384 static void __copy(any const & __this, any & __dest) {
385 _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
386 static_cast<void const *>(&__this.__s.__buf)));
389 _LIBCPP_INLINE_VISIBILITY
390 static void __move(any & __this, any & __dest) {
391 _SmallHandler::__create(__dest, _VSTD::move(
392 *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
396 _LIBCPP_INLINE_VISIBILITY
397 static void* __get(any & __this,
398 type_info const * __info,
399 const void* __fallback_id)
401 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
402 return static_cast<void*>(&__this.__s.__buf);
406 _LIBCPP_INLINE_VISIBILITY
407 static void* __type_info()
409 #if !defined(_LIBCPP_NO_RTTI)
410 return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
418 struct _LIBCPP_TEMPLATE_VIS _LargeHandler
420 _LIBCPP_INLINE_VISIBILITY
421 static void* __handle(_Action __act, any const * __this,
422 any * __other, type_info const * __info,
423 void const* __fallback_info)
427 case _Action::_Destroy:
428 __destroy(const_cast<any &>(*__this));
431 __copy(*__this, *__other);
434 __move(const_cast<any &>(*__this), *__other);
437 return __get(const_cast<any &>(*__this), __info, __fallback_info);
438 case _Action::_TypeInfo:
439 return __type_info();
443 template <class ..._Args>
444 _LIBCPP_INLINE_VISIBILITY
445 static _Tp& __create(any & __dest, _Args&&... __args) {
446 typedef allocator<_Tp> _Alloc;
447 typedef __allocator_destructor<_Alloc> _Dp;
449 unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
450 _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...);
451 __dest.__s.__ptr = __hold.release();
452 __dest.__h = &_LargeHandler::__handle;
458 _LIBCPP_INLINE_VISIBILITY
459 static void __destroy(any & __this){
460 delete static_cast<_Tp*>(__this.__s.__ptr);
461 __this.__h = nullptr;
464 _LIBCPP_INLINE_VISIBILITY
465 static void __copy(any const & __this, any & __dest) {
466 _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
469 _LIBCPP_INLINE_VISIBILITY
470 static void __move(any & __this, any & __dest) {
471 __dest.__s.__ptr = __this.__s.__ptr;
472 __dest.__h = &_LargeHandler::__handle;
473 __this.__h = nullptr;
476 _LIBCPP_INLINE_VISIBILITY
477 static void* __get(any & __this, type_info const * __info,
478 void const* __fallback_info)
480 if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
481 return static_cast<void*>(__this.__s.__ptr);
486 _LIBCPP_INLINE_VISIBILITY
487 static void* __type_info()
489 #if !defined(_LIBCPP_NO_RTTI)
490 return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
497 } // namespace __any_imp
500 template <class _ValueType, class _Tp, class>
501 any::any(_ValueType && __v) : __h(nullptr)
503 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
506 template <class _ValueType, class ..._Args, class _Tp, class>
507 any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
508 __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
511 template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
512 any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
513 __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
516 template <class _ValueType, class, class>
517 inline _LIBCPP_INLINE_VISIBILITY
518 any & any::operator=(_ValueType && __v)
520 any(_VSTD::forward<_ValueType>(__v)).swap(*this);
524 template <class _ValueType, class ..._Args, class _Tp, class>
525 inline _LIBCPP_INLINE_VISIBILITY
526 _Tp& any::emplace(_Args&&... __args) {
528 return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
531 template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
532 inline _LIBCPP_INLINE_VISIBILITY
533 _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
535 return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
538 inline _LIBCPP_INLINE_VISIBILITY
539 void any::swap(any & __rhs) _NOEXCEPT
543 if (__h && __rhs.__h) {
545 __rhs.__call(_Action::_Move, &__tmp);
546 this->__call(_Action::_Move, &__rhs);
547 __tmp.__call(_Action::_Move, this);
550 this->__call(_Action::_Move, &__rhs);
552 else if (__rhs.__h) {
553 __rhs.__call(_Action::_Move, this);
557 // 6.4 Non-member functions
559 inline _LIBCPP_INLINE_VISIBILITY
560 void swap(any & __lhs, any & __rhs) _NOEXCEPT
565 template <class _Tp, class ..._Args>
566 inline _LIBCPP_INLINE_VISIBILITY
567 any make_any(_Args&&... __args) {
568 return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...);
571 template <class _Tp, class _Up, class ..._Args>
572 inline _LIBCPP_INLINE_VISIBILITY
573 any make_any(initializer_list<_Up> __il, _Args&&... __args) {
574 return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
577 template <class _ValueType>
578 inline _LIBCPP_INLINE_VISIBILITY
579 _ValueType any_cast(any const & __v)
581 using _RawValueType = __uncvref_t<_ValueType>;
582 static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
583 "ValueType is required to be a const lvalue reference "
584 "or a CopyConstructible type");
585 auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
586 if (__tmp == nullptr)
587 __throw_bad_any_cast();
588 return static_cast<_ValueType>(*__tmp);
591 template <class _ValueType>
592 inline _LIBCPP_INLINE_VISIBILITY
593 _ValueType any_cast(any & __v)
595 using _RawValueType = __uncvref_t<_ValueType>;
596 static_assert(is_constructible<_ValueType, _RawValueType &>::value,
597 "ValueType is required to be an lvalue reference "
598 "or a CopyConstructible type");
599 auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
600 if (__tmp == nullptr)
601 __throw_bad_any_cast();
602 return static_cast<_ValueType>(*__tmp);
605 template <class _ValueType>
606 inline _LIBCPP_INLINE_VISIBILITY
607 _ValueType any_cast(any && __v)
609 using _RawValueType = __uncvref_t<_ValueType>;
610 static_assert(is_constructible<_ValueType, _RawValueType>::value,
611 "ValueType is required to be an rvalue reference "
612 "or a CopyConstructible type");
613 auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
614 if (__tmp == nullptr)
615 __throw_bad_any_cast();
616 return static_cast<_ValueType>(_VSTD::move(*__tmp));
619 template <class _ValueType>
620 inline _LIBCPP_INLINE_VISIBILITY
621 add_pointer_t<add_const_t<_ValueType>>
622 any_cast(any const * __any) _NOEXCEPT
624 static_assert(!is_reference<_ValueType>::value,
625 "_ValueType may not be a reference.");
626 return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
629 template <class _RetType>
630 inline _LIBCPP_INLINE_VISIBILITY
631 _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
632 return static_cast<_RetType>(__p);
635 template <class _RetType>
636 inline _LIBCPP_INLINE_VISIBILITY
637 _RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
641 template <class _ValueType>
642 add_pointer_t<_ValueType>
643 any_cast(any * __any) _NOEXCEPT
645 using __any_imp::_Action;
646 static_assert(!is_reference<_ValueType>::value,
647 "_ValueType may not be a reference.");
648 typedef typename add_pointer<_ValueType>::type _ReturnType;
649 if (__any && __any->__h) {
650 void *__p = __any->__call(_Action::_Get, nullptr,
651 #if !defined(_LIBCPP_NO_RTTI)
656 __any_imp::__get_fallback_typeid<_ValueType>());
657 return _VSTD::__pointer_or_func_cast<_ReturnType>(
658 __p, is_function<_ValueType>{});
663 #endif // _LIBCPP_STD_VER > 14
665 _LIBCPP_END_NAMESPACE_STD
667 #endif // _LIBCPP_ANY