mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			607 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			607 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
| // <any> -*- C++ -*-
 | |
| 
 | |
| // Copyright (C) 2014-2016 Free Software Foundation, Inc.
 | |
| //
 | |
| // This file is part of the GNU ISO C++ Library.  This library is free
 | |
| // software; you can redistribute it and/or modify it under the
 | |
| // terms of the GNU General Public License as published by the
 | |
| // Free Software Foundation; either version 3, or (at your option)
 | |
| // any later version.
 | |
| 
 | |
| // This library is distributed in the hope that it will be useful,
 | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| // GNU General Public License for more details.
 | |
| 
 | |
| // Under Section 7 of GPL version 3, you are granted additional
 | |
| // permissions described in the GCC Runtime Library Exception, version
 | |
| // 3.1, as published by the Free Software Foundation.
 | |
| 
 | |
| // You should have received a copy of the GNU General Public License and
 | |
| // a copy of the GCC Runtime Library Exception along with this program;
 | |
| // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 | |
| // <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| /** @file include/any
 | |
|  *  This is a Standard C++ Library header.
 | |
|  */
 | |
| 
 | |
| #ifndef _GLIBCXX_ANY
 | |
| #define _GLIBCXX_ANY 1
 | |
| 
 | |
| #pragma GCC system_header
 | |
| 
 | |
| #if __cplusplus <= 201402L
 | |
| # include <bits/c++17_warning.h>
 | |
| #else
 | |
| 
 | |
| #include <typeinfo>
 | |
| #include <new>
 | |
| #include <utility>
 | |
| #include <type_traits>
 | |
| 
 | |
| namespace std _GLIBCXX_VISIBILITY(default)
 | |
