1*38fd1498Szrj// <any> -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj// Copyright (C) 2014-2018 Free Software Foundation, Inc. 4*38fd1498Szrj// 5*38fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj// software; you can redistribute it and/or modify it under the 7*38fd1498Szrj// terms of the GNU General Public License as published by the 8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj// any later version. 10*38fd1498Szrj 11*38fd1498Szrj// This library is distributed in the hope that it will be useful, 12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj// GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj// 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj// You should have received a copy of the GNU General Public License and 21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj// <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj/** @file include/any 26*38fd1498Szrj * This is a Standard C++ Library header. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj#ifndef _GLIBCXX_ANY 30*38fd1498Szrj#define _GLIBCXX_ANY 1 31*38fd1498Szrj 32*38fd1498Szrj#pragma GCC system_header 33*38fd1498Szrj 34*38fd1498Szrj#if __cplusplus >= 201703L 35*38fd1498Szrj 36*38fd1498Szrj#include <typeinfo> 37*38fd1498Szrj#include <new> 38*38fd1498Szrj#include <utility> 39*38fd1498Szrj#include <type_traits> 40*38fd1498Szrj 41*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 42*38fd1498Szrj{ 43*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 44*38fd1498Szrj 45*38fd1498Szrj /** 46*38fd1498Szrj * @addtogroup utilities 47*38fd1498Szrj * @{ 48*38fd1498Szrj */ 49*38fd1498Szrj 50*38fd1498Szrj /** 51*38fd1498Szrj * @brief Exception class thrown by a failed @c any_cast 52*38fd1498Szrj * @ingroup exceptions 53*38fd1498Szrj */ 54*38fd1498Szrj class bad_any_cast : public bad_cast 55*38fd1498Szrj { 56*38fd1498Szrj public: 57*38fd1498Szrj virtual const char* what() const noexcept { return "bad any_cast"; } 58*38fd1498Szrj }; 59*38fd1498Szrj 60*38fd1498Szrj [[gnu::noreturn]] inline void __throw_bad_any_cast() 61*38fd1498Szrj { 62*38fd1498Szrj#if __cpp_exceptions 63*38fd1498Szrj throw bad_any_cast{}; 64*38fd1498Szrj#else 65*38fd1498Szrj __builtin_abort(); 66*38fd1498Szrj#endif 67*38fd1498Szrj } 68*38fd1498Szrj 69*38fd1498Szrj#define __cpp_lib_any 201603 70*38fd1498Szrj 71*38fd1498Szrj /** 72*38fd1498Szrj * @brief A type-safe container of any type. 73*38fd1498Szrj * 74*38fd1498Szrj * An @c any object's state is either empty or it stores a contained object 75*38fd1498Szrj * of CopyConstructible type. 76*38fd1498Szrj */ 77*38fd1498Szrj class any 78*38fd1498Szrj { 79*38fd1498Szrj // Holds either pointer to a heap object or the contained object itself. 80*38fd1498Szrj union _Storage 81*38fd1498Szrj { 82*38fd1498Szrj constexpr _Storage() : _M_ptr{nullptr} {} 83*38fd1498Szrj 84*38fd1498Szrj // Prevent trivial copies of this type, buffer might hold a non-POD. 85*38fd1498Szrj _Storage(const _Storage&) = delete; 86*38fd1498Szrj _Storage& operator=(const _Storage&) = delete; 87*38fd1498Szrj 88*38fd1498Szrj void* _M_ptr; 89*38fd1498Szrj aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer; 90*38fd1498Szrj }; 91*38fd1498Szrj 92*38fd1498Szrj template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>, 93*38fd1498Szrj bool _Fits = (sizeof(_Tp) <= sizeof(_Storage)) 94*38fd1498Szrj && (alignof(_Tp) <= alignof(_Storage))> 95*38fd1498Szrj using _Internal = std::integral_constant<bool, _Safe::value && _Fits>; 96*38fd1498Szrj 97*38fd1498Szrj template<typename _Tp> 98*38fd1498Szrj struct _Manager_internal; // uses small-object optimization 99*38fd1498Szrj 100*38fd1498Szrj template<typename _Tp> 101*38fd1498Szrj struct _Manager_external; // creates contained object on the heap 102*38fd1498Szrj 103*38fd1498Szrj template<typename _Tp> 104*38fd1498Szrj using _Manager = conditional_t<_Internal<_Tp>::value, 105*38fd1498Szrj _Manager_internal<_Tp>, 106*38fd1498Szrj _Manager_external<_Tp>>; 107*38fd1498Szrj 108*38fd1498Szrj template<typename _Tp, typename _Decayed = decay_t<_Tp>> 109*38fd1498Szrj using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>; 110*38fd1498Szrj 111*38fd1498Szrj /// Emplace with an object created from @p __args as the contained object. 112*38fd1498Szrj template <typename _Tp, typename... _Args, 113*38fd1498Szrj typename _Mgr = _Manager<_Tp>> 114*38fd1498Szrj void __do_emplace(_Args&&... __args) 115*38fd1498Szrj { 116*38fd1498Szrj reset(); 117*38fd1498Szrj _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); 118*38fd1498Szrj _M_manager = &_Mgr::_S_manage; 119*38fd1498Szrj } 120*38fd1498Szrj 121*38fd1498Szrj /// Emplace with an object created from @p __il and @p __args as 122*38fd1498Szrj /// the contained object. 123*38fd1498Szrj template <typename _Tp, typename _Up, typename... _Args, 124*38fd1498Szrj typename _Mgr = _Manager<_Tp>> 125*38fd1498Szrj void __do_emplace(initializer_list<_Up> __il, _Args&&... __args) 126*38fd1498Szrj { 127*38fd1498Szrj reset(); 128*38fd1498Szrj _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); 129*38fd1498Szrj _M_manager = &_Mgr::_S_manage; 130*38fd1498Szrj } 131*38fd1498Szrj 132*38fd1498Szrj public: 133*38fd1498Szrj // construct/destruct 134*38fd1498Szrj 135*38fd1498Szrj /// Default constructor, creates an empty object. 136*38fd1498Szrj constexpr any() noexcept : _M_manager(nullptr) { } 137*38fd1498Szrj 138*38fd1498Szrj /// Copy constructor, copies the state of @p __other 139*38fd1498Szrj any(const any& __other) 140*38fd1498Szrj { 141*38fd1498Szrj if (!__other.has_value()) 142*38fd1498Szrj _M_manager = nullptr; 143*38fd1498Szrj else 144*38fd1498Szrj { 145*38fd1498Szrj _Arg __arg; 146*38fd1498Szrj __arg._M_any = this; 147*38fd1498Szrj __other._M_manager(_Op_clone, &__other, &__arg); 148*38fd1498Szrj } 149*38fd1498Szrj } 150*38fd1498Szrj 151*38fd1498Szrj /** 152*38fd1498Szrj * @brief Move constructor, transfer the state from @p __other 153*38fd1498Szrj * 154*38fd1498Szrj * @post @c !__other.has_value() (this postcondition is a GNU extension) 155*38fd1498Szrj */ 156*38fd1498Szrj any(any&& __other) noexcept 157*38fd1498Szrj { 158*38fd1498Szrj if (!__other.has_value()) 159*38fd1498Szrj _M_manager = nullptr; 160*38fd1498Szrj else 161*38fd1498Szrj { 162*38fd1498Szrj _Arg __arg; 163*38fd1498Szrj __arg._M_any = this; 164*38fd1498Szrj __other._M_manager(_Op_xfer, &__other, &__arg); 165*38fd1498Szrj } 166*38fd1498Szrj } 167*38fd1498Szrj 168*38fd1498Szrj template <typename _Res, typename _Tp, typename... _Args> 169*38fd1498Szrj using __any_constructible = 170*38fd1498Szrj enable_if<__and_<is_copy_constructible<_Tp>, 171*38fd1498Szrj is_constructible<_Tp, _Args...>>::value, 172*38fd1498Szrj _Res>; 173*38fd1498Szrj 174*38fd1498Szrj template <typename _Tp, typename... _Args> 175*38fd1498Szrj using __any_constructible_t = 176*38fd1498Szrj typename __any_constructible<bool, _Tp, _Args...>::type; 177*38fd1498Szrj 178*38fd1498Szrj /// Construct with a copy of @p __value as the contained object. 179*38fd1498Szrj template <typename _ValueType, typename _Tp = _Decay<_ValueType>, 180*38fd1498Szrj typename _Mgr = _Manager<_Tp>, 181*38fd1498Szrj __any_constructible_t<_Tp, _ValueType&&> = true, 182*38fd1498Szrj enable_if_t<!__is_in_place_type<_Tp>::value, bool> = true> 183*38fd1498Szrj any(_ValueType&& __value) 184*38fd1498Szrj : _M_manager(&_Mgr::_S_manage) 185*38fd1498Szrj { 186*38fd1498Szrj _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value)); 187*38fd1498Szrj } 188*38fd1498Szrj 189*38fd1498Szrj /// Construct with a copy of @p __value as the contained object. 190*38fd1498Szrj template <typename _ValueType, typename _Tp = _Decay<_ValueType>, 191*38fd1498Szrj typename _Mgr = _Manager<_Tp>, 192*38fd1498Szrj enable_if_t<__and_<is_copy_constructible<_Tp>, 193*38fd1498Szrj __not_<is_constructible<_Tp, _ValueType&&>>, 194*38fd1498Szrj __not_<__is_in_place_type<_Tp>>>::value, 195*38fd1498Szrj bool> = false> 196*38fd1498Szrj any(_ValueType&& __value) 197*38fd1498Szrj : _M_manager(&_Mgr::_S_manage) 198*38fd1498Szrj { 199*38fd1498Szrj _Mgr::_S_create(_M_storage, __value); 200*38fd1498Szrj } 201*38fd1498Szrj 202*38fd1498Szrj /// Construct with an object created from @p __args as the contained object. 203*38fd1498Szrj template <typename _ValueType, typename... _Args, 204*38fd1498Szrj typename _Tp = _Decay<_ValueType>, 205*38fd1498Szrj typename _Mgr = _Manager<_Tp>, 206*38fd1498Szrj __any_constructible_t<_Tp, _Args&&...> = false> 207*38fd1498Szrj explicit 208*38fd1498Szrj any(in_place_type_t<_ValueType>, _Args&&... __args) 209*38fd1498Szrj : _M_manager(&_Mgr::_S_manage) 210*38fd1498Szrj { 211*38fd1498Szrj _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); 212*38fd1498Szrj } 213*38fd1498Szrj 214*38fd1498Szrj /// Construct with an object created from @p __il and @p __args as 215*38fd1498Szrj /// the contained object. 216*38fd1498Szrj template <typename _ValueType, typename _Up, typename... _Args, 217*38fd1498Szrj typename _Tp = _Decay<_ValueType>, 218*38fd1498Szrj typename _Mgr = _Manager<_Tp>, 219*38fd1498Szrj __any_constructible_t<_Tp, initializer_list<_Up>, 220*38fd1498Szrj _Args&&...> = false> 221*38fd1498Szrj explicit 222*38fd1498Szrj any(in_place_type_t<_ValueType>, 223*38fd1498Szrj initializer_list<_Up> __il, _Args&&... __args) 224*38fd1498Szrj : _M_manager(&_Mgr::_S_manage) 225*38fd1498Szrj { 226*38fd1498Szrj _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); 227*38fd1498Szrj } 228*38fd1498Szrj 229*38fd1498Szrj /// Destructor, calls @c reset() 230*38fd1498Szrj ~any() { reset(); } 231*38fd1498Szrj 232*38fd1498Szrj // assignments 233*38fd1498Szrj 234*38fd1498Szrj /// Copy the state of another object. 235*38fd1498Szrj any& operator=(const any& __rhs) 236*38fd1498Szrj { 237*38fd1498Szrj *this = any(__rhs); 238*38fd1498Szrj return *this; 239*38fd1498Szrj } 240*38fd1498Szrj 241*38fd1498Szrj /** 242*38fd1498Szrj * @brief Move assignment operator 243*38fd1498Szrj * 244*38fd1498Szrj * @post @c !__rhs.has_value() (not guaranteed for other implementations) 245*38fd1498Szrj */ 246*38fd1498Szrj any& operator=(any&& __rhs) noexcept 247*38fd1498Szrj { 248*38fd1498Szrj if (!__rhs.has_value()) 249*38fd1498Szrj reset(); 250*38fd1498Szrj else if (this != &__rhs) 251*38fd1498Szrj { 252*38fd1498Szrj reset(); 253*38fd1498Szrj _Arg __arg; 254*38fd1498Szrj __arg._M_any = this; 255*38fd1498Szrj __rhs._M_manager(_Op_xfer, &__rhs, &__arg); 256*38fd1498Szrj } 257*38fd1498Szrj return *this; 258*38fd1498Szrj } 259*38fd1498Szrj 260*38fd1498Szrj /// Store a copy of @p __rhs as the contained object. 261*38fd1498Szrj template<typename _ValueType> 262*38fd1498Szrj enable_if_t<is_copy_constructible<_Decay<_ValueType>>::value, any&> 263*38fd1498Szrj operator=(_ValueType&& __rhs) 264*38fd1498Szrj { 265*38fd1498Szrj *this = any(std::forward<_ValueType>(__rhs)); 266*38fd1498Szrj return *this; 267*38fd1498Szrj } 268*38fd1498Szrj 269*38fd1498Szrj /// Emplace with an object created from @p __args as the contained object. 270*38fd1498Szrj template <typename _ValueType, typename... _Args> 271*38fd1498Szrj typename __any_constructible<_Decay<_ValueType>&, 272*38fd1498Szrj _Decay<_ValueType>, _Args&&...>::type 273*38fd1498Szrj emplace(_Args&&... __args) 274*38fd1498Szrj { 275*38fd1498Szrj __do_emplace<_Decay<_ValueType>>(std::forward<_Args>(__args)...); 276*38fd1498Szrj any::_Arg __arg; 277*38fd1498Szrj this->_M_manager(any::_Op_access, this, &__arg); 278*38fd1498Szrj return *static_cast<_Decay<_ValueType>*>(__arg._M_obj); 279*38fd1498Szrj } 280*38fd1498Szrj 281*38fd1498Szrj /// Emplace with an object created from @p __il and @p __args as 282*38fd1498Szrj /// the contained object. 283*38fd1498Szrj template <typename _ValueType, typename _Up, typename... _Args> 284*38fd1498Szrj typename __any_constructible<_Decay<_ValueType>&, 285*38fd1498Szrj _Decay<_ValueType>, 286*38fd1498Szrj initializer_list<_Up>, 287*38fd1498Szrj _Args&&...>::type 288*38fd1498Szrj emplace(initializer_list<_Up> __il, _Args&&... __args) 289*38fd1498Szrj { 290*38fd1498Szrj __do_emplace<_Decay<_ValueType>, _Up>(__il, 291*38fd1498Szrj std::forward<_Args>(__args)...); 292*38fd1498Szrj any::_Arg __arg; 293*38fd1498Szrj this->_M_manager(any::_Op_access, this, &__arg); 294*38fd1498Szrj return *static_cast<_Decay<_ValueType>*>(__arg._M_obj); 295*38fd1498Szrj } 296*38fd1498Szrj 297*38fd1498Szrj // modifiers 298*38fd1498Szrj 299*38fd1498Szrj /// If not empty, destroy the contained object. 300*38fd1498Szrj void reset() noexcept 301*38fd1498Szrj { 302*38fd1498Szrj if (has_value()) 303*38fd1498Szrj { 304*38fd1498Szrj _M_manager(_Op_destroy, this, nullptr); 305*38fd1498Szrj _M_manager = nullptr; 306*38fd1498Szrj } 307*38fd1498Szrj } 308*38fd1498Szrj 309*38fd1498Szrj /// Exchange state with another object. 310*38fd1498Szrj void swap(any& __rhs) noexcept 311*38fd1498Szrj { 312*38fd1498Szrj if (!has_value() && !__rhs.has_value()) 313*38fd1498Szrj return; 314*38fd1498Szrj 315*38fd1498Szrj if (has_value() && __rhs.has_value()) 316*38fd1498Szrj { 317*38fd1498Szrj if (this == &__rhs) 318*38fd1498Szrj return; 319*38fd1498Szrj 320*38fd1498Szrj any __tmp; 321*38fd1498Szrj _Arg __arg; 322*38fd1498Szrj __arg._M_any = &__tmp; 323*38fd1498Szrj __rhs._M_manager(_Op_xfer, &__rhs, &__arg); 324*38fd1498Szrj __arg._M_any = &__rhs; 325*38fd1498Szrj _M_manager(_Op_xfer, this, &__arg); 326*38fd1498Szrj __arg._M_any = this; 327*38fd1498Szrj __tmp._M_manager(_Op_xfer, &__tmp, &__arg); 328*38fd1498Szrj } 329*38fd1498Szrj else 330*38fd1498Szrj { 331*38fd1498Szrj any* __empty = !has_value() ? this : &__rhs; 332*38fd1498Szrj any* __full = !has_value() ? &__rhs : this; 333*38fd1498Szrj _Arg __arg; 334*38fd1498Szrj __arg._M_any = __empty; 335*38fd1498Szrj __full->_M_manager(_Op_xfer, __full, &__arg); 336*38fd1498Szrj } 337*38fd1498Szrj } 338*38fd1498Szrj 339*38fd1498Szrj // observers 340*38fd1498Szrj 341*38fd1498Szrj /// Reports whether there is a contained object or not. 342*38fd1498Szrj bool has_value() const noexcept { return _M_manager != nullptr; } 343*38fd1498Szrj 344*38fd1498Szrj#if __cpp_rtti 345*38fd1498Szrj /// The @c typeid of the contained object, or @c typeid(void) if empty. 346*38fd1498Szrj const type_info& type() const noexcept 347*38fd1498Szrj { 348*38fd1498Szrj if (!has_value()) 349*38fd1498Szrj return typeid(void); 350*38fd1498Szrj _Arg __arg; 351*38fd1498Szrj _M_manager(_Op_get_type_info, this, &__arg); 352*38fd1498Szrj return *__arg._M_typeinfo; 353*38fd1498Szrj } 354*38fd1498Szrj#endif 355*38fd1498Szrj 356*38fd1498Szrj template<typename _Tp> 357*38fd1498Szrj static constexpr bool __is_valid_cast() 358*38fd1498Szrj { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; } 359*38fd1498Szrj 360*38fd1498Szrj private: 361*38fd1498Szrj enum _Op { 362*38fd1498Szrj _Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer 363*38fd1498Szrj }; 364*38fd1498Szrj 365*38fd1498Szrj union _Arg 366*38fd1498Szrj { 367*38fd1498Szrj void* _M_obj; 368*38fd1498Szrj const std::type_info* _M_typeinfo; 369*38fd1498Szrj any* _M_any; 370*38fd1498Szrj }; 371*38fd1498Szrj 372*38fd1498Szrj void (*_M_manager)(_Op, const any*, _Arg*); 373*38fd1498Szrj _Storage _M_storage; 374*38fd1498Szrj 375*38fd1498Szrj template<typename _Tp> 376*38fd1498Szrj friend void* __any_caster(const any* __any); 377*38fd1498Szrj 378*38fd1498Szrj // Manage in-place contained object. 379*38fd1498Szrj template<typename _Tp> 380*38fd1498Szrj struct _Manager_internal 381*38fd1498Szrj { 382*38fd1498Szrj static void 383*38fd1498Szrj _S_manage(_Op __which, const any* __anyp, _Arg* __arg); 384*38fd1498Szrj 385*38fd1498Szrj template<typename _Up> 386*38fd1498Szrj static void 387*38fd1498Szrj _S_create(_Storage& __storage, _Up&& __value) 388*38fd1498Szrj { 389*38fd1498Szrj void* __addr = &__storage._M_buffer; 390*38fd1498Szrj ::new (__addr) _Tp(std::forward<_Up>(__value)); 391*38fd1498Szrj } 392*38fd1498Szrj 393*38fd1498Szrj template<typename... _Args> 394*38fd1498Szrj static void 395*38fd1498Szrj _S_create(_Storage& __storage, _Args&&... __args) 396*38fd1498Szrj { 397*38fd1498Szrj void* __addr = &__storage._M_buffer; 398*38fd1498Szrj ::new (__addr) _Tp(std::forward<_Args>(__args)...); 399*38fd1498Szrj } 400*38fd1498Szrj }; 401*38fd1498Szrj 402*38fd1498Szrj // Manage external contained object. 403*38fd1498Szrj template<typename _Tp> 404*38fd1498Szrj struct _Manager_external 405*38fd1498Szrj { 406*38fd1498Szrj static void 407*38fd1498Szrj _S_manage(_Op __which, const any* __anyp, _Arg* __arg); 408*38fd1498Szrj 409*38fd1498Szrj template<typename _Up> 410*38fd1498Szrj static void 411*38fd1498Szrj _S_create(_Storage& __storage, _Up&& __value) 412*38fd1498Szrj { 413*38fd1498Szrj __storage._M_ptr = new _Tp(std::forward<_Up>(__value)); 414*38fd1498Szrj } 415*38fd1498Szrj template<typename... _Args> 416*38fd1498Szrj static void 417*38fd1498Szrj _S_create(_Storage& __storage, _Args&&... __args) 418*38fd1498Szrj { 419*38fd1498Szrj __storage._M_ptr = new _Tp(std::forward<_Args>(__args)...); 420*38fd1498Szrj } 421*38fd1498Szrj }; 422*38fd1498Szrj }; 423*38fd1498Szrj 424*38fd1498Szrj /// Exchange the states of two @c any objects. 425*38fd1498Szrj inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); } 426*38fd1498Szrj 427*38fd1498Szrj /// Create an any holding a @c _Tp constructed from @c __args. 428*38fd1498Szrj template <typename _Tp, typename... _Args> 429*38fd1498Szrj any make_any(_Args&&... __args) 430*38fd1498Szrj { 431*38fd1498Szrj return any(in_place_type<_Tp>, std::forward<_Args>(__args)...); 432*38fd1498Szrj } 433*38fd1498Szrj 434*38fd1498Szrj /// Create an any holding a @c _Tp constructed from @c __il and @c __args. 435*38fd1498Szrj template <typename _Tp, typename _Up, typename... _Args> 436*38fd1498Szrj any make_any(initializer_list<_Up> __il, _Args&&... __args) 437*38fd1498Szrj { 438*38fd1498Szrj return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...); 439*38fd1498Szrj } 440*38fd1498Szrj 441*38fd1498Szrj /** 442*38fd1498Szrj * @brief Access the contained object. 443*38fd1498Szrj * 444*38fd1498Szrj * @tparam _ValueType A const-reference or CopyConstructible type. 445*38fd1498Szrj * @param __any The object to access. 446*38fd1498Szrj * @return The contained object. 447*38fd1498Szrj * @throw bad_any_cast If <code> 448*38fd1498Szrj * __any.type() != typeid(remove_reference_t<_ValueType>) 449*38fd1498Szrj * </code> 450*38fd1498Szrj */ 451*38fd1498Szrj template<typename _ValueType> 452*38fd1498Szrj inline _ValueType any_cast(const any& __any) 453*38fd1498Szrj { 454*38fd1498Szrj using _Up = remove_cv_t<remove_reference_t<_ValueType>>; 455*38fd1498Szrj static_assert(any::__is_valid_cast<_ValueType>(), 456*38fd1498Szrj "Template argument must be a reference or CopyConstructible type"); 457*38fd1498Szrj static_assert(is_constructible_v<_ValueType, const _Up&>, 458*38fd1498Szrj "Template argument must be constructible from a const value."); 459*38fd1498Szrj auto __p = any_cast<_Up>(&__any); 460*38fd1498Szrj if (__p) 461*38fd1498Szrj return static_cast<_ValueType>(*__p); 462*38fd1498Szrj __throw_bad_any_cast(); 463*38fd1498Szrj } 464*38fd1498Szrj 465*38fd1498Szrj /** 466*38fd1498Szrj * @brief Access the contained object. 467*38fd1498Szrj * 468*38fd1498Szrj * @tparam _ValueType A reference or CopyConstructible type. 469*38fd1498Szrj * @param __any The object to access. 470*38fd1498Szrj * @return The contained object. 471*38fd1498Szrj * @throw bad_any_cast If <code> 472*38fd1498Szrj * __any.type() != typeid(remove_reference_t<_ValueType>) 473*38fd1498Szrj * </code> 474*38fd1498Szrj * 475*38fd1498Szrj * @{ 476*38fd1498Szrj */ 477*38fd1498Szrj template<typename _ValueType> 478*38fd1498Szrj inline _ValueType any_cast(any& __any) 479*38fd1498Szrj { 480*38fd1498Szrj using _Up = remove_cv_t<remove_reference_t<_ValueType>>; 481*38fd1498Szrj static_assert(any::__is_valid_cast<_ValueType>(), 482*38fd1498Szrj "Template argument must be a reference or CopyConstructible type"); 483*38fd1498Szrj static_assert(is_constructible_v<_ValueType, _Up&>, 484*38fd1498Szrj "Template argument must be constructible from an lvalue."); 485*38fd1498Szrj auto __p = any_cast<_Up>(&__any); 486*38fd1498Szrj if (__p) 487*38fd1498Szrj return static_cast<_ValueType>(*__p); 488*38fd1498Szrj __throw_bad_any_cast(); 489*38fd1498Szrj } 490*38fd1498Szrj 491*38fd1498Szrj template<typename _ValueType> 492*38fd1498Szrj inline _ValueType any_cast(any&& __any) 493*38fd1498Szrj { 494*38fd1498Szrj using _Up = remove_cv_t<remove_reference_t<_ValueType>>; 495*38fd1498Szrj static_assert(any::__is_valid_cast<_ValueType>(), 496*38fd1498Szrj "Template argument must be a reference or CopyConstructible type"); 497*38fd1498Szrj static_assert(is_constructible_v<_ValueType, _Up>, 498*38fd1498Szrj "Template argument must be constructible from an rvalue."); 499*38fd1498Szrj auto __p = any_cast<_Up>(&__any); 500*38fd1498Szrj if (__p) 501*38fd1498Szrj return static_cast<_ValueType>(std::move(*__p)); 502*38fd1498Szrj __throw_bad_any_cast(); 503*38fd1498Szrj } 504*38fd1498Szrj // @} 505*38fd1498Szrj 506*38fd1498Szrj template<typename _Tp> 507*38fd1498Szrj void* __any_caster(const any* __any) 508*38fd1498Szrj { 509*38fd1498Szrj if constexpr (is_copy_constructible_v<decay_t<_Tp>>) 510*38fd1498Szrj { 511*38fd1498Szrj if (__any->_M_manager == &any::_Manager<decay_t<_Tp>>::_S_manage) 512*38fd1498Szrj { 513*38fd1498Szrj any::_Arg __arg; 514*38fd1498Szrj __any->_M_manager(any::_Op_access, __any, &__arg); 515*38fd1498Szrj return __arg._M_obj; 516*38fd1498Szrj } 517*38fd1498Szrj } 518*38fd1498Szrj return nullptr; 519*38fd1498Szrj } 520*38fd1498Szrj 521*38fd1498Szrj /** 522*38fd1498Szrj * @brief Access the contained object. 523*38fd1498Szrj * 524*38fd1498Szrj * @tparam _ValueType The type of the contained object. 525*38fd1498Szrj * @param __any A pointer to the object to access. 526*38fd1498Szrj * @return The address of the contained object if <code> 527*38fd1498Szrj * __any != nullptr && __any.type() == typeid(_ValueType) 528*38fd1498Szrj * </code>, otherwise a null pointer. 529*38fd1498Szrj * 530*38fd1498Szrj * @{ 531*38fd1498Szrj */ 532*38fd1498Szrj template<typename _ValueType> 533*38fd1498Szrj inline const _ValueType* any_cast(const any* __any) noexcept 534*38fd1498Szrj { 535*38fd1498Szrj if (__any) 536*38fd1498Szrj return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); 537*38fd1498Szrj return nullptr; 538*38fd1498Szrj } 539*38fd1498Szrj 540*38fd1498Szrj template<typename _ValueType> 541*38fd1498Szrj inline _ValueType* any_cast(any* __any) noexcept 542*38fd1498Szrj { 543*38fd1498Szrj if (__any) 544*38fd1498Szrj return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); 545*38fd1498Szrj return nullptr; 546*38fd1498Szrj } 547*38fd1498Szrj // @} 548*38fd1498Szrj 549*38fd1498Szrj template<typename _Tp> 550*38fd1498Szrj void 551*38fd1498Szrj any::_Manager_internal<_Tp>:: 552*38fd1498Szrj _S_manage(_Op __which, const any* __any, _Arg* __arg) 553*38fd1498Szrj { 554*38fd1498Szrj // The contained object is in _M_storage._M_buffer 555*38fd1498Szrj auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer); 556*38fd1498Szrj switch (__which) 557*38fd1498Szrj { 558*38fd1498Szrj case _Op_access: 559*38fd1498Szrj __arg->_M_obj = const_cast<_Tp*>(__ptr); 560*38fd1498Szrj break; 561*38fd1498Szrj case _Op_get_type_info: 562*38fd1498Szrj#if __cpp_rtti 563*38fd1498Szrj __arg->_M_typeinfo = &typeid(_Tp); 564*38fd1498Szrj#endif 565*38fd1498Szrj break; 566*38fd1498Szrj case _Op_clone: 567*38fd1498Szrj ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr); 568*38fd1498Szrj __arg->_M_any->_M_manager = __any->_M_manager; 569*38fd1498Szrj break; 570*38fd1498Szrj case _Op_destroy: 571*38fd1498Szrj __ptr->~_Tp(); 572*38fd1498Szrj break; 573*38fd1498Szrj case _Op_xfer: 574*38fd1498Szrj ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp 575*38fd1498Szrj (std::move(*const_cast<_Tp*>(__ptr))); 576*38fd1498Szrj __ptr->~_Tp(); 577*38fd1498Szrj __arg->_M_any->_M_manager = __any->_M_manager; 578*38fd1498Szrj const_cast<any*>(__any)->_M_manager = nullptr; 579*38fd1498Szrj break; 580*38fd1498Szrj } 581*38fd1498Szrj } 582*38fd1498Szrj 583*38fd1498Szrj template<typename _Tp> 584*38fd1498Szrj void 585*38fd1498Szrj any::_Manager_external<_Tp>:: 586*38fd1498Szrj _S_manage(_Op __which, const any* __any, _Arg* __arg) 587*38fd1498Szrj { 588*38fd1498Szrj // The contained object is *_M_storage._M_ptr 589*38fd1498Szrj auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr); 590*38fd1498Szrj switch (__which) 591*38fd1498Szrj { 592*38fd1498Szrj case _Op_access: 593*38fd1498Szrj __arg->_M_obj = const_cast<_Tp*>(__ptr); 594*38fd1498Szrj break; 595*38fd1498Szrj case _Op_get_type_info: 596*38fd1498Szrj#if __cpp_rtti 597*38fd1498Szrj __arg->_M_typeinfo = &typeid(_Tp); 598*38fd1498Szrj#endif 599*38fd1498Szrj break; 600*38fd1498Szrj case _Op_clone: 601*38fd1498Szrj __arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr); 602*38fd1498Szrj __arg->_M_any->_M_manager = __any->_M_manager; 603*38fd1498Szrj break; 604*38fd1498Szrj case _Op_destroy: 605*38fd1498Szrj delete __ptr; 606*38fd1498Szrj break; 607*38fd1498Szrj case _Op_xfer: 608*38fd1498Szrj __arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr; 609*38fd1498Szrj __arg->_M_any->_M_manager = __any->_M_manager; 610*38fd1498Szrj const_cast<any*>(__any)->_M_manager = nullptr; 611*38fd1498Szrj break; 612*38fd1498Szrj } 613*38fd1498Szrj } 614*38fd1498Szrj 615*38fd1498Szrj /// @} 616*38fd1498Szrj 617*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 618*38fd1498Szrj} // namespace std 619*38fd1498Szrj 620*38fd1498Szrj#endif // C++14 621*38fd1498Szrj 622*38fd1498Szrj#endif // _GLIBCXX_ANY 623