1*0b57cec5SDimitry Andric// -*- C++ -*- 2*0b57cec5SDimitry Andric//===------------------------------ any -----------------------------------===// 3*0b57cec5SDimitry Andric// 4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric// 8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric 10*0b57cec5SDimitry Andric#ifndef _LIBCPP_ANY 11*0b57cec5SDimitry Andric#define _LIBCPP_ANY 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric/* 14*0b57cec5SDimitry Andric any synopsis 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andricnamespace std { 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric class bad_any_cast : public bad_cast 19*0b57cec5SDimitry Andric { 20*0b57cec5SDimitry Andric public: 21*0b57cec5SDimitry Andric virtual const char* what() const noexcept; 22*0b57cec5SDimitry Andric }; 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric class any 25*0b57cec5SDimitry Andric { 26*0b57cec5SDimitry Andric public: 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric // 6.3.1 any construct/destruct 29*0b57cec5SDimitry Andric any() noexcept; 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric any(const any& other); 32*0b57cec5SDimitry Andric any(any&& other) noexcept; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric template <class ValueType> 35*0b57cec5SDimitry Andric any(ValueType&& value); 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric ~any(); 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric // 6.3.2 any assignments 40*0b57cec5SDimitry Andric any& operator=(const any& rhs); 41*0b57cec5SDimitry Andric any& operator=(any&& rhs) noexcept; 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric template <class ValueType> 44*0b57cec5SDimitry Andric any& operator=(ValueType&& rhs); 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric // 6.3.3 any modifiers 47*0b57cec5SDimitry Andric template <class ValueType, class... Args> 48*0b57cec5SDimitry Andric decay_t<ValueType>& emplace(Args&&... args); 49*0b57cec5SDimitry Andric template <class ValueType, class U, class... Args> 50*0b57cec5SDimitry Andric decay_t<ValueType>& emplace(initializer_list<U>, Args&&...); 51*0b57cec5SDimitry Andric void reset() noexcept; 52*0b57cec5SDimitry Andric void swap(any& rhs) noexcept; 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric // 6.3.4 any observers 55*0b57cec5SDimitry Andric bool has_value() const noexcept; 56*0b57cec5SDimitry Andric const type_info& type() const noexcept; 57*0b57cec5SDimitry Andric }; 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric // 6.4 Non-member functions 60*0b57cec5SDimitry Andric void swap(any& x, any& y) noexcept; 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric template <class T, class ...Args> 63*0b57cec5SDimitry Andric any make_any(Args&& ...args); 64*0b57cec5SDimitry Andric template <class T, class U, class ...Args> 65*0b57cec5SDimitry Andric any make_any(initializer_list<U>, Args&& ...args); 66*0b57cec5SDimitry Andric 67*0b57cec5SDimitry Andric template<class ValueType> 68*0b57cec5SDimitry Andric ValueType any_cast(const any& operand); 69*0b57cec5SDimitry Andric template<class ValueType> 70*0b57cec5SDimitry Andric ValueType any_cast(any& operand); 71*0b57cec5SDimitry Andric template<class ValueType> 72*0b57cec5SDimitry Andric ValueType any_cast(any&& operand); 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric template<class ValueType> 75*0b57cec5SDimitry Andric const ValueType* any_cast(const any* operand) noexcept; 76*0b57cec5SDimitry Andric template<class ValueType> 77*0b57cec5SDimitry Andric ValueType* any_cast(any* operand) noexcept; 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric} // namespace std 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric*/ 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric#include <experimental/__config> 84*0b57cec5SDimitry Andric#include <memory> 85*0b57cec5SDimitry Andric#include <new> 86*0b57cec5SDimitry Andric#include <typeinfo> 87*0b57cec5SDimitry Andric#include <type_traits> 88*0b57cec5SDimitry Andric#include <cstdlib> 89*0b57cec5SDimitry Andric#include <version> 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 92*0b57cec5SDimitry Andric#pragma GCC system_header 93*0b57cec5SDimitry Andric#endif 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andricnamespace std { 96*0b57cec5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast 97*0b57cec5SDimitry Andric{ 98*0b57cec5SDimitry Andricpublic: 99*0b57cec5SDimitry Andric virtual const char* what() const _NOEXCEPT; 100*0b57cec5SDimitry Andric}; 101*0b57cec5SDimitry Andric} // namespace std 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 108*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST 109*0b57cec5SDimitry Andricvoid __throw_bad_any_cast() 110*0b57cec5SDimitry Andric{ 111*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS 112*0b57cec5SDimitry Andric throw bad_any_cast(); 113*0b57cec5SDimitry Andric#else 114*0b57cec5SDimitry Andric _VSTD::abort(); 115*0b57cec5SDimitry Andric#endif 116*0b57cec5SDimitry Andric} 117*0b57cec5SDimitry Andric 118*0b57cec5SDimitry Andric// Forward declarations 119*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS any; 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andrictemplate <class _ValueType> 122*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 123*0b57cec5SDimitry Andricadd_pointer_t<add_const_t<_ValueType>> 124*0b57cec5SDimitry Andricany_cast(any const *) _NOEXCEPT; 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andrictemplate <class _ValueType> 127*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 128*0b57cec5SDimitry Andricadd_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT; 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andricnamespace __any_imp 131*0b57cec5SDimitry Andric{ 132*0b57cec5SDimitry Andric using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>; 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric template <class _Tp> 135*0b57cec5SDimitry Andric using _IsSmallObject = integral_constant<bool 136*0b57cec5SDimitry Andric , sizeof(_Tp) <= sizeof(_Buffer) 137*0b57cec5SDimitry Andric && alignment_of<_Buffer>::value 138*0b57cec5SDimitry Andric % alignment_of<_Tp>::value == 0 139*0b57cec5SDimitry Andric && is_nothrow_move_constructible<_Tp>::value 140*0b57cec5SDimitry Andric >; 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric enum class _Action { 143*0b57cec5SDimitry Andric _Destroy, 144*0b57cec5SDimitry Andric _Copy, 145*0b57cec5SDimitry Andric _Move, 146*0b57cec5SDimitry Andric _Get, 147*0b57cec5SDimitry Andric _TypeInfo 148*0b57cec5SDimitry Andric }; 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric template <class _Tp> struct _SmallHandler; 151*0b57cec5SDimitry Andric template <class _Tp> struct _LargeHandler; 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric template <class _Tp> 154*0b57cec5SDimitry Andric struct _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; }; 155*0b57cec5SDimitry Andric template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id; 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric template <class _Tp> 158*0b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 159*0b57cec5SDimitry Andric constexpr const void* __get_fallback_typeid() { 160*0b57cec5SDimitry Andric return &__unique_typeinfo<decay_t<_Tp>>::__id; 161*0b57cec5SDimitry Andric } 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric template <class _Tp> 164*0b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 165*0b57cec5SDimitry Andric bool __compare_typeid(type_info const* __id, const void* __fallback_id) 166*0b57cec5SDimitry Andric { 167*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI) 168*0b57cec5SDimitry Andric if (__id && *__id == typeid(_Tp)) 169*0b57cec5SDimitry Andric return true; 170*0b57cec5SDimitry Andric#endif 171*0b57cec5SDimitry Andric if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>()) 172*0b57cec5SDimitry Andric return true; 173*0b57cec5SDimitry Andric return false; 174*0b57cec5SDimitry Andric } 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric template <class _Tp> 177*0b57cec5SDimitry Andric using _Handler = conditional_t< 178*0b57cec5SDimitry Andric _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>; 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric} // namespace __any_imp 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS any 183*0b57cec5SDimitry Andric{ 184*0b57cec5SDimitry Andricpublic: 185*0b57cec5SDimitry Andric // construct/destruct 186*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 187*0b57cec5SDimitry Andric constexpr any() _NOEXCEPT : __h(nullptr) {} 188*0b57cec5SDimitry Andric 189*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 190*0b57cec5SDimitry Andric any(any const & __other) : __h(nullptr) 191*0b57cec5SDimitry Andric { 192*0b57cec5SDimitry Andric if (__other.__h) __other.__call(_Action::_Copy, this); 193*0b57cec5SDimitry Andric } 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 196*0b57cec5SDimitry Andric any(any && __other) _NOEXCEPT : __h(nullptr) 197*0b57cec5SDimitry Andric { 198*0b57cec5SDimitry Andric if (__other.__h) __other.__call(_Action::_Move, this); 199*0b57cec5SDimitry Andric } 200*0b57cec5SDimitry Andric 201*0b57cec5SDimitry Andric template < 202*0b57cec5SDimitry Andric class _ValueType 203*0b57cec5SDimitry Andric , class _Tp = decay_t<_ValueType> 204*0b57cec5SDimitry Andric , class = enable_if_t< 205*0b57cec5SDimitry Andric !is_same<_Tp, any>::value && 206*0b57cec5SDimitry Andric !__is_inplace_type<_ValueType>::value && 207*0b57cec5SDimitry Andric is_copy_constructible<_Tp>::value> 208*0b57cec5SDimitry Andric > 209*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 210*0b57cec5SDimitry Andric any(_ValueType && __value); 211*0b57cec5SDimitry Andric 212*0b57cec5SDimitry Andric template <class _ValueType, class ..._Args, 213*0b57cec5SDimitry Andric class _Tp = decay_t<_ValueType>, 214*0b57cec5SDimitry Andric class = enable_if_t< 215*0b57cec5SDimitry Andric is_constructible<_Tp, _Args...>::value && 216*0b57cec5SDimitry Andric is_copy_constructible<_Tp>::value 217*0b57cec5SDimitry Andric > 218*0b57cec5SDimitry Andric > 219*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 220*0b57cec5SDimitry Andric explicit any(in_place_type_t<_ValueType>, _Args&&... __args); 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric template <class _ValueType, class _Up, class ..._Args, 223*0b57cec5SDimitry Andric class _Tp = decay_t<_ValueType>, 224*0b57cec5SDimitry Andric class = enable_if_t< 225*0b57cec5SDimitry Andric is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && 226*0b57cec5SDimitry Andric is_copy_constructible<_Tp>::value> 227*0b57cec5SDimitry Andric > 228*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 229*0b57cec5SDimitry Andric explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args); 230*0b57cec5SDimitry Andric 231*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 232*0b57cec5SDimitry Andric ~any() { this->reset(); } 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric // assignments 235*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 236*0b57cec5SDimitry Andric any & operator=(any const & __rhs) { 237*0b57cec5SDimitry Andric any(__rhs).swap(*this); 238*0b57cec5SDimitry Andric return *this; 239*0b57cec5SDimitry Andric } 240*0b57cec5SDimitry Andric 241*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 242*0b57cec5SDimitry Andric any & operator=(any && __rhs) _NOEXCEPT { 243*0b57cec5SDimitry Andric any(_VSTD::move(__rhs)).swap(*this); 244*0b57cec5SDimitry Andric return *this; 245*0b57cec5SDimitry Andric } 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric template < 248*0b57cec5SDimitry Andric class _ValueType 249*0b57cec5SDimitry Andric , class _Tp = decay_t<_ValueType> 250*0b57cec5SDimitry Andric , class = enable_if_t< 251*0b57cec5SDimitry Andric !is_same<_Tp, any>::value 252*0b57cec5SDimitry Andric && is_copy_constructible<_Tp>::value> 253*0b57cec5SDimitry Andric > 254*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 255*0b57cec5SDimitry Andric any & operator=(_ValueType && __rhs); 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric template <class _ValueType, class ..._Args, 258*0b57cec5SDimitry Andric class _Tp = decay_t<_ValueType>, 259*0b57cec5SDimitry Andric class = enable_if_t< 260*0b57cec5SDimitry Andric is_constructible<_Tp, _Args...>::value && 261*0b57cec5SDimitry Andric is_copy_constructible<_Tp>::value> 262*0b57cec5SDimitry Andric > 263*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 264*0b57cec5SDimitry Andric _Tp& emplace(_Args&&... args); 265*0b57cec5SDimitry Andric 266*0b57cec5SDimitry Andric template <class _ValueType, class _Up, class ..._Args, 267*0b57cec5SDimitry Andric class _Tp = decay_t<_ValueType>, 268*0b57cec5SDimitry Andric class = enable_if_t< 269*0b57cec5SDimitry Andric is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && 270*0b57cec5SDimitry Andric is_copy_constructible<_Tp>::value> 271*0b57cec5SDimitry Andric > 272*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 273*0b57cec5SDimitry Andric _Tp& emplace(initializer_list<_Up>, _Args&&...); 274*0b57cec5SDimitry Andric 275*0b57cec5SDimitry Andric // 6.3.3 any modifiers 276*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 277*0b57cec5SDimitry Andric void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); } 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 280*0b57cec5SDimitry Andric void swap(any & __rhs) _NOEXCEPT; 281*0b57cec5SDimitry Andric 282*0b57cec5SDimitry Andric // 6.3.4 any observers 283*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 284*0b57cec5SDimitry Andric bool has_value() const _NOEXCEPT { return __h != nullptr; } 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI) 287*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 288*0b57cec5SDimitry Andric const type_info & type() const _NOEXCEPT { 289*0b57cec5SDimitry Andric if (__h) { 290*0b57cec5SDimitry Andric return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo)); 291*0b57cec5SDimitry Andric } else { 292*0b57cec5SDimitry Andric return typeid(void); 293*0b57cec5SDimitry Andric } 294*0b57cec5SDimitry Andric } 295*0b57cec5SDimitry Andric#endif 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andricprivate: 298*0b57cec5SDimitry Andric typedef __any_imp::_Action _Action; 299*0b57cec5SDimitry Andric using _HandleFuncPtr = void* (*)(_Action, any const *, any *, const type_info *, 300*0b57cec5SDimitry Andric const void* __fallback_info); 301*0b57cec5SDimitry Andric 302*0b57cec5SDimitry Andric union _Storage { 303*0b57cec5SDimitry Andric constexpr _Storage() : __ptr(nullptr) {} 304*0b57cec5SDimitry Andric void * __ptr; 305*0b57cec5SDimitry Andric __any_imp::_Buffer __buf; 306*0b57cec5SDimitry Andric }; 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 309*0b57cec5SDimitry Andric void * __call(_Action __a, any * __other = nullptr, 310*0b57cec5SDimitry Andric type_info const * __info = nullptr, 311*0b57cec5SDimitry Andric const void* __fallback_info = nullptr) const 312*0b57cec5SDimitry Andric { 313*0b57cec5SDimitry Andric return __h(__a, this, __other, __info, __fallback_info); 314*0b57cec5SDimitry Andric } 315*0b57cec5SDimitry Andric 316*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 317*0b57cec5SDimitry Andric void * __call(_Action __a, any * __other = nullptr, 318*0b57cec5SDimitry Andric type_info const * __info = nullptr, 319*0b57cec5SDimitry Andric const void* __fallback_info = nullptr) 320*0b57cec5SDimitry Andric { 321*0b57cec5SDimitry Andric return __h(__a, this, __other, __info, __fallback_info); 322*0b57cec5SDimitry Andric } 323*0b57cec5SDimitry Andric 324*0b57cec5SDimitry Andric template <class> 325*0b57cec5SDimitry Andric friend struct __any_imp::_SmallHandler; 326*0b57cec5SDimitry Andric template <class> 327*0b57cec5SDimitry Andric friend struct __any_imp::_LargeHandler; 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric template <class _ValueType> 330*0b57cec5SDimitry Andric friend add_pointer_t<add_const_t<_ValueType>> 331*0b57cec5SDimitry Andric any_cast(any const *) _NOEXCEPT; 332*0b57cec5SDimitry Andric 333*0b57cec5SDimitry Andric template <class _ValueType> 334*0b57cec5SDimitry Andric friend add_pointer_t<_ValueType> 335*0b57cec5SDimitry Andric any_cast(any *) _NOEXCEPT; 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric _HandleFuncPtr __h = nullptr; 338*0b57cec5SDimitry Andric _Storage __s; 339*0b57cec5SDimitry Andric}; 340*0b57cec5SDimitry Andric 341*0b57cec5SDimitry Andricnamespace __any_imp 342*0b57cec5SDimitry Andric{ 343*0b57cec5SDimitry Andric template <class _Tp> 344*0b57cec5SDimitry Andric struct _LIBCPP_TEMPLATE_VIS _SmallHandler 345*0b57cec5SDimitry Andric { 346*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 347*0b57cec5SDimitry Andric static void* __handle(_Action __act, any const * __this, any * __other, 348*0b57cec5SDimitry Andric type_info const * __info, const void* __fallback_info) 349*0b57cec5SDimitry Andric { 350*0b57cec5SDimitry Andric switch (__act) 351*0b57cec5SDimitry Andric { 352*0b57cec5SDimitry Andric case _Action::_Destroy: 353*0b57cec5SDimitry Andric __destroy(const_cast<any &>(*__this)); 354*0b57cec5SDimitry Andric return nullptr; 355*0b57cec5SDimitry Andric case _Action::_Copy: 356*0b57cec5SDimitry Andric __copy(*__this, *__other); 357*0b57cec5SDimitry Andric return nullptr; 358*0b57cec5SDimitry Andric case _Action::_Move: 359*0b57cec5SDimitry Andric __move(const_cast<any &>(*__this), *__other); 360*0b57cec5SDimitry Andric return nullptr; 361*0b57cec5SDimitry Andric case _Action::_Get: 362*0b57cec5SDimitry Andric return __get(const_cast<any &>(*__this), __info, __fallback_info); 363*0b57cec5SDimitry Andric case _Action::_TypeInfo: 364*0b57cec5SDimitry Andric return __type_info(); 365*0b57cec5SDimitry Andric } 366*0b57cec5SDimitry Andric } 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric template <class ..._Args> 369*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 370*0b57cec5SDimitry Andric static _Tp& __create(any & __dest, _Args&&... __args) { 371*0b57cec5SDimitry Andric _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...); 372*0b57cec5SDimitry Andric __dest.__h = &_SmallHandler::__handle; 373*0b57cec5SDimitry Andric return *__ret; 374*0b57cec5SDimitry Andric } 375*0b57cec5SDimitry Andric 376*0b57cec5SDimitry Andric private: 377*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 378*0b57cec5SDimitry Andric static void __destroy(any & __this) { 379*0b57cec5SDimitry Andric _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf)); 380*0b57cec5SDimitry Andric __value.~_Tp(); 381*0b57cec5SDimitry Andric __this.__h = nullptr; 382*0b57cec5SDimitry Andric } 383*0b57cec5SDimitry Andric 384*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 385*0b57cec5SDimitry Andric static void __copy(any const & __this, any & __dest) { 386*0b57cec5SDimitry Andric _SmallHandler::__create(__dest, *static_cast<_Tp const *>( 387*0b57cec5SDimitry Andric static_cast<void const *>(&__this.__s.__buf))); 388*0b57cec5SDimitry Andric } 389*0b57cec5SDimitry Andric 390*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 391*0b57cec5SDimitry Andric static void __move(any & __this, any & __dest) { 392*0b57cec5SDimitry Andric _SmallHandler::__create(__dest, _VSTD::move( 393*0b57cec5SDimitry Andric *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf)))); 394*0b57cec5SDimitry Andric __destroy(__this); 395*0b57cec5SDimitry Andric } 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 398*0b57cec5SDimitry Andric static void* __get(any & __this, 399*0b57cec5SDimitry Andric type_info const * __info, 400*0b57cec5SDimitry Andric const void* __fallback_id) 401*0b57cec5SDimitry Andric { 402*0b57cec5SDimitry Andric if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id)) 403*0b57cec5SDimitry Andric return static_cast<void*>(&__this.__s.__buf); 404*0b57cec5SDimitry Andric return nullptr; 405*0b57cec5SDimitry Andric } 406*0b57cec5SDimitry Andric 407*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 408*0b57cec5SDimitry Andric static void* __type_info() 409*0b57cec5SDimitry Andric { 410*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI) 411*0b57cec5SDimitry Andric return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); 412*0b57cec5SDimitry Andric#else 413*0b57cec5SDimitry Andric return nullptr; 414*0b57cec5SDimitry Andric#endif 415*0b57cec5SDimitry Andric } 416*0b57cec5SDimitry Andric }; 417*0b57cec5SDimitry Andric 418*0b57cec5SDimitry Andric template <class _Tp> 419*0b57cec5SDimitry Andric struct _LIBCPP_TEMPLATE_VIS _LargeHandler 420*0b57cec5SDimitry Andric { 421*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 422*0b57cec5SDimitry Andric static void* __handle(_Action __act, any const * __this, 423*0b57cec5SDimitry Andric any * __other, type_info const * __info, 424*0b57cec5SDimitry Andric void const* __fallback_info) 425*0b57cec5SDimitry Andric { 426*0b57cec5SDimitry Andric switch (__act) 427*0b57cec5SDimitry Andric { 428*0b57cec5SDimitry Andric case _Action::_Destroy: 429*0b57cec5SDimitry Andric __destroy(const_cast<any &>(*__this)); 430*0b57cec5SDimitry Andric return nullptr; 431*0b57cec5SDimitry Andric case _Action::_Copy: 432*0b57cec5SDimitry Andric __copy(*__this, *__other); 433*0b57cec5SDimitry Andric return nullptr; 434*0b57cec5SDimitry Andric case _Action::_Move: 435*0b57cec5SDimitry Andric __move(const_cast<any &>(*__this), *__other); 436*0b57cec5SDimitry Andric return nullptr; 437*0b57cec5SDimitry Andric case _Action::_Get: 438*0b57cec5SDimitry Andric return __get(const_cast<any &>(*__this), __info, __fallback_info); 439*0b57cec5SDimitry Andric case _Action::_TypeInfo: 440*0b57cec5SDimitry Andric return __type_info(); 441*0b57cec5SDimitry Andric } 442*0b57cec5SDimitry Andric } 443*0b57cec5SDimitry Andric 444*0b57cec5SDimitry Andric template <class ..._Args> 445*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 446*0b57cec5SDimitry Andric static _Tp& __create(any & __dest, _Args&&... __args) { 447*0b57cec5SDimitry Andric typedef allocator<_Tp> _Alloc; 448*0b57cec5SDimitry Andric typedef __allocator_destructor<_Alloc> _Dp; 449*0b57cec5SDimitry Andric _Alloc __a; 450*0b57cec5SDimitry Andric unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); 451*0b57cec5SDimitry Andric _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...); 452*0b57cec5SDimitry Andric __dest.__s.__ptr = __hold.release(); 453*0b57cec5SDimitry Andric __dest.__h = &_LargeHandler::__handle; 454*0b57cec5SDimitry Andric return *__ret; 455*0b57cec5SDimitry Andric } 456*0b57cec5SDimitry Andric 457*0b57cec5SDimitry Andric private: 458*0b57cec5SDimitry Andric 459*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 460*0b57cec5SDimitry Andric static void __destroy(any & __this){ 461*0b57cec5SDimitry Andric delete static_cast<_Tp*>(__this.__s.__ptr); 462*0b57cec5SDimitry Andric __this.__h = nullptr; 463*0b57cec5SDimitry Andric } 464*0b57cec5SDimitry Andric 465*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 466*0b57cec5SDimitry Andric static void __copy(any const & __this, any & __dest) { 467*0b57cec5SDimitry Andric _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); 468*0b57cec5SDimitry Andric } 469*0b57cec5SDimitry Andric 470*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 471*0b57cec5SDimitry Andric static void __move(any & __this, any & __dest) { 472*0b57cec5SDimitry Andric __dest.__s.__ptr = __this.__s.__ptr; 473*0b57cec5SDimitry Andric __dest.__h = &_LargeHandler::__handle; 474*0b57cec5SDimitry Andric __this.__h = nullptr; 475*0b57cec5SDimitry Andric } 476*0b57cec5SDimitry Andric 477*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 478*0b57cec5SDimitry Andric static void* __get(any & __this, type_info const * __info, 479*0b57cec5SDimitry Andric void const* __fallback_info) 480*0b57cec5SDimitry Andric { 481*0b57cec5SDimitry Andric if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info)) 482*0b57cec5SDimitry Andric return static_cast<void*>(__this.__s.__ptr); 483*0b57cec5SDimitry Andric return nullptr; 484*0b57cec5SDimitry Andric 485*0b57cec5SDimitry Andric } 486*0b57cec5SDimitry Andric 487*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 488*0b57cec5SDimitry Andric static void* __type_info() 489*0b57cec5SDimitry Andric { 490*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI) 491*0b57cec5SDimitry Andric return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); 492*0b57cec5SDimitry Andric#else 493*0b57cec5SDimitry Andric return nullptr; 494*0b57cec5SDimitry Andric#endif 495*0b57cec5SDimitry Andric } 496*0b57cec5SDimitry Andric }; 497*0b57cec5SDimitry Andric 498*0b57cec5SDimitry Andric} // namespace __any_imp 499*0b57cec5SDimitry Andric 500*0b57cec5SDimitry Andric 501*0b57cec5SDimitry Andrictemplate <class _ValueType, class _Tp, class> 502*0b57cec5SDimitry Andricany::any(_ValueType && __v) : __h(nullptr) 503*0b57cec5SDimitry Andric{ 504*0b57cec5SDimitry Andric __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v)); 505*0b57cec5SDimitry Andric} 506*0b57cec5SDimitry Andric 507*0b57cec5SDimitry Andrictemplate <class _ValueType, class ..._Args, class _Tp, class> 508*0b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, _Args&&... __args) { 509*0b57cec5SDimitry Andric __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); 510*0b57cec5SDimitry Andric} 511*0b57cec5SDimitry Andric 512*0b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class ..._Args, class _Tp, class> 513*0b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) { 514*0b57cec5SDimitry Andric __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); 515*0b57cec5SDimitry Andric} 516*0b57cec5SDimitry Andric 517*0b57cec5SDimitry Andrictemplate <class _ValueType, class, class> 518*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 519*0b57cec5SDimitry Andricany & any::operator=(_ValueType && __v) 520*0b57cec5SDimitry Andric{ 521*0b57cec5SDimitry Andric any(_VSTD::forward<_ValueType>(__v)).swap(*this); 522*0b57cec5SDimitry Andric return *this; 523*0b57cec5SDimitry Andric} 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andrictemplate <class _ValueType, class ..._Args, class _Tp, class> 526*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 527*0b57cec5SDimitry Andric_Tp& any::emplace(_Args&&... __args) { 528*0b57cec5SDimitry Andric reset(); 529*0b57cec5SDimitry Andric return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); 530*0b57cec5SDimitry Andric} 531*0b57cec5SDimitry Andric 532*0b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class ..._Args, class _Tp, class> 533*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 534*0b57cec5SDimitry Andric_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) { 535*0b57cec5SDimitry Andric reset(); 536*0b57cec5SDimitry Andric return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); 537*0b57cec5SDimitry Andric} 538*0b57cec5SDimitry Andric 539*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 540*0b57cec5SDimitry Andricvoid any::swap(any & __rhs) _NOEXCEPT 541*0b57cec5SDimitry Andric{ 542*0b57cec5SDimitry Andric if (this == &__rhs) 543*0b57cec5SDimitry Andric return; 544*0b57cec5SDimitry Andric if (__h && __rhs.__h) { 545*0b57cec5SDimitry Andric any __tmp; 546*0b57cec5SDimitry Andric __rhs.__call(_Action::_Move, &__tmp); 547*0b57cec5SDimitry Andric this->__call(_Action::_Move, &__rhs); 548*0b57cec5SDimitry Andric __tmp.__call(_Action::_Move, this); 549*0b57cec5SDimitry Andric } 550*0b57cec5SDimitry Andric else if (__h) { 551*0b57cec5SDimitry Andric this->__call(_Action::_Move, &__rhs); 552*0b57cec5SDimitry Andric } 553*0b57cec5SDimitry Andric else if (__rhs.__h) { 554*0b57cec5SDimitry Andric __rhs.__call(_Action::_Move, this); 555*0b57cec5SDimitry Andric } 556*0b57cec5SDimitry Andric} 557*0b57cec5SDimitry Andric 558*0b57cec5SDimitry Andric// 6.4 Non-member functions 559*0b57cec5SDimitry Andric 560*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 561*0b57cec5SDimitry Andricvoid swap(any & __lhs, any & __rhs) _NOEXCEPT 562*0b57cec5SDimitry Andric{ 563*0b57cec5SDimitry Andric __lhs.swap(__rhs); 564*0b57cec5SDimitry Andric} 565*0b57cec5SDimitry Andric 566*0b57cec5SDimitry Andrictemplate <class _Tp, class ..._Args> 567*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 568*0b57cec5SDimitry Andricany make_any(_Args&&... __args) { 569*0b57cec5SDimitry Andric return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...); 570*0b57cec5SDimitry Andric} 571*0b57cec5SDimitry Andric 572*0b57cec5SDimitry Andrictemplate <class _Tp, class _Up, class ..._Args> 573*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 574*0b57cec5SDimitry Andricany make_any(initializer_list<_Up> __il, _Args&&... __args) { 575*0b57cec5SDimitry Andric return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...); 576*0b57cec5SDimitry Andric} 577*0b57cec5SDimitry Andric 578*0b57cec5SDimitry Andrictemplate <class _ValueType> 579*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 580*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST 581*0b57cec5SDimitry Andric_ValueType any_cast(any const & __v) 582*0b57cec5SDimitry Andric{ 583*0b57cec5SDimitry Andric using _RawValueType = __uncvref_t<_ValueType>; 584*0b57cec5SDimitry Andric static_assert(is_constructible<_ValueType, _RawValueType const &>::value, 585*0b57cec5SDimitry Andric "ValueType is required to be a const lvalue reference " 586*0b57cec5SDimitry Andric "or a CopyConstructible type"); 587*0b57cec5SDimitry Andric auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v); 588*0b57cec5SDimitry Andric if (__tmp == nullptr) 589*0b57cec5SDimitry Andric __throw_bad_any_cast(); 590*0b57cec5SDimitry Andric return static_cast<_ValueType>(*__tmp); 591*0b57cec5SDimitry Andric} 592*0b57cec5SDimitry Andric 593*0b57cec5SDimitry Andrictemplate <class _ValueType> 594*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 595*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST 596*0b57cec5SDimitry Andric_ValueType any_cast(any & __v) 597*0b57cec5SDimitry Andric{ 598*0b57cec5SDimitry Andric using _RawValueType = __uncvref_t<_ValueType>; 599*0b57cec5SDimitry Andric static_assert(is_constructible<_ValueType, _RawValueType &>::value, 600*0b57cec5SDimitry Andric "ValueType is required to be an lvalue reference " 601*0b57cec5SDimitry Andric "or a CopyConstructible type"); 602*0b57cec5SDimitry Andric auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); 603*0b57cec5SDimitry Andric if (__tmp == nullptr) 604*0b57cec5SDimitry Andric __throw_bad_any_cast(); 605*0b57cec5SDimitry Andric return static_cast<_ValueType>(*__tmp); 606*0b57cec5SDimitry Andric} 607*0b57cec5SDimitry Andric 608*0b57cec5SDimitry Andrictemplate <class _ValueType> 609*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 610*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST 611*0b57cec5SDimitry Andric_ValueType any_cast(any && __v) 612*0b57cec5SDimitry Andric{ 613*0b57cec5SDimitry Andric using _RawValueType = __uncvref_t<_ValueType>; 614*0b57cec5SDimitry Andric static_assert(is_constructible<_ValueType, _RawValueType>::value, 615*0b57cec5SDimitry Andric "ValueType is required to be an rvalue reference " 616*0b57cec5SDimitry Andric "or a CopyConstructible type"); 617*0b57cec5SDimitry Andric auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); 618*0b57cec5SDimitry Andric if (__tmp == nullptr) 619*0b57cec5SDimitry Andric __throw_bad_any_cast(); 620*0b57cec5SDimitry Andric return static_cast<_ValueType>(_VSTD::move(*__tmp)); 621*0b57cec5SDimitry Andric} 622*0b57cec5SDimitry Andric 623*0b57cec5SDimitry Andrictemplate <class _ValueType> 624*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 625*0b57cec5SDimitry Andricadd_pointer_t<add_const_t<_ValueType>> 626*0b57cec5SDimitry Andricany_cast(any const * __any) _NOEXCEPT 627*0b57cec5SDimitry Andric{ 628*0b57cec5SDimitry Andric static_assert(!is_reference<_ValueType>::value, 629*0b57cec5SDimitry Andric "_ValueType may not be a reference."); 630*0b57cec5SDimitry Andric return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any)); 631*0b57cec5SDimitry Andric} 632*0b57cec5SDimitry Andric 633*0b57cec5SDimitry Andrictemplate <class _RetType> 634*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 635*0b57cec5SDimitry Andric_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept { 636*0b57cec5SDimitry Andric return static_cast<_RetType>(__p); 637*0b57cec5SDimitry Andric} 638*0b57cec5SDimitry Andric 639*0b57cec5SDimitry Andrictemplate <class _RetType> 640*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 641*0b57cec5SDimitry Andric_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept { 642*0b57cec5SDimitry Andric return nullptr; 643*0b57cec5SDimitry Andric} 644*0b57cec5SDimitry Andric 645*0b57cec5SDimitry Andrictemplate <class _ValueType> 646*0b57cec5SDimitry Andricadd_pointer_t<_ValueType> 647*0b57cec5SDimitry Andricany_cast(any * __any) _NOEXCEPT 648*0b57cec5SDimitry Andric{ 649*0b57cec5SDimitry Andric using __any_imp::_Action; 650*0b57cec5SDimitry Andric static_assert(!is_reference<_ValueType>::value, 651*0b57cec5SDimitry Andric "_ValueType may not be a reference."); 652*0b57cec5SDimitry Andric typedef typename add_pointer<_ValueType>::type _ReturnType; 653*0b57cec5SDimitry Andric if (__any && __any->__h) { 654*0b57cec5SDimitry Andric void *__p = __any->__call(_Action::_Get, nullptr, 655*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI) 656*0b57cec5SDimitry Andric &typeid(_ValueType), 657*0b57cec5SDimitry Andric#else 658*0b57cec5SDimitry Andric nullptr, 659*0b57cec5SDimitry Andric#endif 660*0b57cec5SDimitry Andric __any_imp::__get_fallback_typeid<_ValueType>()); 661*0b57cec5SDimitry Andric return _VSTD::__pointer_or_func_cast<_ReturnType>( 662*0b57cec5SDimitry Andric __p, is_function<_ValueType>{}); 663*0b57cec5SDimitry Andric } 664*0b57cec5SDimitry Andric return nullptr; 665*0b57cec5SDimitry Andric} 666*0b57cec5SDimitry Andric 667*0b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14 668*0b57cec5SDimitry Andric 669*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 670*0b57cec5SDimitry Andric 671*0b57cec5SDimitry Andric#endif // _LIBCPP_ANY 672