10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_ANY 110b57cec5SDimitry Andric#define _LIBCPP_ANY 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric any synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std { 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric class bad_any_cast : public bad_cast 190b57cec5SDimitry Andric { 200b57cec5SDimitry Andric public: 210b57cec5SDimitry Andric virtual const char* what() const noexcept; 220b57cec5SDimitry Andric }; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric class any 250b57cec5SDimitry Andric { 260b57cec5SDimitry Andric public: 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric // 6.3.1 any construct/destruct 290b57cec5SDimitry Andric any() noexcept; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric any(const any& other); 320b57cec5SDimitry Andric any(any&& other) noexcept; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric template <class ValueType> 350b57cec5SDimitry Andric any(ValueType&& value); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric ~any(); 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric // 6.3.2 any assignments 400b57cec5SDimitry Andric any& operator=(const any& rhs); 410b57cec5SDimitry Andric any& operator=(any&& rhs) noexcept; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric template <class ValueType> 440b57cec5SDimitry Andric any& operator=(ValueType&& rhs); 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric // 6.3.3 any modifiers 470b57cec5SDimitry Andric template <class ValueType, class... Args> 480b57cec5SDimitry Andric decay_t<ValueType>& emplace(Args&&... args); 490b57cec5SDimitry Andric template <class ValueType, class U, class... Args> 500b57cec5SDimitry Andric decay_t<ValueType>& emplace(initializer_list<U>, Args&&...); 510b57cec5SDimitry Andric void reset() noexcept; 520b57cec5SDimitry Andric void swap(any& rhs) noexcept; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric // 6.3.4 any observers 550b57cec5SDimitry Andric bool has_value() const noexcept; 560b57cec5SDimitry Andric const type_info& type() const noexcept; 570b57cec5SDimitry Andric }; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric // 6.4 Non-member functions 600b57cec5SDimitry Andric void swap(any& x, any& y) noexcept; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric template <class T, class ...Args> 630b57cec5SDimitry Andric any make_any(Args&& ...args); 640b57cec5SDimitry Andric template <class T, class U, class ...Args> 650b57cec5SDimitry Andric any make_any(initializer_list<U>, Args&& ...args); 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric template<class ValueType> 680b57cec5SDimitry Andric ValueType any_cast(const any& operand); 690b57cec5SDimitry Andric template<class ValueType> 700b57cec5SDimitry Andric ValueType any_cast(any& operand); 710b57cec5SDimitry Andric template<class ValueType> 720b57cec5SDimitry Andric ValueType any_cast(any&& operand); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric template<class ValueType> 750b57cec5SDimitry Andric const ValueType* any_cast(const any* operand) noexcept; 760b57cec5SDimitry Andric template<class ValueType> 770b57cec5SDimitry Andric ValueType* any_cast(any* operand) noexcept; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric} // namespace std 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric*/ 820b57cec5SDimitry Andric 8381ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 84e8d8bef9SDimitry Andric#include <__availability> 85fe6060f1SDimitry Andric#include <__config> 86bdd1243dSDimitry Andric#include <__memory/allocator.h> 87bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h> 88bdd1243dSDimitry Andric#include <__memory/allocator_traits.h> 89bdd1243dSDimitry Andric#include <__memory/unique_ptr.h> 9006c3fb27SDimitry Andric#include <__type_traits/add_const.h> 9106c3fb27SDimitry Andric#include <__type_traits/add_pointer.h> 9206c3fb27SDimitry Andric#include <__type_traits/aligned_storage.h> 9306c3fb27SDimitry Andric#include <__type_traits/conditional.h> 9406c3fb27SDimitry Andric#include <__type_traits/decay.h> 9506c3fb27SDimitry Andric#include <__type_traits/is_constructible.h> 9606c3fb27SDimitry Andric#include <__type_traits/is_copy_constructible.h> 9706c3fb27SDimitry Andric#include <__type_traits/is_function.h> 9806c3fb27SDimitry Andric#include <__type_traits/is_nothrow_move_constructible.h> 9906c3fb27SDimitry Andric#include <__type_traits/is_reference.h> 10006c3fb27SDimitry Andric#include <__type_traits/is_same.h> 10106c3fb27SDimitry Andric#include <__type_traits/remove_cv.h> 10206c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h> 10306c3fb27SDimitry Andric#include <__type_traits/remove_reference.h> 104fe6060f1SDimitry Andric#include <__utility/forward.h> 10581ad6265SDimitry Andric#include <__utility/in_place.h> 10681ad6265SDimitry Andric#include <__utility/move.h> 10781ad6265SDimitry Andric#include <__utility/unreachable.h> 10806c3fb27SDimitry Andric#include <__verbose_abort> 10981ad6265SDimitry Andric#include <initializer_list> 110fe6060f1SDimitry Andric#include <typeinfo> 1110b57cec5SDimitry Andric#include <version> 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1140b57cec5SDimitry Andric# pragma GCC system_header 1150b57cec5SDimitry Andric#endif 1160b57cec5SDimitry Andric 11706c3fb27SDimitry Andric_LIBCPP_PUSH_MACROS 11806c3fb27SDimitry Andric#include <__undef_macros> 11906c3fb27SDimitry Andric 1200b57cec5SDimitry Andricnamespace std { 121*cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast { 1220b57cec5SDimitry Andricpublic: 123bdd1243dSDimitry Andric const char* what() const _NOEXCEPT override; 1240b57cec5SDimitry Andric}; 1250b57cec5SDimitry Andric} // namespace std 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1280b57cec5SDimitry Andric 12906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17 1300b57cec5SDimitry Andric 131*cb14a3feSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST void __throw_bad_any_cast() { 13206c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_EXCEPTIONS 1330b57cec5SDimitry Andric throw bad_any_cast(); 1340b57cec5SDimitry Andric# else 13506c3fb27SDimitry Andric _LIBCPP_VERBOSE_ABORT("bad_any_cast was thrown in -fno-exceptions mode"); 1360b57cec5SDimitry Andric# endif 1370b57cec5SDimitry Andric} 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric// Forward declarations 1400b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS any; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andrictemplate <class _ValueType> 143*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andrictemplate <class _ValueType> 146*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT; 1470b57cec5SDimitry Andric 148*cb14a3feSDimitry Andricnamespace __any_imp { 149bdd1243dSDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH 1505f757f3fSDimitry Andricusing _Buffer = aligned_storage_t<3 * sizeof(void*), alignof(void*)>; 151bdd1243dSDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_POP 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andrictemplate <class _Tp> 154*cb14a3feSDimitry Andricusing _IsSmallObject = 155*cb14a3feSDimitry Andric integral_constant<bool, 156*cb14a3feSDimitry Andric sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 && 157*cb14a3feSDimitry Andric is_nothrow_move_constructible<_Tp>::value >; 1580b57cec5SDimitry Andric 159*cb14a3feSDimitry Andricenum class _Action { _Destroy, _Copy, _Move, _Get, _TypeInfo }; 160*cb14a3feSDimitry Andric 161*cb14a3feSDimitry Andrictemplate <class _Tp> 162*cb14a3feSDimitry Andricstruct _SmallHandler; 163*cb14a3feSDimitry Andrictemplate <class _Tp> 164*cb14a3feSDimitry Andricstruct _LargeHandler; 165*cb14a3feSDimitry Andric 166*cb14a3feSDimitry Andrictemplate <class _Tp> 167*cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __unique_typeinfo { 168*cb14a3feSDimitry Andric static constexpr int __id = 0; 1690b57cec5SDimitry Andric}; 170*cb14a3feSDimitry Andrictemplate <class _Tp> 171*cb14a3feSDimitry Andricconstexpr int __unique_typeinfo<_Tp>::__id; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andrictemplate <class _Tp> 174*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr const void* __get_fallback_typeid() { 175e8d8bef9SDimitry Andric return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id; 1760b57cec5SDimitry Andric} 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andrictemplate <class _Tp> 179*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool __compare_typeid(type_info const* __id, const void* __fallback_id) { 1801ac55f4cSDimitry Andric# if !defined(_LIBCPP_HAS_NO_RTTI) 1810b57cec5SDimitry Andric if (__id && *__id == typeid(_Tp)) 1820b57cec5SDimitry Andric return true; 1830b57cec5SDimitry Andric# endif 1845f757f3fSDimitry Andric return !__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>(); 1850b57cec5SDimitry Andric} 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andrictemplate <class _Tp> 188*cb14a3feSDimitry Andricusing _Handler = conditional_t< _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric} // namespace __any_imp 1910b57cec5SDimitry Andric 192*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS any { 1930b57cec5SDimitry Andricpublic: 1940b57cec5SDimitry Andric // construct/destruct 195*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr any() _NOEXCEPT : __h_(nullptr) {} 1960b57cec5SDimitry Andric 197*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI any(any const& __other) : __h_(nullptr) { 198*cb14a3feSDimitry Andric if (__other.__h_) 199*cb14a3feSDimitry Andric __other.__call(_Action::_Copy, this); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 202*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI any(any&& __other) _NOEXCEPT : __h_(nullptr) { 203*cb14a3feSDimitry Andric if (__other.__h_) 204*cb14a3feSDimitry Andric __other.__call(_Action::_Move, this); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 207*cb14a3feSDimitry Andric template < class _ValueType, 2080b57cec5SDimitry Andric class _Tp = decay_t<_ValueType>, 209*cb14a3feSDimitry Andric class = enable_if_t< !is_same<_Tp, any>::value && !__is_inplace_type<_ValueType>::value && 210*cb14a3feSDimitry Andric is_copy_constructible<_Tp>::value> > 211*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI any(_ValueType&& __value); 2120b57cec5SDimitry Andric 213*cb14a3feSDimitry Andric template <class _ValueType, 214*cb14a3feSDimitry Andric class... _Args, 2150b57cec5SDimitry Andric class _Tp = decay_t<_ValueType>, 216*cb14a3feSDimitry Andric class = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value > > 217*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, _Args&&... __args); 2180b57cec5SDimitry Andric 219*cb14a3feSDimitry Andric template <class _ValueType, 220*cb14a3feSDimitry Andric class _Up, 221*cb14a3feSDimitry Andric class... _Args, 222*cb14a3feSDimitry Andric class _Tp = decay_t<_ValueType>, 223*cb14a3feSDimitry Andric class = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && 224*cb14a3feSDimitry Andric is_copy_constructible<_Tp>::value> > 225*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args); 226*cb14a3feSDimitry Andric 227*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI ~any() { this->reset(); } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric // assignments 230*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI any& operator=(any const& __rhs) { 2310b57cec5SDimitry Andric any(__rhs).swap(*this); 2320b57cec5SDimitry Andric return *this; 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 235*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI any& operator=(any&& __rhs) _NOEXCEPT { 2365f757f3fSDimitry Andric any(std::move(__rhs)).swap(*this); 2370b57cec5SDimitry Andric return *this; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 240*cb14a3feSDimitry Andric template < class _ValueType, 2410b57cec5SDimitry Andric class _Tp = decay_t<_ValueType>, 242*cb14a3feSDimitry Andric class = enable_if_t< !is_same<_Tp, any>::value && is_copy_constructible<_Tp>::value> > 243*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI any& operator=(_ValueType&& __rhs); 2440b57cec5SDimitry Andric 245*cb14a3feSDimitry Andric template <class _ValueType, 246*cb14a3feSDimitry Andric class... _Args, 2470b57cec5SDimitry Andric class _Tp = decay_t<_ValueType>, 248*cb14a3feSDimitry Andric class = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value> > 249*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp& emplace(_Args&&...); 250*cb14a3feSDimitry Andric 251*cb14a3feSDimitry Andric template <class _ValueType, 252*cb14a3feSDimitry Andric class _Up, 253*cb14a3feSDimitry Andric class... _Args, 254*cb14a3feSDimitry Andric class _Tp = decay_t<_ValueType>, 255*cb14a3feSDimitry Andric class = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && 256*cb14a3feSDimitry Andric is_copy_constructible<_Tp>::value> > 257*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp& emplace(initializer_list<_Up>, _Args&&...); 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric // 6.3.3 any modifiers 260*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT { 261*cb14a3feSDimitry Andric if (__h_) 262*cb14a3feSDimitry Andric this->__call(_Action::_Destroy); 263*cb14a3feSDimitry Andric } 2640b57cec5SDimitry Andric 265*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) _NOEXCEPT; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric // 6.3.4 any observers 268*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; } 2690b57cec5SDimitry Andric 2701ac55f4cSDimitry Andric# if !defined(_LIBCPP_HAS_NO_RTTI) 271*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT { 272bdd1243dSDimitry Andric if (__h_) { 2730b57cec5SDimitry Andric return *static_cast<type_info const*>(this->__call(_Action::_TypeInfo)); 2740b57cec5SDimitry Andric } else { 2750b57cec5SDimitry Andric return typeid(void); 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric# endif 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andricprivate: 2810b57cec5SDimitry Andric typedef __any_imp::_Action _Action; 282*cb14a3feSDimitry Andric using _HandleFuncPtr = void* (*)(_Action, any const*, any*, const type_info*, const void* __fallback_info); 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric union _Storage { 28506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {} 2860b57cec5SDimitry Andric void* __ptr; 2870b57cec5SDimitry Andric __any_imp::_Buffer __buf; 2880b57cec5SDimitry Andric }; 2890b57cec5SDimitry Andric 290*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void* 291*cb14a3feSDimitry Andric __call(_Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr) 292*cb14a3feSDimitry Andric const { 293bdd1243dSDimitry Andric return __h_(__a, this, __other, __info, __fallback_info); 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 296*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void* __call( 297*cb14a3feSDimitry Andric _Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr) { 298bdd1243dSDimitry Andric return __h_(__a, this, __other, __info, __fallback_info); 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric template <class> 3020b57cec5SDimitry Andric friend struct __any_imp::_SmallHandler; 3030b57cec5SDimitry Andric template <class> 3040b57cec5SDimitry Andric friend struct __any_imp::_LargeHandler; 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric template <class _ValueType> 307*cb14a3feSDimitry Andric friend add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT; 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric template <class _ValueType> 310*cb14a3feSDimitry Andric friend add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT; 3110b57cec5SDimitry Andric 312bdd1243dSDimitry Andric _HandleFuncPtr __h_ = nullptr; 313bdd1243dSDimitry Andric _Storage __s_; 3140b57cec5SDimitry Andric}; 3150b57cec5SDimitry Andric 316*cb14a3feSDimitry Andricnamespace __any_imp { 3170b57cec5SDimitry Andrictemplate <class _Tp> 318*cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS _SmallHandler { 319*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* 320*cb14a3feSDimitry Andric __handle(_Action __act, any const* __this, any* __other, type_info const* __info, const void* __fallback_info) { 321*cb14a3feSDimitry Andric switch (__act) { 3220b57cec5SDimitry Andric case _Action::_Destroy: 3230b57cec5SDimitry Andric __destroy(const_cast<any&>(*__this)); 3240b57cec5SDimitry Andric return nullptr; 3250b57cec5SDimitry Andric case _Action::_Copy: 3260b57cec5SDimitry Andric __copy(*__this, *__other); 3270b57cec5SDimitry Andric return nullptr; 3280b57cec5SDimitry Andric case _Action::_Move: 3290b57cec5SDimitry Andric __move(const_cast<any&>(*__this), *__other); 3300b57cec5SDimitry Andric return nullptr; 3310b57cec5SDimitry Andric case _Action::_Get: 3320b57cec5SDimitry Andric return __get(const_cast<any&>(*__this), __info, __fallback_info); 3330b57cec5SDimitry Andric case _Action::_TypeInfo: 3340b57cec5SDimitry Andric return __type_info(); 3350b57cec5SDimitry Andric } 33681ad6265SDimitry Andric __libcpp_unreachable(); 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric template <class... _Args> 340*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) { 341e8d8bef9SDimitry Andric typedef allocator<_Tp> _Alloc; 342e8d8bef9SDimitry Andric typedef allocator_traits<_Alloc> _ATraits; 343e8d8bef9SDimitry Andric _Alloc __a; 344bdd1243dSDimitry Andric _Tp* __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s_.__buf)); 3455f757f3fSDimitry Andric _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...); 346bdd1243dSDimitry Andric __dest.__h_ = &_SmallHandler::__handle; 3470b57cec5SDimitry Andric return *__ret; 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andricprivate: 351*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) { 352e8d8bef9SDimitry Andric typedef allocator<_Tp> _Alloc; 353e8d8bef9SDimitry Andric typedef allocator_traits<_Alloc> _ATraits; 354e8d8bef9SDimitry Andric _Alloc __a; 355bdd1243dSDimitry Andric _Tp* __p = static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf)); 356e8d8bef9SDimitry Andric _ATraits::destroy(__a, __p); 357bdd1243dSDimitry Andric __this.__h_ = nullptr; 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric 360*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) { 361*cb14a3feSDimitry Andric _SmallHandler::__create(__dest, *static_cast<_Tp const*>(static_cast<void const*>(&__this.__s_.__buf))); 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric 364*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) { 365*cb14a3feSDimitry Andric _SmallHandler::__create(__dest, std::move(*static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf)))); 3660b57cec5SDimitry Andric __destroy(__this); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 369*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, const void* __fallback_id) { 3700b57cec5SDimitry Andric if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id)) 371bdd1243dSDimitry Andric return static_cast<void*>(&__this.__s_.__buf); 3720b57cec5SDimitry Andric return nullptr; 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 375*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* __type_info() { 3761ac55f4cSDimitry Andric# if !defined(_LIBCPP_HAS_NO_RTTI) 3770b57cec5SDimitry Andric return const_cast<void*>(static_cast<void const*>(&typeid(_Tp))); 3780b57cec5SDimitry Andric# else 3790b57cec5SDimitry Andric return nullptr; 3800b57cec5SDimitry Andric# endif 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric}; 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andrictemplate <class _Tp> 385*cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS _LargeHandler { 386*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* 387*cb14a3feSDimitry Andric __handle(_Action __act, any const* __this, any* __other, type_info const* __info, void const* __fallback_info) { 388*cb14a3feSDimitry Andric switch (__act) { 3890b57cec5SDimitry Andric case _Action::_Destroy: 3900b57cec5SDimitry Andric __destroy(const_cast<any&>(*__this)); 3910b57cec5SDimitry Andric return nullptr; 3920b57cec5SDimitry Andric case _Action::_Copy: 3930b57cec5SDimitry Andric __copy(*__this, *__other); 3940b57cec5SDimitry Andric return nullptr; 3950b57cec5SDimitry Andric case _Action::_Move: 3960b57cec5SDimitry Andric __move(const_cast<any&>(*__this), *__other); 3970b57cec5SDimitry Andric return nullptr; 3980b57cec5SDimitry Andric case _Action::_Get: 3990b57cec5SDimitry Andric return __get(const_cast<any&>(*__this), __info, __fallback_info); 4000b57cec5SDimitry Andric case _Action::_TypeInfo: 4010b57cec5SDimitry Andric return __type_info(); 4020b57cec5SDimitry Andric } 40381ad6265SDimitry Andric __libcpp_unreachable(); 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric template <class... _Args> 407*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) { 4080b57cec5SDimitry Andric typedef allocator<_Tp> _Alloc; 409e8d8bef9SDimitry Andric typedef allocator_traits<_Alloc> _ATraits; 4100b57cec5SDimitry Andric typedef __allocator_destructor<_Alloc> _Dp; 4110b57cec5SDimitry Andric _Alloc __a; 412e8d8bef9SDimitry Andric unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1)); 413e8d8bef9SDimitry Andric _Tp* __ret = __hold.get(); 4145f757f3fSDimitry Andric _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...); 415bdd1243dSDimitry Andric __dest.__s_.__ptr = __hold.release(); 416bdd1243dSDimitry Andric __dest.__h_ = &_LargeHandler::__handle; 4170b57cec5SDimitry Andric return *__ret; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andricprivate: 421*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) { 422e8d8bef9SDimitry Andric typedef allocator<_Tp> _Alloc; 423e8d8bef9SDimitry Andric typedef allocator_traits<_Alloc> _ATraits; 424e8d8bef9SDimitry Andric _Alloc __a; 425bdd1243dSDimitry Andric _Tp* __p = static_cast<_Tp*>(__this.__s_.__ptr); 426e8d8bef9SDimitry Andric _ATraits::destroy(__a, __p); 427e8d8bef9SDimitry Andric _ATraits::deallocate(__a, __p, 1); 428bdd1243dSDimitry Andric __this.__h_ = nullptr; 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric 431*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) { 432bdd1243dSDimitry Andric _LargeHandler::__create(__dest, *static_cast<_Tp const*>(__this.__s_.__ptr)); 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 435*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) { 436bdd1243dSDimitry Andric __dest.__s_.__ptr = __this.__s_.__ptr; 437bdd1243dSDimitry Andric __dest.__h_ = &_LargeHandler::__handle; 438bdd1243dSDimitry Andric __this.__h_ = nullptr; 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric 441*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, void const* __fallback_info) { 4420b57cec5SDimitry Andric if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info)) 443bdd1243dSDimitry Andric return static_cast<void*>(__this.__s_.__ptr); 4440b57cec5SDimitry Andric return nullptr; 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric 447*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI static void* __type_info() { 4481ac55f4cSDimitry Andric# if !defined(_LIBCPP_HAS_NO_RTTI) 4490b57cec5SDimitry Andric return const_cast<void*>(static_cast<void const*>(&typeid(_Tp))); 4500b57cec5SDimitry Andric# else 4510b57cec5SDimitry Andric return nullptr; 4520b57cec5SDimitry Andric# endif 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric}; 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric} // namespace __any_imp 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andrictemplate <class _ValueType, class _Tp, class> 459*cb14a3feSDimitry Andricany::any(_ValueType&& __v) : __h_(nullptr) { 4605f757f3fSDimitry Andric __any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__v)); 4610b57cec5SDimitry Andric} 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andrictemplate <class _ValueType, class... _Args, class _Tp, class> 4640b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, _Args&&... __args) { 4655f757f3fSDimitry Andric __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...); 4660b57cec5SDimitry Andric} 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class... _Args, class _Tp, class> 4690b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) { 4705f757f3fSDimitry Andric __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...); 4710b57cec5SDimitry Andric} 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andrictemplate <class _ValueType, class, class> 474*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any& any::operator=(_ValueType&& __v) { 4755f757f3fSDimitry Andric any(std::forward<_ValueType>(__v)).swap(*this); 4760b57cec5SDimitry Andric return *this; 4770b57cec5SDimitry Andric} 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andrictemplate <class _ValueType, class... _Args, class _Tp, class> 480*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(_Args&&... __args) { 4810b57cec5SDimitry Andric reset(); 4825f757f3fSDimitry Andric return __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...); 4830b57cec5SDimitry Andric} 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class... _Args, class _Tp, class> 486*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) { 4870b57cec5SDimitry Andric reset(); 4885f757f3fSDimitry Andric return __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...); 4890b57cec5SDimitry Andric} 4900b57cec5SDimitry Andric 491*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void any::swap(any& __rhs) _NOEXCEPT { 4920b57cec5SDimitry Andric if (this == &__rhs) 4930b57cec5SDimitry Andric return; 494bdd1243dSDimitry Andric if (__h_ && __rhs.__h_) { 4950b57cec5SDimitry Andric any __tmp; 4960b57cec5SDimitry Andric __rhs.__call(_Action::_Move, &__tmp); 4970b57cec5SDimitry Andric this->__call(_Action::_Move, &__rhs); 4980b57cec5SDimitry Andric __tmp.__call(_Action::_Move, this); 499*cb14a3feSDimitry Andric } else if (__h_) { 5000b57cec5SDimitry Andric this->__call(_Action::_Move, &__rhs); 501*cb14a3feSDimitry Andric } else if (__rhs.__h_) { 5020b57cec5SDimitry Andric __rhs.__call(_Action::_Move, this); 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric} 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric// 6.4 Non-member functions 5070b57cec5SDimitry Andric 508*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) _NOEXCEPT { __lhs.swap(__rhs); } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andrictemplate <class _Tp, class... _Args> 511*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) { 5125f757f3fSDimitry Andric return any(in_place_type<_Tp>, std::forward<_Args>(__args)...); 5130b57cec5SDimitry Andric} 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andrictemplate <class _Tp, class _Up, class... _Args> 516*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) { 5175f757f3fSDimitry Andric return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...); 5180b57cec5SDimitry Andric} 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andrictemplate <class _ValueType> 521*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any const& __v) { 522bdd1243dSDimitry Andric using _RawValueType = __remove_cvref_t<_ValueType>; 5230b57cec5SDimitry Andric static_assert(is_constructible<_ValueType, _RawValueType const&>::value, 5240b57cec5SDimitry Andric "ValueType is required to be a const lvalue reference " 5250b57cec5SDimitry Andric "or a CopyConstructible type"); 5265f757f3fSDimitry Andric auto __tmp = std::any_cast<add_const_t<_RawValueType>>(&__v); 5270b57cec5SDimitry Andric if (__tmp == nullptr) 5280b57cec5SDimitry Andric __throw_bad_any_cast(); 5290b57cec5SDimitry Andric return static_cast<_ValueType>(*__tmp); 5300b57cec5SDimitry Andric} 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andrictemplate <class _ValueType> 533*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any& __v) { 534bdd1243dSDimitry Andric using _RawValueType = __remove_cvref_t<_ValueType>; 5350b57cec5SDimitry Andric static_assert(is_constructible<_ValueType, _RawValueType&>::value, 5360b57cec5SDimitry Andric "ValueType is required to be an lvalue reference " 5370b57cec5SDimitry Andric "or a CopyConstructible type"); 5385f757f3fSDimitry Andric auto __tmp = std::any_cast<_RawValueType>(&__v); 5390b57cec5SDimitry Andric if (__tmp == nullptr) 5400b57cec5SDimitry Andric __throw_bad_any_cast(); 5410b57cec5SDimitry Andric return static_cast<_ValueType>(*__tmp); 5420b57cec5SDimitry Andric} 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andrictemplate <class _ValueType> 545*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any&& __v) { 546bdd1243dSDimitry Andric using _RawValueType = __remove_cvref_t<_ValueType>; 5470b57cec5SDimitry Andric static_assert(is_constructible<_ValueType, _RawValueType>::value, 5480b57cec5SDimitry Andric "ValueType is required to be an rvalue reference " 5490b57cec5SDimitry Andric "or a CopyConstructible type"); 5505f757f3fSDimitry Andric auto __tmp = std::any_cast<_RawValueType>(&__v); 5510b57cec5SDimitry Andric if (__tmp == nullptr) 5520b57cec5SDimitry Andric __throw_bad_any_cast(); 5535f757f3fSDimitry Andric return static_cast<_ValueType>(std::move(*__tmp)); 5540b57cec5SDimitry Andric} 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andrictemplate <class _ValueType> 557*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT { 558*cb14a3feSDimitry Andric static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference."); 5595f757f3fSDimitry Andric return std::any_cast<_ValueType>(const_cast<any*>(__any)); 5600b57cec5SDimitry Andric} 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andrictemplate <class _RetType> 563*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/ false_type) noexcept { 5640b57cec5SDimitry Andric return static_cast<_RetType>(__p); 5650b57cec5SDimitry Andric} 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andrictemplate <class _RetType> 568*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction*/ true_type) noexcept { 5690b57cec5SDimitry Andric return nullptr; 5700b57cec5SDimitry Andric} 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andrictemplate <class _ValueType> 573*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT { 5740b57cec5SDimitry Andric using __any_imp::_Action; 575*cb14a3feSDimitry Andric static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference."); 576bdd1243dSDimitry Andric typedef add_pointer_t<_ValueType> _ReturnType; 577bdd1243dSDimitry Andric if (__any && __any->__h_) { 578*cb14a3feSDimitry Andric void* __p = __any->__call( 579*cb14a3feSDimitry Andric _Action::_Get, 580*cb14a3feSDimitry Andric nullptr, 5811ac55f4cSDimitry Andric# if !defined(_LIBCPP_HAS_NO_RTTI) 5820b57cec5SDimitry Andric &typeid(_ValueType), 5830b57cec5SDimitry Andric# else 5840b57cec5SDimitry Andric nullptr, 5850b57cec5SDimitry Andric# endif 5860b57cec5SDimitry Andric __any_imp::__get_fallback_typeid<_ValueType>()); 587*cb14a3feSDimitry Andric return std::__pointer_or_func_cast<_ReturnType>(__p, is_function<_ValueType>{}); 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric return nullptr; 5900b57cec5SDimitry Andric} 5910b57cec5SDimitry Andric 59206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 17 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5950b57cec5SDimitry Andric 59606c3fb27SDimitry Andric_LIBCPP_POP_MACROS 59706c3fb27SDimitry Andric 598bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 599bdd1243dSDimitry Andric# include <chrono> 600bdd1243dSDimitry Andric#endif 601bdd1243dSDimitry Andric 602bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 603bdd1243dSDimitry Andric# include <atomic> 604bdd1243dSDimitry Andric# include <concepts> 60506c3fb27SDimitry Andric# include <cstdlib> 606bdd1243dSDimitry Andric# include <iosfwd> 607bdd1243dSDimitry Andric# include <iterator> 608bdd1243dSDimitry Andric# include <memory> 60906c3fb27SDimitry Andric# include <stdexcept> 61006c3fb27SDimitry Andric# include <type_traits> 611bdd1243dSDimitry Andric# include <variant> 612bdd1243dSDimitry Andric#endif 613bdd1243dSDimitry Andric 6140b57cec5SDimitry Andric#endif // _LIBCPP_ANY 615