1324506b9SEric Fiselier// -*- C++ -*- 2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===// 3324506b9SEric Fiselier// 42946cd70SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 52946cd70SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 62946cd70SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7324506b9SEric Fiselier// 8324506b9SEric Fiselier//===----------------------------------------------------------------------===// 9324506b9SEric Fiselier 10324506b9SEric Fiselier#ifndef _LIBCPP_ANY 11324506b9SEric Fiselier#define _LIBCPP_ANY 12324506b9SEric Fiselier 13324506b9SEric Fiselier/* 14324506b9SEric Fiselier any synopsis 15324506b9SEric Fiselier 16324506b9SEric Fiseliernamespace std { 17324506b9SEric Fiselier 18324506b9SEric Fiselier class bad_any_cast : public bad_cast 19324506b9SEric Fiselier { 20324506b9SEric Fiselier public: 21324506b9SEric Fiselier virtual const char* what() const noexcept; 22324506b9SEric Fiselier }; 23324506b9SEric Fiselier 24324506b9SEric Fiselier class any 25324506b9SEric Fiselier { 26324506b9SEric Fiselier public: 27324506b9SEric Fiselier 28324506b9SEric Fiselier // 6.3.1 any construct/destruct 29324506b9SEric Fiselier any() noexcept; 30324506b9SEric Fiselier 31324506b9SEric Fiselier any(const any& other); 32324506b9SEric Fiselier any(any&& other) noexcept; 33324506b9SEric Fiselier 34324506b9SEric Fiselier template <class ValueType> 35324506b9SEric Fiselier any(ValueType&& value); 36324506b9SEric Fiselier 37324506b9SEric Fiselier ~any(); 38324506b9SEric Fiselier 39324506b9SEric Fiselier // 6.3.2 any assignments 40324506b9SEric Fiselier any& operator=(const any& rhs); 41324506b9SEric Fiselier any& operator=(any&& rhs) noexcept; 42324506b9SEric Fiselier 43324506b9SEric Fiselier template <class ValueType> 44324506b9SEric Fiselier any& operator=(ValueType&& rhs); 45324506b9SEric Fiselier 46324506b9SEric Fiselier // 6.3.3 any modifiers 475c80f4f6SMarshall Clow template <class ValueType, class... Args> 485c80f4f6SMarshall Clow decay_t<ValueType>& emplace(Args&&... args); 495c80f4f6SMarshall Clow template <class ValueType, class U, class... Args> 505c80f4f6SMarshall Clow decay_t<ValueType>& emplace(initializer_list<U>, Args&&...); 51324506b9SEric Fiselier void reset() noexcept; 52324506b9SEric Fiselier void swap(any& rhs) noexcept; 53324506b9SEric Fiselier 54324506b9SEric Fiselier // 6.3.4 any observers 55324506b9SEric Fiselier bool has_value() const noexcept; 56324506b9SEric Fiselier const type_info& type() const noexcept; 57324506b9SEric Fiselier }; 58324506b9SEric Fiselier 59324506b9SEric Fiselier // 6.4 Non-member functions 60324506b9SEric Fiselier void swap(any& x, any& y) noexcept; 61324506b9SEric Fiselier 62324506b9SEric Fiselier template <class T, class ...Args> 63324506b9SEric Fiselier any make_any(Args&& ...args); 64324506b9SEric Fiselier template <class T, class U, class ...Args> 65324506b9SEric Fiselier any make_any(initializer_list<U>, Args&& ...args); 66324506b9SEric Fiselier 67324506b9SEric Fiselier template<class ValueType> 68324506b9SEric Fiselier ValueType any_cast(const any& operand); 69324506b9SEric Fiselier template<class ValueType> 70324506b9SEric Fiselier ValueType any_cast(any& operand); 71324506b9SEric Fiselier template<class ValueType> 72324506b9SEric Fiselier ValueType any_cast(any&& operand); 73324506b9SEric Fiselier 74324506b9SEric Fiselier template<class ValueType> 75324506b9SEric Fiselier const ValueType* any_cast(const any* operand) noexcept; 76324506b9SEric Fiselier template<class ValueType> 77324506b9SEric Fiselier ValueType* any_cast(any* operand) noexcept; 78324506b9SEric Fiselier 79324506b9SEric Fiselier} // namespace std 80324506b9SEric Fiselier 81324506b9SEric Fiselier*/ 82324506b9SEric Fiselier 83385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler 842eadbc86SLouis Dionne#include <__availability> 85bfbd73f8SArthur O'Dwyer#include <__config> 866adbc83eSChristopher Di Bella#include <__utility/forward.h> 8752915d78SNikolas Klauser#include <__utility/in_place.h> 8852915d78SNikolas Klauser#include <__utility/move.h> 89e39095a3SLouis Dionne#include <__utility/unreachable.h> 90324506b9SEric Fiselier#include <cstdlib> 913cd4531bSNikolas Klauser#include <initializer_list> 92bfbd73f8SArthur O'Dwyer#include <memory> 93bfbd73f8SArthur O'Dwyer#include <type_traits> 94bfbd73f8SArthur O'Dwyer#include <typeinfo> 95f56972e2SMarshall Clow#include <version> 96324506b9SEric Fiselier 97de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES 98de4a57cbSLouis Dionne# include <chrono> 99de4a57cbSLouis Dionne#endif 100de4a57cbSLouis Dionne 101324506b9SEric Fiselier#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 102324506b9SEric Fiselier# pragma GCC system_header 103324506b9SEric Fiselier#endif 104324506b9SEric Fiselier 105324506b9SEric Fiseliernamespace std { 1068a063df1SLouis Dionneclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast 107324506b9SEric Fiselier{ 108324506b9SEric Fiselierpublic: 109324506b9SEric Fiselier virtual const char* what() const _NOEXCEPT; 110324506b9SEric Fiselier}; 111324506b9SEric Fiselier} // namespace std 112324506b9SEric Fiselier 113324506b9SEric Fiselier_LIBCPP_BEGIN_NAMESPACE_STD 114324506b9SEric Fiselier 115324506b9SEric Fiselier#if _LIBCPP_STD_VER > 14 116324506b9SEric Fiselier 117dc7200b4SLouis Dionne_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 1188a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST 1190fc8cec7SMarshall Clowvoid __throw_bad_any_cast() 1200fc8cec7SMarshall Clow{ 1210fc8cec7SMarshall Clow#ifndef _LIBCPP_NO_EXCEPTIONS 1220fc8cec7SMarshall Clow throw bad_any_cast(); 1230fc8cec7SMarshall Clow#else 1240fc8cec7SMarshall Clow _VSTD::abort(); 1250fc8cec7SMarshall Clow#endif 1260fc8cec7SMarshall Clow} 1270fc8cec7SMarshall Clow 128324506b9SEric Fiselier// Forward declarations 129e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS any; 130324506b9SEric Fiselier 131324506b9SEric Fiseliertemplate <class _ValueType> 132324506b9SEric Fiselier_LIBCPP_INLINE_VISIBILITY 133324506b9SEric Fiselieradd_pointer_t<add_const_t<_ValueType>> 134324506b9SEric Fiselierany_cast(any const *) _NOEXCEPT; 135324506b9SEric Fiselier 136324506b9SEric Fiseliertemplate <class _ValueType> 137324506b9SEric Fiselier_LIBCPP_INLINE_VISIBILITY 138324506b9SEric Fiselieradd_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT; 139324506b9SEric Fiselier 140324506b9SEric Fiseliernamespace __any_imp 141324506b9SEric Fiselier{ 142324506b9SEric Fiselier using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>; 143324506b9SEric Fiselier 144324506b9SEric Fiselier template <class _Tp> 145324506b9SEric Fiselier using _IsSmallObject = integral_constant<bool 146324506b9SEric Fiselier , sizeof(_Tp) <= sizeof(_Buffer) 147324506b9SEric Fiselier && alignment_of<_Buffer>::value 148324506b9SEric Fiselier % alignment_of<_Tp>::value == 0 149324506b9SEric Fiselier && is_nothrow_move_constructible<_Tp>::value 150324506b9SEric Fiselier >; 151324506b9SEric Fiselier 152324506b9SEric Fiselier enum class _Action { 153324506b9SEric Fiselier _Destroy, 154324506b9SEric Fiselier _Copy, 155324506b9SEric Fiselier _Move, 156324506b9SEric Fiselier _Get, 157324506b9SEric Fiselier _TypeInfo 158324506b9SEric Fiselier }; 159324506b9SEric Fiselier 160324506b9SEric Fiselier template <class _Tp> struct _SmallHandler; 161324506b9SEric Fiselier template <class _Tp> struct _LargeHandler; 162324506b9SEric Fiselier 163324506b9SEric Fiselier template <class _Tp> 164e2f2d1edSEric Fiselier struct _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; }; 165324506b9SEric Fiselier template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id; 166324506b9SEric Fiselier 167324506b9SEric Fiselier template <class _Tp> 168324506b9SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 169324506b9SEric Fiselier constexpr const void* __get_fallback_typeid() { 170bb09ef95SLouis Dionne return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id; 171324506b9SEric Fiselier } 172324506b9SEric Fiselier 173324506b9SEric Fiselier template <class _Tp> 174324506b9SEric Fiselier inline _LIBCPP_INLINE_VISIBILITY 175324506b9SEric Fiselier bool __compare_typeid(type_info const* __id, const void* __fallback_id) 176324506b9SEric Fiselier { 177324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI) 178324506b9SEric Fiselier if (__id && *__id == typeid(_Tp)) 179324506b9SEric Fiselier return true; 180324506b9SEric Fiselier#endif 181324506b9SEric Fiselier if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>()) 182324506b9SEric Fiselier return true; 183324506b9SEric Fiselier return false; 184324506b9SEric Fiselier } 185324506b9SEric Fiselier 186324506b9SEric Fiselier template <class _Tp> 187324506b9SEric Fiselier using _Handler = conditional_t< 188324506b9SEric Fiselier _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>; 189324506b9SEric Fiselier 190324506b9SEric Fiselier} // namespace __any_imp 191324506b9SEric Fiselier 192e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS any 193324506b9SEric Fiselier{ 194324506b9SEric Fiselierpublic: 195324506b9SEric Fiselier // construct/destruct 196324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 197324506b9SEric Fiselier constexpr any() _NOEXCEPT : __h(nullptr) {} 198324506b9SEric Fiselier 199324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 200324506b9SEric Fiselier any(any const & __other) : __h(nullptr) 201324506b9SEric Fiselier { 202324506b9SEric Fiselier if (__other.__h) __other.__call(_Action::_Copy, this); 203324506b9SEric Fiselier } 204324506b9SEric Fiselier 205324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 206324506b9SEric Fiselier any(any && __other) _NOEXCEPT : __h(nullptr) 207324506b9SEric Fiselier { 208324506b9SEric Fiselier if (__other.__h) __other.__call(_Action::_Move, this); 209324506b9SEric Fiselier } 210324506b9SEric Fiselier 211324506b9SEric Fiselier template < 212324506b9SEric Fiselier class _ValueType 213b18fd965SEric Fiselier , class _Tp = decay_t<_ValueType> 214324506b9SEric Fiselier , class = enable_if_t< 215b18fd965SEric Fiselier !is_same<_Tp, any>::value && 216034555f1SEric Fiselier !__is_inplace_type<_ValueType>::value && 217b18fd965SEric Fiselier is_copy_constructible<_Tp>::value> 218324506b9SEric Fiselier > 219324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 220324506b9SEric Fiselier any(_ValueType && __value); 221324506b9SEric Fiselier 222b18fd965SEric Fiselier template <class _ValueType, class ..._Args, 223b18fd965SEric Fiselier class _Tp = decay_t<_ValueType>, 224324506b9SEric Fiselier class = enable_if_t< 225324506b9SEric Fiselier is_constructible<_Tp, _Args...>::value && 226324506b9SEric Fiselier is_copy_constructible<_Tp>::value 227324506b9SEric Fiselier > 228324506b9SEric Fiselier > 229324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 230b18fd965SEric Fiselier explicit any(in_place_type_t<_ValueType>, _Args&&... __args); 231324506b9SEric Fiselier 232b18fd965SEric Fiselier template <class _ValueType, class _Up, class ..._Args, 233b18fd965SEric Fiselier class _Tp = decay_t<_ValueType>, 234324506b9SEric Fiselier class = enable_if_t< 235324506b9SEric Fiselier is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && 236324506b9SEric Fiselier is_copy_constructible<_Tp>::value> 237324506b9SEric Fiselier > 238324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 239b18fd965SEric Fiselier explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args); 240324506b9SEric Fiselier 241324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 242324506b9SEric Fiselier ~any() { this->reset(); } 243324506b9SEric Fiselier 244324506b9SEric Fiselier // assignments 245324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 246324506b9SEric Fiselier any & operator=(any const & __rhs) { 247324506b9SEric Fiselier any(__rhs).swap(*this); 248324506b9SEric Fiselier return *this; 249324506b9SEric Fiselier } 250324506b9SEric Fiselier 251324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 252324506b9SEric Fiselier any & operator=(any && __rhs) _NOEXCEPT { 253324506b9SEric Fiselier any(_VSTD::move(__rhs)).swap(*this); 254324506b9SEric Fiselier return *this; 255324506b9SEric Fiselier } 256324506b9SEric Fiselier 257324506b9SEric Fiselier template < 258324506b9SEric Fiselier class _ValueType 259b18fd965SEric Fiselier , class _Tp = decay_t<_ValueType> 260324506b9SEric Fiselier , class = enable_if_t< 261b18fd965SEric Fiselier !is_same<_Tp, any>::value 26250253ed1SEric Fiselier && is_copy_constructible<_Tp>::value> 263324506b9SEric Fiselier > 264324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 265324506b9SEric Fiselier any & operator=(_ValueType && __rhs); 266324506b9SEric Fiselier 267b18fd965SEric Fiselier template <class _ValueType, class ..._Args, 268b18fd965SEric Fiselier class _Tp = decay_t<_ValueType>, 269324506b9SEric Fiselier class = enable_if_t< 270324506b9SEric Fiselier is_constructible<_Tp, _Args...>::value && 271324506b9SEric Fiselier is_copy_constructible<_Tp>::value> 272324506b9SEric Fiselier > 273324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 274*b48c5010SNikolas Klauser _Tp& emplace(_Args&&...); 275324506b9SEric Fiselier 276b18fd965SEric Fiselier template <class _ValueType, class _Up, class ..._Args, 277b18fd965SEric Fiselier class _Tp = decay_t<_ValueType>, 278324506b9SEric Fiselier class = enable_if_t< 279324506b9SEric Fiselier is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && 280324506b9SEric Fiselier is_copy_constructible<_Tp>::value> 281324506b9SEric Fiselier > 282324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 2835c80f4f6SMarshall Clow _Tp& emplace(initializer_list<_Up>, _Args&&...); 284324506b9SEric Fiselier 285324506b9SEric Fiselier // 6.3.3 any modifiers 286324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 287324506b9SEric Fiselier void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); } 288324506b9SEric Fiselier 289324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 290324506b9SEric Fiselier void swap(any & __rhs) _NOEXCEPT; 291324506b9SEric Fiselier 292324506b9SEric Fiselier // 6.3.4 any observers 293324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 294324506b9SEric Fiselier bool has_value() const _NOEXCEPT { return __h != nullptr; } 295324506b9SEric Fiselier 296324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI) 297324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 298324506b9SEric Fiselier const type_info & type() const _NOEXCEPT { 299324506b9SEric Fiselier if (__h) { 300324506b9SEric Fiselier return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo)); 301324506b9SEric Fiselier } else { 302324506b9SEric Fiselier return typeid(void); 303324506b9SEric Fiselier } 304324506b9SEric Fiselier } 305324506b9SEric Fiselier#endif 306324506b9SEric Fiselier 307324506b9SEric Fiselierprivate: 308324506b9SEric Fiselier typedef __any_imp::_Action _Action; 309324506b9SEric Fiselier using _HandleFuncPtr = void* (*)(_Action, any const *, any *, const type_info *, 310324506b9SEric Fiselier const void* __fallback_info); 311324506b9SEric Fiselier 312324506b9SEric Fiselier union _Storage { 313324506b9SEric Fiselier constexpr _Storage() : __ptr(nullptr) {} 314324506b9SEric Fiselier void * __ptr; 315324506b9SEric Fiselier __any_imp::_Buffer __buf; 316324506b9SEric Fiselier }; 317324506b9SEric Fiselier 318dc7200b4SLouis Dionne _LIBCPP_INLINE_VISIBILITY 319324506b9SEric Fiselier void * __call(_Action __a, any * __other = nullptr, 320324506b9SEric Fiselier type_info const * __info = nullptr, 321324506b9SEric Fiselier const void* __fallback_info = nullptr) const 322324506b9SEric Fiselier { 323324506b9SEric Fiselier return __h(__a, this, __other, __info, __fallback_info); 324324506b9SEric Fiselier } 325324506b9SEric Fiselier 326dc7200b4SLouis Dionne _LIBCPP_INLINE_VISIBILITY 327324506b9SEric Fiselier void * __call(_Action __a, any * __other = nullptr, 328324506b9SEric Fiselier type_info const * __info = nullptr, 329324506b9SEric Fiselier const void* __fallback_info = nullptr) 330324506b9SEric Fiselier { 331324506b9SEric Fiselier return __h(__a, this, __other, __info, __fallback_info); 332324506b9SEric Fiselier } 333324506b9SEric Fiselier 334324506b9SEric Fiselier template <class> 335324506b9SEric Fiselier friend struct __any_imp::_SmallHandler; 336324506b9SEric Fiselier template <class> 337324506b9SEric Fiselier friend struct __any_imp::_LargeHandler; 338324506b9SEric Fiselier 339324506b9SEric Fiselier template <class _ValueType> 340324506b9SEric Fiselier friend add_pointer_t<add_const_t<_ValueType>> 341324506b9SEric Fiselier any_cast(any const *) _NOEXCEPT; 342324506b9SEric Fiselier 343324506b9SEric Fiselier template <class _ValueType> 344324506b9SEric Fiselier friend add_pointer_t<_ValueType> 345324506b9SEric Fiselier any_cast(any *) _NOEXCEPT; 346324506b9SEric Fiselier 347324506b9SEric Fiselier _HandleFuncPtr __h = nullptr; 348324506b9SEric Fiselier _Storage __s; 349324506b9SEric Fiselier}; 350324506b9SEric Fiselier 351324506b9SEric Fiseliernamespace __any_imp 352324506b9SEric Fiselier{ 353324506b9SEric Fiselier template <class _Tp> 354e2f2d1edSEric Fiselier struct _LIBCPP_TEMPLATE_VIS _SmallHandler 355324506b9SEric Fiselier { 356324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 357324506b9SEric Fiselier static void* __handle(_Action __act, any const * __this, any * __other, 358324506b9SEric Fiselier type_info const * __info, const void* __fallback_info) 359324506b9SEric Fiselier { 360324506b9SEric Fiselier switch (__act) 361324506b9SEric Fiselier { 362324506b9SEric Fiselier case _Action::_Destroy: 363324506b9SEric Fiselier __destroy(const_cast<any &>(*__this)); 364324506b9SEric Fiselier return nullptr; 365324506b9SEric Fiselier case _Action::_Copy: 366324506b9SEric Fiselier __copy(*__this, *__other); 367324506b9SEric Fiselier return nullptr; 368324506b9SEric Fiselier case _Action::_Move: 369324506b9SEric Fiselier __move(const_cast<any &>(*__this), *__other); 370324506b9SEric Fiselier return nullptr; 371324506b9SEric Fiselier case _Action::_Get: 372324506b9SEric Fiselier return __get(const_cast<any &>(*__this), __info, __fallback_info); 373324506b9SEric Fiselier case _Action::_TypeInfo: 374324506b9SEric Fiselier return __type_info(); 375324506b9SEric Fiselier } 376e39095a3SLouis Dionne __libcpp_unreachable(); 377324506b9SEric Fiselier } 378324506b9SEric Fiselier 379324506b9SEric Fiselier template <class ..._Args> 380324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 3815c80f4f6SMarshall Clow static _Tp& __create(any & __dest, _Args&&... __args) { 38239c87951SMarshall Clow typedef allocator<_Tp> _Alloc; 38339c87951SMarshall Clow typedef allocator_traits<_Alloc> _ATraits; 38439c87951SMarshall Clow _Alloc __a; 38539c87951SMarshall Clow _Tp * __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s.__buf)); 38639c87951SMarshall Clow _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...); 387324506b9SEric Fiselier __dest.__h = &_SmallHandler::__handle; 3885c80f4f6SMarshall Clow return *__ret; 389324506b9SEric Fiselier } 390324506b9SEric Fiselier 391324506b9SEric Fiselier private: 392324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 393324506b9SEric Fiselier static void __destroy(any & __this) { 39439c87951SMarshall Clow typedef allocator<_Tp> _Alloc; 39539c87951SMarshall Clow typedef allocator_traits<_Alloc> _ATraits; 39639c87951SMarshall Clow _Alloc __a; 39739c87951SMarshall Clow _Tp * __p = static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf)); 39839c87951SMarshall Clow _ATraits::destroy(__a, __p); 399324506b9SEric Fiselier __this.__h = nullptr; 400324506b9SEric Fiselier } 401324506b9SEric Fiselier 402324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 403324506b9SEric Fiselier static void __copy(any const & __this, any & __dest) { 404324506b9SEric Fiselier _SmallHandler::__create(__dest, *static_cast<_Tp const *>( 405324506b9SEric Fiselier static_cast<void const *>(&__this.__s.__buf))); 406324506b9SEric Fiselier } 407324506b9SEric Fiselier 408324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 409324506b9SEric Fiselier static void __move(any & __this, any & __dest) { 410324506b9SEric Fiselier _SmallHandler::__create(__dest, _VSTD::move( 411324506b9SEric Fiselier *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf)))); 412324506b9SEric Fiselier __destroy(__this); 413324506b9SEric Fiselier } 414324506b9SEric Fiselier 415324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 416324506b9SEric Fiselier static void* __get(any & __this, 417324506b9SEric Fiselier type_info const * __info, 418324506b9SEric Fiselier const void* __fallback_id) 419324506b9SEric Fiselier { 420324506b9SEric Fiselier if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id)) 421324506b9SEric Fiselier return static_cast<void*>(&__this.__s.__buf); 422324506b9SEric Fiselier return nullptr; 423324506b9SEric Fiselier } 424324506b9SEric Fiselier 425324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 426324506b9SEric Fiselier static void* __type_info() 427324506b9SEric Fiselier { 428324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI) 429324506b9SEric Fiselier return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); 430324506b9SEric Fiselier#else 431324506b9SEric Fiselier return nullptr; 432324506b9SEric Fiselier#endif 433324506b9SEric Fiselier } 434324506b9SEric Fiselier }; 435324506b9SEric Fiselier 436324506b9SEric Fiselier template <class _Tp> 437e2f2d1edSEric Fiselier struct _LIBCPP_TEMPLATE_VIS _LargeHandler 438324506b9SEric Fiselier { 439324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 440324506b9SEric Fiselier static void* __handle(_Action __act, any const * __this, 441324506b9SEric Fiselier any * __other, type_info const * __info, 442324506b9SEric Fiselier void const* __fallback_info) 443324506b9SEric Fiselier { 444324506b9SEric Fiselier switch (__act) 445324506b9SEric Fiselier { 446324506b9SEric Fiselier case _Action::_Destroy: 447324506b9SEric Fiselier __destroy(const_cast<any &>(*__this)); 448324506b9SEric Fiselier return nullptr; 449324506b9SEric Fiselier case _Action::_Copy: 450324506b9SEric Fiselier __copy(*__this, *__other); 451324506b9SEric Fiselier return nullptr; 452324506b9SEric Fiselier case _Action::_Move: 453324506b9SEric Fiselier __move(const_cast<any &>(*__this), *__other); 454324506b9SEric Fiselier return nullptr; 455324506b9SEric Fiselier case _Action::_Get: 456324506b9SEric Fiselier return __get(const_cast<any &>(*__this), __info, __fallback_info); 457324506b9SEric Fiselier case _Action::_TypeInfo: 458324506b9SEric Fiselier return __type_info(); 459324506b9SEric Fiselier } 460e39095a3SLouis Dionne __libcpp_unreachable(); 461324506b9SEric Fiselier } 462324506b9SEric Fiselier 463324506b9SEric Fiselier template <class ..._Args> 464324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 4655c80f4f6SMarshall Clow static _Tp& __create(any & __dest, _Args&&... __args) { 466324506b9SEric Fiselier typedef allocator<_Tp> _Alloc; 46739c87951SMarshall Clow typedef allocator_traits<_Alloc> _ATraits; 468324506b9SEric Fiselier typedef __allocator_destructor<_Alloc> _Dp; 469324506b9SEric Fiselier _Alloc __a; 47039c87951SMarshall Clow unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1)); 47139c87951SMarshall Clow _Tp * __ret = __hold.get(); 47239c87951SMarshall Clow _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...); 473324506b9SEric Fiselier __dest.__s.__ptr = __hold.release(); 474324506b9SEric Fiselier __dest.__h = &_LargeHandler::__handle; 4755c80f4f6SMarshall Clow return *__ret; 476324506b9SEric Fiselier } 477324506b9SEric Fiselier 478324506b9SEric Fiselier private: 479324506b9SEric Fiselier 480324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 481324506b9SEric Fiselier static void __destroy(any & __this){ 48239c87951SMarshall Clow typedef allocator<_Tp> _Alloc; 48339c87951SMarshall Clow typedef allocator_traits<_Alloc> _ATraits; 48439c87951SMarshall Clow _Alloc __a; 48539c87951SMarshall Clow _Tp * __p = static_cast<_Tp *>(__this.__s.__ptr); 48639c87951SMarshall Clow _ATraits::destroy(__a, __p); 48739c87951SMarshall Clow _ATraits::deallocate(__a, __p, 1); 488324506b9SEric Fiselier __this.__h = nullptr; 489324506b9SEric Fiselier } 490324506b9SEric Fiselier 491324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 492324506b9SEric Fiselier static void __copy(any const & __this, any & __dest) { 493324506b9SEric Fiselier _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); 494324506b9SEric Fiselier } 495324506b9SEric Fiselier 496324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 497324506b9SEric Fiselier static void __move(any & __this, any & __dest) { 498324506b9SEric Fiselier __dest.__s.__ptr = __this.__s.__ptr; 499324506b9SEric Fiselier __dest.__h = &_LargeHandler::__handle; 500324506b9SEric Fiselier __this.__h = nullptr; 501324506b9SEric Fiselier } 502324506b9SEric Fiselier 503324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 504324506b9SEric Fiselier static void* __get(any & __this, type_info const * __info, 505324506b9SEric Fiselier void const* __fallback_info) 506324506b9SEric Fiselier { 507324506b9SEric Fiselier if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info)) 508324506b9SEric Fiselier return static_cast<void*>(__this.__s.__ptr); 509324506b9SEric Fiselier return nullptr; 510324506b9SEric Fiselier 511324506b9SEric Fiselier } 512324506b9SEric Fiselier 513324506b9SEric Fiselier _LIBCPP_INLINE_VISIBILITY 514324506b9SEric Fiselier static void* __type_info() 515324506b9SEric Fiselier { 516324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI) 517324506b9SEric Fiselier return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); 518324506b9SEric Fiselier#else 519324506b9SEric Fiselier return nullptr; 520324506b9SEric Fiselier#endif 521324506b9SEric Fiselier } 522324506b9SEric Fiselier }; 523324506b9SEric Fiselier 524324506b9SEric Fiselier} // namespace __any_imp 525324506b9SEric Fiselier 526324506b9SEric Fiselier 527b18fd965SEric Fiseliertemplate <class _ValueType, class _Tp, class> 528324506b9SEric Fiselierany::any(_ValueType && __v) : __h(nullptr) 529324506b9SEric Fiselier{ 530b18fd965SEric Fiselier __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v)); 531324506b9SEric Fiselier} 532324506b9SEric Fiselier 533b18fd965SEric Fiseliertemplate <class _ValueType, class ..._Args, class _Tp, class> 534b18fd965SEric Fiselierany::any(in_place_type_t<_ValueType>, _Args&&... __args) { 535b18fd965SEric Fiselier __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); 536205ead8cSLouis Dionne} 537324506b9SEric Fiselier 538b18fd965SEric Fiseliertemplate <class _ValueType, class _Up, class ..._Args, class _Tp, class> 539b18fd965SEric Fiselierany::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) { 540b18fd965SEric Fiselier __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); 541324506b9SEric Fiselier} 542324506b9SEric Fiselier 543b18fd965SEric Fiseliertemplate <class _ValueType, class, class> 544324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 545324506b9SEric Fiselierany & any::operator=(_ValueType && __v) 546324506b9SEric Fiselier{ 547324506b9SEric Fiselier any(_VSTD::forward<_ValueType>(__v)).swap(*this); 548324506b9SEric Fiselier return *this; 549324506b9SEric Fiselier} 550324506b9SEric Fiselier 551b18fd965SEric Fiseliertemplate <class _ValueType, class ..._Args, class _Tp, class> 552324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 5535c80f4f6SMarshall Clow_Tp& any::emplace(_Args&&... __args) { 554324506b9SEric Fiselier reset(); 5555c80f4f6SMarshall Clow return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); 556324506b9SEric Fiselier} 557324506b9SEric Fiselier 558b18fd965SEric Fiseliertemplate <class _ValueType, class _Up, class ..._Args, class _Tp, class> 559324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 5605c80f4f6SMarshall Clow_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) { 561324506b9SEric Fiselier reset(); 5625c80f4f6SMarshall Clow return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); 563324506b9SEric Fiselier} 564324506b9SEric Fiselier 565324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 566324506b9SEric Fiseliervoid any::swap(any & __rhs) _NOEXCEPT 567324506b9SEric Fiselier{ 568b18fd965SEric Fiselier if (this == &__rhs) 569b18fd965SEric Fiselier return; 570324506b9SEric Fiselier if (__h && __rhs.__h) { 571324506b9SEric Fiselier any __tmp; 572324506b9SEric Fiselier __rhs.__call(_Action::_Move, &__tmp); 573324506b9SEric Fiselier this->__call(_Action::_Move, &__rhs); 574324506b9SEric Fiselier __tmp.__call(_Action::_Move, this); 575324506b9SEric Fiselier } 576324506b9SEric Fiselier else if (__h) { 577324506b9SEric Fiselier this->__call(_Action::_Move, &__rhs); 578324506b9SEric Fiselier } 579324506b9SEric Fiselier else if (__rhs.__h) { 580324506b9SEric Fiselier __rhs.__call(_Action::_Move, this); 581324506b9SEric Fiselier } 582324506b9SEric Fiselier} 583324506b9SEric Fiselier 584324506b9SEric Fiselier// 6.4 Non-member functions 585324506b9SEric Fiselier 586324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 587324506b9SEric Fiseliervoid swap(any & __lhs, any & __rhs) _NOEXCEPT 588324506b9SEric Fiselier{ 589324506b9SEric Fiselier __lhs.swap(__rhs); 590324506b9SEric Fiselier} 591324506b9SEric Fiselier 592324506b9SEric Fiseliertemplate <class _Tp, class ..._Args> 593324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 594324506b9SEric Fiselierany make_any(_Args&&... __args) { 595034555f1SEric Fiselier return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...); 596324506b9SEric Fiselier} 597324506b9SEric Fiselier 598324506b9SEric Fiseliertemplate <class _Tp, class _Up, class ..._Args> 599324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 600324506b9SEric Fiselierany make_any(initializer_list<_Up> __il, _Args&&... __args) { 601034555f1SEric Fiselier return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...); 602324506b9SEric Fiselier} 603324506b9SEric Fiselier 604324506b9SEric Fiseliertemplate <class _ValueType> 605324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 6068a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST 607324506b9SEric Fiselier_ValueType any_cast(any const & __v) 608324506b9SEric Fiselier{ 609b18fd965SEric Fiselier using _RawValueType = __uncvref_t<_ValueType>; 610b18fd965SEric Fiselier static_assert(is_constructible<_ValueType, _RawValueType const &>::value, 6119c737fddSEric Fiselier "ValueType is required to be a const lvalue reference " 6129c737fddSEric Fiselier "or a CopyConstructible type"); 613b18fd965SEric Fiselier auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v); 614324506b9SEric Fiselier if (__tmp == nullptr) 6150fc8cec7SMarshall Clow __throw_bad_any_cast(); 616b18fd965SEric Fiselier return static_cast<_ValueType>(*__tmp); 617324506b9SEric Fiselier} 618324506b9SEric Fiselier 619324506b9SEric Fiseliertemplate <class _ValueType> 620324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 6218a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST 622324506b9SEric Fiselier_ValueType any_cast(any & __v) 623324506b9SEric Fiselier{ 624b18fd965SEric Fiselier using _RawValueType = __uncvref_t<_ValueType>; 625b18fd965SEric Fiselier static_assert(is_constructible<_ValueType, _RawValueType &>::value, 6269c737fddSEric Fiselier "ValueType is required to be an lvalue reference " 6279c737fddSEric Fiselier "or a CopyConstructible type"); 628b18fd965SEric Fiselier auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); 629324506b9SEric Fiselier if (__tmp == nullptr) 6300fc8cec7SMarshall Clow __throw_bad_any_cast(); 631b18fd965SEric Fiselier return static_cast<_ValueType>(*__tmp); 632324506b9SEric Fiselier} 633324506b9SEric Fiselier 634324506b9SEric Fiseliertemplate <class _ValueType> 635324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 6368a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST 637324506b9SEric Fiselier_ValueType any_cast(any && __v) 638324506b9SEric Fiselier{ 639b18fd965SEric Fiselier using _RawValueType = __uncvref_t<_ValueType>; 640b18fd965SEric Fiselier static_assert(is_constructible<_ValueType, _RawValueType>::value, 6419c737fddSEric Fiselier "ValueType is required to be an rvalue reference " 6429c737fddSEric Fiselier "or a CopyConstructible type"); 643b18fd965SEric Fiselier auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); 644324506b9SEric Fiselier if (__tmp == nullptr) 6450fc8cec7SMarshall Clow __throw_bad_any_cast(); 646b18fd965SEric Fiselier return static_cast<_ValueType>(_VSTD::move(*__tmp)); 647324506b9SEric Fiselier} 648324506b9SEric Fiselier 649324506b9SEric Fiseliertemplate <class _ValueType> 650324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 651324506b9SEric Fiselieradd_pointer_t<add_const_t<_ValueType>> 652324506b9SEric Fiselierany_cast(any const * __any) _NOEXCEPT 653324506b9SEric Fiselier{ 654324506b9SEric Fiselier static_assert(!is_reference<_ValueType>::value, 655324506b9SEric Fiselier "_ValueType may not be a reference."); 656324506b9SEric Fiselier return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any)); 657324506b9SEric Fiselier} 658324506b9SEric Fiselier 659c5777f4dSEric Fiseliertemplate <class _RetType> 660c5777f4dSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 661c5777f4dSEric Fiselier_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept { 662c5777f4dSEric Fiselier return static_cast<_RetType>(__p); 663c5777f4dSEric Fiselier} 664c5777f4dSEric Fiselier 665c5777f4dSEric Fiseliertemplate <class _RetType> 666c5777f4dSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 667c5777f4dSEric Fiselier_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept { 668c5777f4dSEric Fiselier return nullptr; 669c5777f4dSEric Fiselier} 670c5777f4dSEric Fiselier 671324506b9SEric Fiseliertemplate <class _ValueType> 672c358d98bSLouis Dionne_LIBCPP_HIDE_FROM_ABI 673324506b9SEric Fiselieradd_pointer_t<_ValueType> 674324506b9SEric Fiselierany_cast(any * __any) _NOEXCEPT 675324506b9SEric Fiselier{ 676324506b9SEric Fiselier using __any_imp::_Action; 677324506b9SEric Fiselier static_assert(!is_reference<_ValueType>::value, 678324506b9SEric Fiselier "_ValueType may not be a reference."); 679324506b9SEric Fiselier typedef typename add_pointer<_ValueType>::type _ReturnType; 680324506b9SEric Fiselier if (__any && __any->__h) { 681c5777f4dSEric Fiselier void *__p = __any->__call(_Action::_Get, nullptr, 682324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI) 683324506b9SEric Fiselier &typeid(_ValueType), 684324506b9SEric Fiselier#else 685324506b9SEric Fiselier nullptr, 686324506b9SEric Fiselier#endif 687c5777f4dSEric Fiselier __any_imp::__get_fallback_typeid<_ValueType>()); 688c5777f4dSEric Fiselier return _VSTD::__pointer_or_func_cast<_ReturnType>( 689c5777f4dSEric Fiselier __p, is_function<_ValueType>{}); 690324506b9SEric Fiselier } 691324506b9SEric Fiselier return nullptr; 692324506b9SEric Fiselier} 693324506b9SEric Fiselier 694324506b9SEric Fiselier#endif // _LIBCPP_STD_VER > 14 695324506b9SEric Fiselier 696324506b9SEric Fiselier_LIBCPP_END_NAMESPACE_STD 697324506b9SEric Fiselier 698324506b9SEric Fiselier#endif // _LIBCPP_ANY 699