| {
 | |
| _GLIBCXX_BEGIN_NAMESPACE_VERSION
 | |
| 
 | |
|   /**
 | |
|    *  @addtogroup utilities
 | |
|    *  @{
 | |
|    */
 | |
| 
 | |
|   /**
 | |
|    *  @brief Exception class thrown by a failed @c any_cast
 | |
|    *  @ingroup exceptions
 | |
|    */
 | |
|   class bad_any_cast : public bad_cast
 | |
|   {
 | |
|   public:
 | |
|     virtual const char* what() const noexcept { return "bad any_cast"; }
 | |
|   };
 | |
| 
 | |
|   [[gnu::noreturn]] inline void __throw_bad_any_cast()
 | |
|   {
 | |
| #if __cpp_exceptions
 | |
|     throw bad_any_cast{};
 | |
| #else
 | |
|     __builtin_abort();
 | |
| #endif
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    *  @brief A type-safe container of any type.
 | |
|    * 
 | |
|    *  An @c any object's state is either empty or it stores a contained object
 | |
|    *  of CopyConstructible type.
 | |
|    */
 | |
|   class any
 | |
|   {
 | |
|     // Holds either pointer to a heap object or the contained object itself.
 | |
|     union _Storage
 | |
|     {
 | |
|       constexpr _Storage() : _M_ptr{nullptr} {}
 | |
| 
 | |
|       // Prevent trivial copies of this type, buffer might hold a non-POD.
 | |
|       _Storage(const _Storage&) = delete;
 | |
|       _Storage& operator=(const _Storage&) = delete;
 | |
| 
 | |
|       void* _M_ptr;
 | |
|       aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer;
 | |
|     };
 | |
| 
 | |
|     template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>,
 | |
| 	     bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))
 | |
| 			  && (alignof(_Tp) <= alignof(_Storage))>
 | |
|       using _Internal = std::integral_constant<bool, _Safe::value && _Fits>;
 | |
| 
 | |
|     template<typename _Tp>
 | |
|       struct _Manager_internal; // uses small-object optimization
 | |
| 
 | |
|     template<typename _Tp>
 | |
|       struct _Manager_external; // creates contained object on the heap
 | |
| 
 | |
|     template<typename _Tp>
 | |
|       using _Manager = conditional_t<_Internal<_Tp>::value,
 | |
| 				     _Manager_internal<_Tp>,
 | |
| 				     _Manager_external<_Tp>>;
 | |
| 
 | |
|     template<typename _Tp, typename _Decayed = decay_t<_Tp>>
 | |
|       using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>;
 | |
| 
 | |
|   public:
 | |
|     // construct/destruct
 | |
| 
 | |
|     /// Default constructor, creates an empty object.
 | |
|     constexpr any() noexcept : _M_manager(nullptr) { }
 | |
| 
 | |
|     /// Copy constructor, copies the state of @p __other
 | |
|     any(const any& __other)
 | |
|     {
 | |
|       if (!__other.has_value())
 | |
| 	_M_manager = nullptr;
 | |
|       else
 | |
| 	{
 | |
| 	  _Arg __arg;
 | |
| 	  __arg._M_any = this;
 | |
| 	  __other._M_manager(_Op_clone, &__other, &__arg);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @brief Move constructor, transfer the state from @p __other
 | |
|      *
 | |
|      * @post @c !__other.has_value() (this postcondition is a GNU extension)
 | |
|      */
 | |
|     any(any&& __other) noexcept
 | |
|     {
 | |
|       if (!__other.has_value())
 | |
| 	_M_manager = nullptr;
 | |
|       else
 | |
| 	{
 | |
| 	  _Arg __arg;
 | |
| 	  __arg._M_any = this;
 | |
| 	  __other._M_manager(_Op_xfer, &__other, &__arg);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     template <typename _Tp, typename... _Args>
 | |
|     using __any_constructible_t =
 | |
|       enable_if_t<__and_<is_copy_constructible<_Tp>,
 | |
| 			 is_constructible<_Tp, _Args...>>::value,
 | |
| 		  bool>;
 | |
| 
 | |
|     /// Construct with a copy of @p __value as the contained object.
 | |
|     template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
 | |
| 	      typename _Mgr = _Manager<_Tp>,
 | |
|               __any_constructible_t<_Tp, _ValueType&&> = true,
 | |
| 	      enable_if_t<!__is_in_place_type<_ValueType>::value, bool> = true>
 | |
|       any(_ValueType&& __value)
 | |
|       : _M_manager(&_Mgr::_S_manage)
 | |
|       {
 | |
|         _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value));
 | |
|       }
 | |
| 
 | |
|     /// Construct with a copy of @p __value as the contained object.
 | |
|     template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
 | |
| 	      typename _Mgr = _Manager<_Tp>,
 | |
|               enable_if_t<__and_<is_copy_constructible<_Tp>,
 | |
| 				 __not_<is_constructible<_Tp, _ValueType&&>>,
 | |
| 			         __not_<__is_in_place_type<_ValueType>>>::value,
 | |
| 			  bool> = false>
 | |
|       any(_ValueType&& __value)
 | |
|       : _M_manager(&_Mgr::_S_manage)
 | |
|       {
 | |
|         _Mgr::_S_create(_M_storage, __value);
 | |
|       }
 | |
| 
 | |
|     /// Construct with an object created from @p __args as the contained object.
 | |
|     template <typename _ValueType, typename... _Args,
 | |
| 	      typename _Tp = _Decay<_ValueType>,
 | |
| 	      typename _Mgr = _Manager<_Tp>,
 | |
|               __any_constructible_t<_Tp, _Args&&...> = false>
 | |
|       any(in_place_type_t<_ValueType>, _Args&&... __args)
 | |
|       : _M_manager(&_Mgr::_S_manage)
 | |
|       {
 | |
|         _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
 | |
|       }
 | |
| 
 | |
|     /// Construct with an object created from @p __il and @p __args as
 | |
|     /// the contained object.
 | |
|     template <typename _ValueType, typename _Up, typename... _Args,
 | |
| 	      typename _Tp = _Decay<_ValueType>,
 | |
| 	      typename _Mgr = _Manager<_Tp>,
 | |
|               __any_constructible_t<_Tp, initializer_list<_Up>,
 | |
| 				    _Args&&...> = false>
 | |
|       any(in_place_type_t<_ValueType>,
 | |
| 	  initializer_list<_Up> __il, _Args&&... __args)
 | |
|       : _M_manager(&_Mgr::_S_manage)
 | |
|       {
 | |
|         _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
 | |
|       }
 | |
| 
 | |
|     /// Destructor, calls @c reset()
 | |
|     ~any() { reset(); }
 | |
| 
 | |
|     // assignments
 | |
| 
 | |
|     /// Copy the state of another object.
 | |
|     any& operator=(const any& __rhs)
 | |
|     {
 | |
|       if (!__rhs.has_value())
 | |
| 	reset();
 | |
|       else if (this != &__rhs)
 | |
| 	{
 | |
| 	  if (has_value())
 | |
| 	    _M_manager(_Op_destroy, this, nullptr);
 | |
| 	  _Arg __arg;
 | |
| 	  __arg._M_any = this;
 | |
| 	  __rhs._M_manager(_Op_clone, &__rhs, &__arg);
 | |
| 	}
 | |
|       return *this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @brief Move assignment operator
 | |
|      *
 | |
|      * @post @c !__rhs.has_value() (not guaranteed for other implementations)
 | |
|      */
 | |
|     any& operator=(any&& __rhs) noexcept
 | |
|     {
 | |
|       if (!__rhs.has_value())
 | |
| 	reset();
 | |
|       else if (this != &__rhs)
 | |
| 	{
 | |
| 	  if (has_value())
 | |
| 	    _M_manager(_Op_destroy, this, nullptr);
 | |
| 	  _Arg __arg;
 | |
| 	  __arg._M_any = this;
 | |
| 	  __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
 | |
| 	}
 | |
|       return *this;
 | |
|     }
 | |
| 
 | |
|     /// Store a copy of @p __rhs as the contained object.
 | |
|     template<typename _ValueType,
 | |
| 	     typename _Tp = _Decay<_ValueType>>
 | |
|     enable_if_t<is_copy_constructible<_Tp>::value, any&>
 | |
|       operator=(_ValueType&& __rhs)
 | |
|       {
 | |
| 	*this = any(std::forward<_ValueType>(__rhs));
 | |
| 	return *this;
 | |
|       }
 | |
| 
 | |
|     /// Emplace with an object created from @p __args as the contained object.
 | |
|     template <typename _ValueType, typename... _Args,
 | |
| 	      typename _Tp = _Decay<_ValueType>,
 | |
| 	      typename _Mgr = _Manager<_Tp>,
 | |
|               __any_constructible_t<_Tp, _Args&&...> = false>
 | |
|       void emplace(_Args&&... __args)
 | |
|       {
 | |
| 	reset();
 | |
| 	_M_manager = &_Mgr::_S_manage;
 | |
|         _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
 | |
|       }
 | |
| 
 | |
|     /// Emplace with an object created from @p __il and @p __args as
 | |
|     /// the contained object.
 | |
|     template <typename _ValueType, typename _Up, typename... _Args,
 | |
| 	      typename _Tp = _Decay<_ValueType>,
 | |
| 	      typename _Mgr = _Manager<_Tp>,
 | |
|               __any_constructible_t<_Tp, initializer_list<_Up>,
 | |
| 				    _Args&&...> = false>
 | |
|       void emplace(initializer_list<_Up> __il, _Args&&... __args)
 | |
|       {
 | |
| 	reset();
 | |
| 	_M_manager = &_Mgr::_S_manage;
 | |
|         _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
 | |
|       }
 | |
| 
 | |
|     // modifiers
 | |
| 
 | |
|     /// If not empty, destroy the contained object.
 | |
|     void reset() noexcept
 | |
|     {
 | |
|       if (has_value())
 | |
|       {
 | |
| 	_M_manager(_Op_destroy, this, nullptr);
 | |
| 	_M_manager = nullptr;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     /// Exchange state with another object.
 | |
|     void swap(any& __rhs) noexcept
 | |
|     {
 | |
|       if (!has_value() && !__rhs.has_value())
 | |
| 	return;
 | |
| 
 | |
|       if (has_value() && __rhs.has_value())
 | |
| 	{
 | |
| 	  if (this == &__rhs)
 | |
| 	    return;
 | |
| 
 | |
| 	  any __tmp;
 | |
| 	  _Arg __arg;
 | |
| 	  __arg._M_any = &__tmp;
 | |
| 	  __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
 | |
| 	  __arg._M_any = &__rhs;
 | |
| 	  _M_manager(_Op_xfer, this, &__arg);
 | |
| 	  __arg._M_any = this;
 | |
| 	  __tmp._M_manager(_Op_xfer, &__tmp, &__arg);
 | |
| 	}
 | |
|       else
 | |
| 	{
 | |
| 	  any* __empty = !has_value() ? this : &__rhs;
 | |
| 	  any* __full = !has_value() ? &__rhs : this;
 | |
| 	  _Arg __arg;
 | |
| 	  __arg._M_any = __empty;
 | |
| 	  __full->_M_manager(_Op_xfer, __full, &__arg);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     // observers
 | |
| 
 | |
|     /// Reports whether there is a contained object or not.
 | |
|     bool has_value() const noexcept { return _M_manager != nullptr; }
 | |
| 
 | |
| #if __cpp_rtti
 | |
|     /// The @c typeid of the contained object, or @c typeid(void) if empty.
 | |
|     const type_info& type() const noexcept
 | |
|     {
 | |
|       if (!has_value())
 | |
| 	return typeid(void);
 | |
|       _Arg __arg;
 | |
|       _M_manager(_Op_get_type_info, this, &__arg);
 | |
|       return *__arg._M_typeinfo;
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|     template<typename _Tp>
 | |
|       static constexpr bool __is_valid_cast()
 | |
|       { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
 | |
| 
 | |
|   private:
 | |
|     enum _Op {
 | |
| 	_Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer
 | |
|     };
 | |
| 
 | |
|     union _Arg
 | |
|     {
 | |
| 	void* _M_obj;
 | |
| 	const std::type_info* _M_typeinfo;
 | |
| 	any* _M_any;
 | |
|     };
 | |
| 
 | |
|     void (*_M_manager)(_Op, const any*, _Arg*);
 | |
|     _Storage _M_storage;
 | |
| 
 | |
|     template<typename _Tp>
 | |
|       friend void* __any_caster(const any* __any);
 | |
| 
 | |
|     // Manage in-place contained object.
 | |
|     template<typename _Tp>
 | |
|       struct _Manager_internal
 | |
|       {
 | |
| 	static void
 | |
| 	_S_manage(_Op __which, const any* __anyp, _Arg* __arg);
 | |
| 
 | |
| 	template<typename _Up>
 | |
| 	  static void
 | |
| 	  _S_create(_Storage& __storage, _Up&& __value)
 | |
| 	  {
 | |
| 	    void* __addr = &__storage._M_buffer;
 | |
| 	    ::new (__addr) _Tp(std::forward<_Up>(__value));
 | |
| 	  }
 | |
| 
 | |
| 	template<typename... _Args>
 | |
| 	  static void
 | |
| 	  _S_create(_Storage& __storage, _Args&&... __args)
 | |
| 	  {
 | |
| 	    void* __addr = &__storage._M_buffer;
 | |
| 	    ::new (__addr) _Tp(std::forward<_Args>(__args)...);
 | |
| 	  }
 | |
|       };
 | |
| 
 | |
|     // Manage external contained object.
 | |
|     template<typename _Tp>
 | |
|       struct _Manager_external
 | |
|       {
 | |
| 	static void
 | |
| 	_S_manage(_Op __which, const any* __anyp, _Arg* __arg);
 | |
| 
 | |
| 	template<typename _Up>
 | |
| 	  static void
 | |
| 	  _S_create(_Storage& __storage, _Up&& __value)
 | |
| 	  {
 | |
| 	    __storage._M_ptr = new _Tp(std::forward<_Up>(__value));
 | |
| 	  }
 | |
| 	template<typename... _Args>
 | |
| 	  static void
 | |
| 	  _S_create(_Storage& __storage, _Args&&... __args)
 | |
| 	  {
 | |
| 	    __storage._M_ptr = new _Tp(std::forward<_Args>(__args)...);
 | |
| 	  }
 | |
|       };
 | |
|   };
 | |
| 
 | |
|   /// Exchange the states of two @c any objects.
 | |
|   inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); }
 | |
| 
 | |
|   /// Create an any holding a @c _Tp constructed from @c __args.
 | |
|   template <typename _Tp, typename... _Args>
 | |
|     any make_any(_Args&&... __args)
 | |
|     {
 | |
|       return any(in_place<_Tp>, std::forward<_Args>(__args)...);
 | |
|     }
 | |
| 
 | |
|   /// Create an any holding a @c _Tp constructed from @c __il and @c __args.
 | |
|   template <typename _Tp, typename _Up, typename... _Args>
 | |
|     any make_any(initializer_list<_Up> __il, _Args&&... __args)
 | |
|     {
 | |
|       return any(in_place<_Tp>, __il, std::forward<_Args>(__args)...);
 | |
|     }
 | |
| 
 | |
|   /**
 | |
|    * @brief Access the contained object.
 | |
|    *
 | |
|    * @tparam  _ValueType  A const-reference or CopyConstructible type.
 | |
|    * @param   __any       The object to access.
 | |
|    * @return  The contained object.
 | |
|    * @throw   bad_any_cast If <code>
 | |
|    *          __any.type() != typeid(remove_reference_t<_ValueType>)
 | |
|    *          </code>
 | |
|    */
 | |
|   template<typename _ValueType>
 | |
|     inline _ValueType any_cast(const any& __any)
 | |
|     {
 | |
|       static_assert(any::__is_valid_cast<_ValueType>(),
 | |
| 	  "Template argument must be a reference or CopyConstructible type");
 | |
|       auto __p = any_cast<add_const_t<remove_reference_t<_ValueType>>>(&__any);
 | |
|       if (__p)
 | |
| 	return *__p;
 | |
|       __throw_bad_any_cast();
 | |
|     }
 | |
| 
 | |
|   /**
 | |
|    * @brief Access the contained object.
 | |
|    *
 | |
|    * @tparam  _ValueType  A reference or CopyConstructible type.
 | |
|    * @param   __any       The object to access.
 | |
|    * @return  The contained object.
 | |
|    * @throw   bad_any_cast If <code>
 | |
|    *          __any.type() != typeid(remove_reference_t<_ValueType>)
 | |
|    *          </code>
 | |
|    *
 | |
|    * @{
 | |
|    */
 | |
|   template<typename _ValueType>
 | |
|     inline _ValueType any_cast(any& __any)
 | |
|     {
 | |
|       static_assert(any::__is_valid_cast<_ValueType>(),
 | |
| 	  "Template argument must be a reference or CopyConstructible type");
 | |
|       auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
 | |
|       if (__p)
 | |
| 	return *__p;
 | |
|       __throw_bad_any_cast();
 | |
|     }
 | |
| 
 | |
|   template<typename _ValueType,
 | |
|            typename enable_if<!is_move_constructible<_ValueType>::value
 | |
|                               || is_lvalue_reference<_ValueType>::value,
 | |
|                               bool>::type = true>
 | |
|     inline _ValueType any_cast(any&& __any)
 | |
|     {
 | |
|       static_assert(any::__is_valid_cast<_ValueType>(),
 | |
| 	  "Template argument must be a reference or CopyConstructible type");
 | |
|       auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
 | |
|       if (__p)
 | |
| 	return *__p;
 | |
|       __throw_bad_any_cast();
 | |
|     }
 | |
| 
 | |
|   template<typename _ValueType,
 | |
|            typename enable_if<is_move_constructible<_ValueType>::value
 | |
|                               && !is_lvalue_reference<_ValueType>::value,
 | |
|                               bool>::type = false>
 | |
|     inline _ValueType any_cast(any&& __any)
 | |
|     {
 | |
|       static_assert(any::__is_valid_cast<_ValueType>(),
 | |
| 	  "Template argument must be a reference or CopyConstructible type");
 | |
|       auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
 | |
|       if (__p)
 | |
| 	return std::move(*__p);
 | |
|       __throw_bad_any_cast();
 | |
|     }
 | |
|   // @}
 | |
| 
 | |
|   template<typename _Tp>
 | |
|     void* __any_caster(const any* __any)
 | |
|     {
 | |
|       if (__any->_M_manager != &any::_Manager<decay_t<_Tp>>::_S_manage)
 | |
| 	return nullptr;
 | |
|       any::_Arg __arg;
 | |
|       __any->_M_manager(any::_Op_access, __any, &__arg);
 | |
|       return __arg._M_obj;
 | |
|     }
 | |
| 
 | |
|   /**
 | |
|    * @brief Access the contained object.
 | |
|    *
 | |
|    * @tparam  _ValueType  The type of the contained object.
 | |
|    * @param   __any       A pointer to the object to access.
 | |
|    * @return  The address of the contained object if <code>
 | |
|    *          __any != nullptr && __any.type() == typeid(_ValueType)
 | |
|    *          </code>, otherwise a null pointer.
 | |
|    *
 | |
|    * @{
 | |
|    */
 | |
|   template<typename _ValueType>
 | |
|     inline const _ValueType* any_cast(const any* __any) noexcept
 | |
|     {
 | |
|       if (__any)
 | |
| 	return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
 | |
|       return nullptr;
 | |
|     }
 | |
| 
 | |
|   template<typename _ValueType>
 | |
|     inline _ValueType* any_cast(any* __any) noexcept
 | |
|     {
 | |
|       if (__any)
 | |
| 	return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
 | |
|       return nullptr;
 | |
|     }
 | |
|   // @}
 | |
| 
 | |
|   template<typename _Tp>
 | |
|     void
 | |
|     any::_Manager_internal<_Tp>::
 | |
|     _S_manage(_Op __which, const any* __any, _Arg* __arg)
 | |
|     {
 | |
|       // The contained object is in _M_storage._M_buffer
 | |
|       auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer);
 | |
|       switch (__which)
 | |
|       {
 | |
|       case _Op_access:
 | |
| 	__arg->_M_obj = const_cast<_Tp*>(__ptr);
 | |
| 	break;
 | |
|       case _Op_get_type_info:
 | |
| #if __cpp_rtti
 | |
| 	__arg->_M_typeinfo = &typeid(_Tp);
 | |
| #endif
 | |
| 	break;
 | |
|       case _Op_clone:
 | |
| 	::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
 | |
| 	__arg->_M_any->_M_manager = __any->_M_manager;
 | |
| 	break;
 | |
|       case _Op_destroy:
 | |
| 	__ptr->~_Tp();
 | |
| 	break;
 | |
|       case _Op_xfer:
 | |
| 	::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
 | |
| 	__ptr->~_Tp();
 | |
| 	__arg->_M_any->_M_manager = __any->_M_manager;
 | |
| 	const_cast<any*>(__any)->_M_manager = nullptr;
 | |
| 	break;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|   template<typename _Tp>
 | |
|     void
 | |
|     any::_Manager_external<_Tp>::
 | |
|     _S_manage(_Op __which, const any* __any, _Arg* __arg)
 | |
|     {
 | |
|       // The contained object is *_M_storage._M_ptr
 | |
|       auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr);
 | |
|       switch (__which)
 | |
|       {
 | |
|       case _Op_access:
 | |
| 	__arg->_M_obj = const_cast<_Tp*>(__ptr);
 | |
| 	break;
 | |
|       case _Op_get_type_info:
 | |
| #if __cpp_rtti
 | |
| 	__arg->_M_typeinfo = &typeid(_Tp);
 | |
| #endif
 | |
| 	break;
 | |
|       case _Op_clone:
 | |
| 	__arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr);
 | |
| 	__arg->_M_any->_M_manager = __any->_M_manager;
 | |
| 	break;
 | |
|       case _Op_destroy:
 | |
| 	delete __ptr;
 | |
| 	break;
 | |
|       case _Op_xfer:
 | |
| 	__arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr;
 | |
| 	__arg->_M_any->_M_manager = __any->_M_manager;
 | |
| 	const_cast<any*>(__any)->_M_manager = nullptr;
 | |
| 	break;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|   /// @}
 | |
|   
 | |
| _GLIBCXX_END_NAMESPACE_VERSION
 | |
| } // namespace std
 | |
| 
 | |
| #endif // C++14
 | |
| 
 | |
| #endif // _GLIBCXX_ANY
 |