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