1*38fd1498Szrj// <experimental/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 experimental/any 26*38fd1498Szrj * This is a TS C++ Library header. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj#ifndef _GLIBCXX_EXPERIMENTAL_ANY 30*38fd1498Szrj#define _GLIBCXX_EXPERIMENTAL_ANY 1 31*38fd1498Szrj 32*38fd1498Szrj#pragma GCC system_header 33*38fd1498Szrj 34*38fd1498Szrj#if __cplusplus >= 201402L 35*38fd1498Szrj 36*38fd1498Szrj#include <typeinfo> 37*38fd1498Szrj#include <new> 38*38fd1498Szrj#include <utility> 39*38fd1498Szrj#include <type_traits> 40*38fd1498Szrj#include <experimental/bits/lfts_config.h> 41*38fd1498Szrj 42*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 43*38fd1498Szrj{ 44*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 45*38fd1498Szrj 46*38fd1498Szrjnamespace experimental 47*38fd1498Szrj{ 48*38fd1498Szrjinline namespace fundamentals_v1 49*38fd1498Szrj{ 50*38fd1498Szrj /** 51*38fd1498Szrj * @defgroup any Type-safe container of any type 52*38fd1498Szrj * @ingroup experimental 53*38fd1498Szrj * 54*38fd1498Szrj * A type-safe container for single values of value types, as 55*38fd1498Szrj * described in n3804 "Any Library Proposal (Revision 3)". 56*38fd1498Szrj * 57*38fd1498Szrj * @{ 58*38fd1498Szrj */ 59*38fd1498Szrj 60*38fd1498Szrj#define __cpp_lib_experimental_any 201411 61*38fd1498Szrj 62*38fd1498Szrj /** 63*38fd1498Szrj * @brief Exception class thrown by a failed @c any_cast 64*38fd1498Szrj * @ingroup exceptions 65*38fd1498Szrj */ 66*38fd1498Szrj class bad_any_cast : public bad_cast 67*38fd1498Szrj { 68*38fd1498Szrj public: 69*38fd1498Szrj virtual const char* what() const noexcept { return "bad any_cast"; } 70*38fd1498Szrj }; 71*38fd1498Szrj 72*38fd1498Szrj [[gnu::noreturn]] inline void __throw_bad_any_cast() 73*38fd1498Szrj { 74*38fd1498Szrj#if __cpp_exceptions 75*38fd1498Szrj throw bad_any_cast{}; 76*38fd1498Szrj#else 77*38fd1498Szrj __builtin_abort(); 78*38fd1498Szrj#endif 79*38fd1498Szrj } 80*38fd1498Szrj 81*38fd1498Szrj /** 82*38fd1498Szrj * @brief A type-safe container of any type. 83*38fd1498Szrj * 84*38fd1498Szrj * An @c any object's state is either empty or it stores a contained object 85*38fd1498Szrj * of CopyConstructible type. 86*38fd1498Szrj */ 87*38fd1498Szrj class any 88*38fd1498Szrj { 89*38fd1498Szrj // Holds either pointer to a heap object or the contained object itself. 90*38fd1498Szrj union _Storage 91*38fd1498Szrj { 92*38fd1498Szrj // This constructor intentionally doesn't initialize anything. 93*38fd1498Szrj _Storage() = default; 94*38fd1498Szrj 95*38fd1498Szrj // Prevent trivial copies of this type, buffer might hold a non-POD. 96*38fd1498Szrj _Storage(const _Storage&) = delete; 97*38fd1498Szrj _Storage& operator=(const _Storage&) = delete; 98*38fd1498Szrj 99*38fd1498Szrj void* _M_ptr; 100*38fd1498Szrj aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer; 101*38fd1498Szrj }; 102*38fd1498Szrj 103*38fd1498Szrj template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>, 104*38fd1498Szrj bool _Fits = (sizeof(_Tp) <= sizeof(_Storage)) 105*38fd1498Szrj && (alignof(_Tp) <= alignof(_Storage))> 106*38fd1498Szrj using _Internal = std::integral_constant<bool, _Safe::value && _Fits>; 107*38fd1498Szrj 108*38fd1498Szrj template<typename _Tp> 109*38fd1498Szrj struct _Manager_internal; // uses small-object optimization 110*38fd1498Szrj 111*38fd1498Szrj template<typename _Tp> 112*38fd1498Szrj struct _Manager_external; // creates contained object on the heap 113*38fd1498Szrj 114*38fd1498Szrj template<typename _Tp> 115*38fd1498Szrj using _Manager = conditional_t<_Internal<_Tp>::value, 116*38fd1498Szrj _Manager_internal<_Tp>, 117*38fd1498Szrj _Manager_external<_Tp>>; 118*38fd1498Szrj 119*38fd1498Szrj template<typename _Tp, typename _Decayed = decay_t<_Tp>> 120*38fd1498Szrj using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>; 121*38fd1498Szrj 122*38fd1498Szrj public: 123*38fd1498Szrj // construct/destruct 124*38fd1498Szrj 125*38fd1498Szrj /// Default constructor, creates an empty object. 126*38fd1498Szrj any() noexcept : _M_manager(nullptr) { } 127*38fd1498Szrj 128*38fd1498Szrj /// Copy constructor, copies the state of @p __other 129*38fd1498Szrj any(const any& __other) 130*38fd1498Szrj { 131*38fd1498Szrj if (__other.empty()) 132*38fd1498Szrj _M_manager = nullptr; 133*38fd1498Szrj else 134*38fd1498Szrj { 135*38fd1498Szrj _Arg __arg; 136*38fd1498Szrj __arg._M_any = this; 137*38fd1498Szrj __other._M_manager(_Op_clone, &__other, &__arg); 138*38fd1498Szrj } 139*38fd1498Szrj } 140*38fd1498Szrj 141*38fd1498Szrj /** 142*38fd1498Szrj * @brief Move constructor, transfer the state from @p __other 143*38fd1498Szrj * 144*38fd1498Szrj * @post @c __other.empty() (this postcondition is a GNU extension) 145*38fd1498Szrj */ 146*38fd1498Szrj any(any&& __other) noexcept 147*38fd1498Szrj { 148*38fd1498Szrj if (__other.empty()) 149*38fd1498Szrj _M_manager = nullptr; 150*38fd1498Szrj else 151*38fd1498Szrj { 152*38fd1498Szrj _Arg __arg; 153*38fd1498Szrj __arg._M_any = this; 154*38fd1498Szrj __other._M_manager(_Op_xfer, &__other, &__arg); 155*38fd1498Szrj } 156*38fd1498Szrj } 157*38fd1498Szrj 158*38fd1498Szrj /// Construct with a copy of @p __value as the contained object. 159*38fd1498Szrj template <typename _ValueType, typename _Tp = _Decay<_ValueType>, 160*38fd1498Szrj typename _Mgr = _Manager<_Tp>, 161*38fd1498Szrj typename enable_if<is_constructible<_Tp, _ValueType&&>::value, 162*38fd1498Szrj bool>::type = true> 163*38fd1498Szrj any(_ValueType&& __value) 164*38fd1498Szrj : _M_manager(&_Mgr::_S_manage) 165*38fd1498Szrj { 166*38fd1498Szrj _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value)); 167*38fd1498Szrj static_assert(is_copy_constructible<_Tp>::value, 168*38fd1498Szrj "The contained object must be CopyConstructible"); 169*38fd1498Szrj } 170*38fd1498Szrj 171*38fd1498Szrj /// Construct with a copy of @p __value as the contained object. 172*38fd1498Szrj template <typename _ValueType, typename _Tp = _Decay<_ValueType>, 173*38fd1498Szrj typename _Mgr = _Manager<_Tp>, 174*38fd1498Szrj typename enable_if<!is_constructible<_Tp, _ValueType&&>::value, 175*38fd1498Szrj bool>::type = false> 176*38fd1498Szrj any(_ValueType&& __value) 177*38fd1498Szrj : _M_manager(&_Mgr::_S_manage) 178*38fd1498Szrj { 179*38fd1498Szrj _Mgr::_S_create(_M_storage, __value); 180*38fd1498Szrj static_assert(is_copy_constructible<_Tp>::value, 181*38fd1498Szrj "The contained object must be CopyConstructible"); 182*38fd1498Szrj } 183*38fd1498Szrj 184*38fd1498Szrj /// Destructor, calls @c clear() 185*38fd1498Szrj ~any() { clear(); } 186*38fd1498Szrj 187*38fd1498Szrj // assignments 188*38fd1498Szrj 189*38fd1498Szrj /// Copy the state of another object. 190*38fd1498Szrj any& operator=(const any& __rhs) 191*38fd1498Szrj { 192*38fd1498Szrj *this = any(__rhs); 193*38fd1498Szrj return *this; 194*38fd1498Szrj } 195*38fd1498Szrj 196*38fd1498Szrj /** 197*38fd1498Szrj * @brief Move assignment operator 198*38fd1498Szrj * 199*38fd1498Szrj * @post @c __rhs.empty() (not guaranteed for other implementations) 200*38fd1498Szrj */ 201*38fd1498Szrj any& operator=(any&& __rhs) noexcept 202*38fd1498Szrj { 203*38fd1498Szrj if (__rhs.empty()) 204*38fd1498Szrj clear(); 205*38fd1498Szrj else if (this != &__rhs) 206*38fd1498Szrj { 207*38fd1498Szrj clear(); 208*38fd1498Szrj _Arg __arg; 209*38fd1498Szrj __arg._M_any = this; 210*38fd1498Szrj __rhs._M_manager(_Op_xfer, &__rhs, &__arg); 211*38fd1498Szrj } 212*38fd1498Szrj return *this; 213*38fd1498Szrj } 214*38fd1498Szrj 215*38fd1498Szrj /// Store a copy of @p __rhs as the contained object. 216*38fd1498Szrj template<typename _ValueType> 217*38fd1498Szrj enable_if_t<!is_same<any, decay_t<_ValueType>>::value, any&> 218*38fd1498Szrj operator=(_ValueType&& __rhs) 219*38fd1498Szrj { 220*38fd1498Szrj *this = any(std::forward<_ValueType>(__rhs)); 221*38fd1498Szrj return *this; 222*38fd1498Szrj } 223*38fd1498Szrj 224*38fd1498Szrj // modifiers 225*38fd1498Szrj 226*38fd1498Szrj /// If not empty, destroy the contained object. 227*38fd1498Szrj void clear() noexcept 228*38fd1498Szrj { 229*38fd1498Szrj if (!empty()) 230*38fd1498Szrj { 231*38fd1498Szrj _M_manager(_Op_destroy, this, nullptr); 232*38fd1498Szrj _M_manager = nullptr; 233*38fd1498Szrj } 234*38fd1498Szrj } 235*38fd1498Szrj 236*38fd1498Szrj /// Exchange state with another object. 237*38fd1498Szrj void swap(any& __rhs) noexcept 238*38fd1498Szrj { 239*38fd1498Szrj if (empty() && __rhs.empty()) 240*38fd1498Szrj return; 241*38fd1498Szrj 242*38fd1498Szrj if (!empty() && !__rhs.empty()) 243*38fd1498Szrj { 244*38fd1498Szrj if (this == &__rhs) 245*38fd1498Szrj return; 246*38fd1498Szrj 247*38fd1498Szrj any __tmp; 248*38fd1498Szrj _Arg __arg; 249*38fd1498Szrj __arg._M_any = &__tmp; 250*38fd1498Szrj __rhs._M_manager(_Op_xfer, &__rhs, &__arg); 251*38fd1498Szrj __arg._M_any = &__rhs; 252*38fd1498Szrj _M_manager(_Op_xfer, this, &__arg); 253*38fd1498Szrj __arg._M_any = this; 254*38fd1498Szrj __tmp._M_manager(_Op_xfer, &__tmp, &__arg); 255*38fd1498Szrj } 256*38fd1498Szrj else 257*38fd1498Szrj { 258*38fd1498Szrj any* __empty = empty() ? this : &__rhs; 259*38fd1498Szrj any* __full = empty() ? &__rhs : this; 260*38fd1498Szrj _Arg __arg; 261*38fd1498Szrj __arg._M_any = __empty; 262*38fd1498Szrj __full->_M_manager(_Op_xfer, __full, &__arg); 263*38fd1498Szrj } 264*38fd1498Szrj } 265*38fd1498Szrj 266*38fd1498Szrj // observers 267*38fd1498Szrj 268*38fd1498Szrj /// Reports whether there is a contained object or not. 269*38fd1498Szrj bool empty() const noexcept { return _M_manager == nullptr; } 270*38fd1498Szrj 271*38fd1498Szrj#if __cpp_rtti 272*38fd1498Szrj /// The @c typeid of the contained object, or @c typeid(void) if empty. 273*38fd1498Szrj const type_info& type() const noexcept 274*38fd1498Szrj { 275*38fd1498Szrj if (empty()) 276*38fd1498Szrj return typeid(void); 277*38fd1498Szrj _Arg __arg; 278*38fd1498Szrj _M_manager(_Op_get_type_info, this, &__arg); 279*38fd1498Szrj return *__arg._M_typeinfo; 280*38fd1498Szrj } 281*38fd1498Szrj#endif 282*38fd1498Szrj 283*38fd1498Szrj template<typename _Tp> 284*38fd1498Szrj static constexpr bool __is_valid_cast() 285*38fd1498Szrj { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; } 286*38fd1498Szrj 287*38fd1498Szrj private: 288*38fd1498Szrj enum _Op { 289*38fd1498Szrj _Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer 290*38fd1498Szrj }; 291*38fd1498Szrj 292*38fd1498Szrj union _Arg 293*38fd1498Szrj { 294*38fd1498Szrj void* _M_obj; 295*38fd1498Szrj const std::type_info* _M_typeinfo; 296*38fd1498Szrj any* _M_any; 297*38fd1498Szrj }; 298*38fd1498Szrj 299*38fd1498Szrj void (*_M_manager)(_Op, const any*, _Arg*); 300*38fd1498Szrj _Storage _M_storage; 301*38fd1498Szrj 302*38fd1498Szrj template<typename _Tp> 303*38fd1498Szrj friend void* __any_caster(const any* __any); 304*38fd1498Szrj 305*38fd1498Szrj // Manage in-place contained object. 306*38fd1498Szrj template<typename _Tp> 307*38fd1498Szrj struct _Manager_internal 308*38fd1498Szrj { 309*38fd1498Szrj static void 310*38fd1498Szrj _S_manage(_Op __which, const any* __anyp, _Arg* __arg); 311*38fd1498Szrj 312*38fd1498Szrj template<typename _Up> 313*38fd1498Szrj static void 314*38fd1498Szrj _S_create(_Storage& __storage, _Up&& __value) 315*38fd1498Szrj { 316*38fd1498Szrj void* __addr = &__storage._M_buffer; 317*38fd1498Szrj ::new (__addr) _Tp(std::forward<_Up>(__value)); 318*38fd1498Szrj } 319*38fd1498Szrj }; 320*38fd1498Szrj 321*38fd1498Szrj // Manage external contained object. 322*38fd1498Szrj template<typename _Tp> 323*38fd1498Szrj struct _Manager_external 324*38fd1498Szrj { 325*38fd1498Szrj static void 326*38fd1498Szrj _S_manage(_Op __which, const any* __anyp, _Arg* __arg); 327*38fd1498Szrj 328*38fd1498Szrj template<typename _Up> 329*38fd1498Szrj static void 330*38fd1498Szrj _S_create(_Storage& __storage, _Up&& __value) 331*38fd1498Szrj { 332*38fd1498Szrj __storage._M_ptr = new _Tp(std::forward<_Up>(__value)); 333*38fd1498Szrj } 334*38fd1498Szrj }; 335*38fd1498Szrj }; 336*38fd1498Szrj 337*38fd1498Szrj /// Exchange the states of two @c any objects. 338*38fd1498Szrj inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); } 339*38fd1498Szrj 340*38fd1498Szrj /** 341*38fd1498Szrj * @brief Access the contained object. 342*38fd1498Szrj * 343*38fd1498Szrj * @tparam _ValueType A const-reference or CopyConstructible type. 344*38fd1498Szrj * @param __any The object to access. 345*38fd1498Szrj * @return The contained object. 346*38fd1498Szrj * @throw bad_any_cast If <code> 347*38fd1498Szrj * __any.type() != typeid(remove_reference_t<_ValueType>) 348*38fd1498Szrj * </code> 349*38fd1498Szrj */ 350*38fd1498Szrj template<typename _ValueType> 351*38fd1498Szrj inline _ValueType any_cast(const any& __any) 352*38fd1498Szrj { 353*38fd1498Szrj static_assert(any::__is_valid_cast<_ValueType>(), 354*38fd1498Szrj "Template argument must be a reference or CopyConstructible type"); 355*38fd1498Szrj auto __p = any_cast<add_const_t<remove_reference_t<_ValueType>>>(&__any); 356*38fd1498Szrj if (__p) 357*38fd1498Szrj return *__p; 358*38fd1498Szrj __throw_bad_any_cast(); 359*38fd1498Szrj } 360*38fd1498Szrj 361*38fd1498Szrj /** 362*38fd1498Szrj * @brief Access the contained object. 363*38fd1498Szrj * 364*38fd1498Szrj * @tparam _ValueType A reference or CopyConstructible type. 365*38fd1498Szrj * @param __any The object to access. 366*38fd1498Szrj * @return The contained object. 367*38fd1498Szrj * @throw bad_any_cast If <code> 368*38fd1498Szrj * __any.type() != typeid(remove_reference_t<_ValueType>) 369*38fd1498Szrj * </code> 370*38fd1498Szrj * 371*38fd1498Szrj * @{ 372*38fd1498Szrj */ 373*38fd1498Szrj template<typename _ValueType> 374*38fd1498Szrj inline _ValueType any_cast(any& __any) 375*38fd1498Szrj { 376*38fd1498Szrj static_assert(any::__is_valid_cast<_ValueType>(), 377*38fd1498Szrj "Template argument must be a reference or CopyConstructible type"); 378*38fd1498Szrj auto __p = any_cast<remove_reference_t<_ValueType>>(&__any); 379*38fd1498Szrj if (__p) 380*38fd1498Szrj return *__p; 381*38fd1498Szrj __throw_bad_any_cast(); 382*38fd1498Szrj } 383*38fd1498Szrj 384*38fd1498Szrj template<typename _ValueType, 385*38fd1498Szrj typename enable_if<!is_move_constructible<_ValueType>::value 386*38fd1498Szrj || is_lvalue_reference<_ValueType>::value, 387*38fd1498Szrj bool>::type = true> 388*38fd1498Szrj inline _ValueType any_cast(any&& __any) 389*38fd1498Szrj { 390*38fd1498Szrj static_assert(any::__is_valid_cast<_ValueType>(), 391*38fd1498Szrj "Template argument must be a reference or CopyConstructible type"); 392*38fd1498Szrj auto __p = any_cast<remove_reference_t<_ValueType>>(&__any); 393*38fd1498Szrj if (__p) 394*38fd1498Szrj return *__p; 395*38fd1498Szrj __throw_bad_any_cast(); 396*38fd1498Szrj } 397*38fd1498Szrj 398*38fd1498Szrj template<typename _ValueType, 399*38fd1498Szrj typename enable_if<is_move_constructible<_ValueType>::value 400*38fd1498Szrj && !is_lvalue_reference<_ValueType>::value, 401*38fd1498Szrj bool>::type = false> 402*38fd1498Szrj inline _ValueType any_cast(any&& __any) 403*38fd1498Szrj { 404*38fd1498Szrj static_assert(any::__is_valid_cast<_ValueType>(), 405*38fd1498Szrj "Template argument must be a reference or CopyConstructible type"); 406*38fd1498Szrj auto __p = any_cast<remove_reference_t<_ValueType>>(&__any); 407*38fd1498Szrj if (__p) 408*38fd1498Szrj return std::move(*__p); 409*38fd1498Szrj __throw_bad_any_cast(); 410*38fd1498Szrj } 411*38fd1498Szrj // @} 412*38fd1498Szrj 413*38fd1498Szrj template<typename _Tp> 414*38fd1498Szrj void* __any_caster(const any* __any) 415*38fd1498Szrj { 416*38fd1498Szrj struct _None { }; 417*38fd1498Szrj using _Up = decay_t<_Tp>; 418*38fd1498Szrj using _Vp = conditional_t<is_copy_constructible<_Up>::value, _Up, _None>; 419*38fd1498Szrj if (__any->_M_manager != &any::_Manager<_Vp>::_S_manage) 420*38fd1498Szrj return nullptr; 421*38fd1498Szrj any::_Arg __arg; 422*38fd1498Szrj __any->_M_manager(any::_Op_access, __any, &__arg); 423*38fd1498Szrj return __arg._M_obj; 424*38fd1498Szrj } 425*38fd1498Szrj 426*38fd1498Szrj /** 427*38fd1498Szrj * @brief Access the contained object. 428*38fd1498Szrj * 429*38fd1498Szrj * @tparam _ValueType The type of the contained object. 430*38fd1498Szrj * @param __any A pointer to the object to access. 431*38fd1498Szrj * @return The address of the contained object if <code> 432*38fd1498Szrj * __any != nullptr && __any.type() == typeid(_ValueType) 433*38fd1498Szrj * </code>, otherwise a null pointer. 434*38fd1498Szrj * 435*38fd1498Szrj * @{ 436*38fd1498Szrj */ 437*38fd1498Szrj template<typename _ValueType> 438*38fd1498Szrj inline const _ValueType* any_cast(const any* __any) noexcept 439*38fd1498Szrj { 440*38fd1498Szrj if (__any) 441*38fd1498Szrj return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); 442*38fd1498Szrj return nullptr; 443*38fd1498Szrj } 444*38fd1498Szrj 445*38fd1498Szrj template<typename _ValueType> 446*38fd1498Szrj inline _ValueType* any_cast(any* __any) noexcept 447*38fd1498Szrj { 448*38fd1498Szrj if (__any) 449*38fd1498Szrj return static_cast<_ValueType*>(__any_caster<_ValueType>(__any)); 450*38fd1498Szrj return nullptr; 451*38fd1498Szrj } 452*38fd1498Szrj // @} 453*38fd1498Szrj 454*38fd1498Szrj template<typename _Tp> 455*38fd1498Szrj void 456*38fd1498Szrj any::_Manager_internal<_Tp>:: 457*38fd1498Szrj _S_manage(_Op __which, const any* __any, _Arg* __arg) 458*38fd1498Szrj { 459*38fd1498Szrj // The contained object is in _M_storage._M_buffer 460*38fd1498Szrj auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer); 461*38fd1498Szrj switch (__which) 462*38fd1498Szrj { 463*38fd1498Szrj case _Op_access: 464*38fd1498Szrj __arg->_M_obj = const_cast<_Tp*>(__ptr); 465*38fd1498Szrj break; 466*38fd1498Szrj case _Op_get_type_info: 467*38fd1498Szrj#if __cpp_rtti 468*38fd1498Szrj __arg->_M_typeinfo = &typeid(_Tp); 469*38fd1498Szrj#endif 470*38fd1498Szrj break; 471*38fd1498Szrj case _Op_clone: 472*38fd1498Szrj ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr); 473*38fd1498Szrj __arg->_M_any->_M_manager = __any->_M_manager; 474*38fd1498Szrj break; 475*38fd1498Szrj case _Op_destroy: 476*38fd1498Szrj __ptr->~_Tp(); 477*38fd1498Szrj break; 478*38fd1498Szrj case _Op_xfer: 479*38fd1498Szrj ::new(&__arg->_M_any->_M_storage._M_buffer) _Tp 480*38fd1498Szrj (std::move(*const_cast<_Tp*>(__ptr))); 481*38fd1498Szrj __ptr->~_Tp(); 482*38fd1498Szrj __arg->_M_any->_M_manager = __any->_M_manager; 483*38fd1498Szrj const_cast<any*>(__any)->_M_manager = nullptr; 484*38fd1498Szrj break; 485*38fd1498Szrj } 486*38fd1498Szrj } 487*38fd1498Szrj 488*38fd1498Szrj template<typename _Tp> 489*38fd1498Szrj void 490*38fd1498Szrj any::_Manager_external<_Tp>:: 491*38fd1498Szrj _S_manage(_Op __which, const any* __any, _Arg* __arg) 492*38fd1498Szrj { 493*38fd1498Szrj // The contained object is *_M_storage._M_ptr 494*38fd1498Szrj auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr); 495*38fd1498Szrj switch (__which) 496*38fd1498Szrj { 497*38fd1498Szrj case _Op_access: 498*38fd1498Szrj __arg->_M_obj = const_cast<_Tp*>(__ptr); 499*38fd1498Szrj break; 500*38fd1498Szrj case _Op_get_type_info: 501*38fd1498Szrj#if __cpp_rtti 502*38fd1498Szrj __arg->_M_typeinfo = &typeid(_Tp); 503*38fd1498Szrj#endif 504*38fd1498Szrj break; 505*38fd1498Szrj case _Op_clone: 506*38fd1498Szrj __arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr); 507*38fd1498Szrj __arg->_M_any->_M_manager = __any->_M_manager; 508*38fd1498Szrj break; 509*38fd1498Szrj case _Op_destroy: 510*38fd1498Szrj delete __ptr; 511*38fd1498Szrj break; 512*38fd1498Szrj case _Op_xfer: 513*38fd1498Szrj __arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr; 514*38fd1498Szrj __arg->_M_any->_M_manager = __any->_M_manager; 515*38fd1498Szrj const_cast<any*>(__any)->_M_manager = nullptr; 516*38fd1498Szrj break; 517*38fd1498Szrj } 518*38fd1498Szrj } 519*38fd1498Szrj 520*38fd1498Szrj // @} group any 521*38fd1498Szrj} // namespace fundamentals_v1 522*38fd1498Szrj} // namespace experimental 523*38fd1498Szrj 524*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 525*38fd1498Szrj} // namespace std 526*38fd1498Szrj 527*38fd1498Szrj#endif // C++14 528*38fd1498Szrj 529*38fd1498Szrj#endif // _GLIBCXX_EXPERIMENTAL_ANY 530