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