xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/std/any (revision 4ac76180e904e771b9d522c7e57296d371f06499)
13ad841b2Smrg// <any> -*- C++ -*-
23ad841b2Smrg
34c3eb207Smrg// Copyright (C) 2014-2020 Free Software Foundation, Inc.
43ad841b2Smrg//
53ad841b2Smrg// This file is part of the GNU ISO C++ Library.  This library is free
63ad841b2Smrg// software; you can redistribute it and/or modify it under the
73ad841b2Smrg// terms of the GNU General Public License as published by the
83ad841b2Smrg// Free Software Foundation; either version 3, or (at your option)
93ad841b2Smrg// any later version.
103ad841b2Smrg
113ad841b2Smrg// This library is distributed in the hope that it will be useful,
123ad841b2Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
133ad841b2Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
143ad841b2Smrg// GNU General Public License for more details.
153ad841b2Smrg
163ad841b2Smrg// Under Section 7 of GPL version 3, you are granted additional
173ad841b2Smrg// permissions described in the GCC Runtime Library Exception, version
183ad841b2Smrg// 3.1, as published by the Free Software Foundation.
193ad841b2Smrg
203ad841b2Smrg// You should have received a copy of the GNU General Public License and
213ad841b2Smrg// a copy of the GCC Runtime Library Exception along with this program;
223ad841b2Smrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
233ad841b2Smrg// <http://www.gnu.org/licenses/>.
243ad841b2Smrg
253ad841b2Smrg/** @file include/any
263ad841b2Smrg *  This is a Standard C++ Library header.
273ad841b2Smrg */
283ad841b2Smrg
293ad841b2Smrg#ifndef _GLIBCXX_ANY
303ad841b2Smrg#define _GLIBCXX_ANY 1
313ad841b2Smrg
323ad841b2Smrg#pragma GCC system_header
333ad841b2Smrg
343ad841b2Smrg#if __cplusplus >= 201703L
353ad841b2Smrg
363ad841b2Smrg#include <typeinfo>
373ad841b2Smrg#include <new>
383ad841b2Smrg#include <utility>
393ad841b2Smrg#include <type_traits>
403ad841b2Smrg
413ad841b2Smrgnamespace std _GLIBCXX_VISIBILITY(default)
423ad841b2Smrg{
433ad841b2Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
443ad841b2Smrg
453ad841b2Smrg  /**
463ad841b2Smrg   *  @addtogroup utilities
473ad841b2Smrg   *  @{
483ad841b2Smrg   */
493ad841b2Smrg
503ad841b2Smrg  /**
513ad841b2Smrg   *  @brief Exception class thrown by a failed @c any_cast
523ad841b2Smrg   *  @ingroup exceptions
533ad841b2Smrg   */
543ad841b2Smrg  class bad_any_cast : public bad_cast
553ad841b2Smrg  {
563ad841b2Smrg  public:
573ad841b2Smrg    virtual const char* what() const noexcept { return "bad any_cast"; }
583ad841b2Smrg  };
593ad841b2Smrg
603ad841b2Smrg  [[gnu::noreturn]] inline void __throw_bad_any_cast()
613ad841b2Smrg  {
623ad841b2Smrg#if __cpp_exceptions
633ad841b2Smrg    throw bad_any_cast{};
643ad841b2Smrg#else
653ad841b2Smrg    __builtin_abort();
663ad841b2Smrg#endif
673ad841b2Smrg  }
683ad841b2Smrg
69cef8759bSmrg#define __cpp_lib_any 201606L
703ad841b2Smrg
713ad841b2Smrg  /**
723ad841b2Smrg   *  @brief A type-safe container of any type.
733ad841b2Smrg   *
743ad841b2Smrg   *  An @c any object's state is either empty or it stores a contained object
753ad841b2Smrg   *  of CopyConstructible type.
763ad841b2Smrg   */
773ad841b2Smrg  class any
783ad841b2Smrg  {
793ad841b2Smrg    // Holds either pointer to a heap object or the contained object itself.
803ad841b2Smrg    union _Storage
813ad841b2Smrg    {
823ad841b2Smrg      constexpr _Storage() : _M_ptr{nullptr} {}
833ad841b2Smrg
843ad841b2Smrg      // Prevent trivial copies of this type, buffer might hold a non-POD.
853ad841b2Smrg      _Storage(const _Storage&) = delete;
863ad841b2Smrg      _Storage& operator=(const _Storage&) = delete;
873ad841b2Smrg
883ad841b2Smrg      void* _M_ptr;
893ad841b2Smrg      aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer;
903ad841b2Smrg    };
913ad841b2Smrg
923ad841b2Smrg    template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>,
933ad841b2Smrg	     bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))
943ad841b2Smrg			  && (alignof(_Tp) <= alignof(_Storage))>
953ad841b2Smrg      using _Internal = std::integral_constant<bool, _Safe::value && _Fits>;
963ad841b2Smrg
973ad841b2Smrg    template<typename _Tp>
983ad841b2Smrg      struct _Manager_internal; // uses small-object optimization
993ad841b2Smrg
1003ad841b2Smrg    template<typename _Tp>
1013ad841b2Smrg      struct _Manager_external; // creates contained object on the heap
1023ad841b2Smrg
1033ad841b2Smrg    template<typename _Tp>
1043ad841b2Smrg      using _Manager = conditional_t<_Internal<_Tp>::value,
1053ad841b2Smrg				     _Manager_internal<_Tp>,
1063ad841b2Smrg				     _Manager_external<_Tp>>;
1073ad841b2Smrg
1084c3eb207Smrg    template<typename _Tp, typename _VTp = decay_t<_Tp>>
1094c3eb207Smrg      using _Decay_if_not_any = enable_if_t<!is_same_v<_VTp, any>, _VTp>;
1103ad841b2Smrg
1113ad841b2Smrg    /// Emplace with an object created from @p __args as the contained object.
1123ad841b2Smrg    template <typename _Tp, typename... _Args,
1133ad841b2Smrg	      typename _Mgr = _Manager<_Tp>>
1143ad841b2Smrg      void __do_emplace(_Args&&... __args)
1153ad841b2Smrg      {
1163ad841b2Smrg	reset();
1173ad841b2Smrg        _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
1183ad841b2Smrg	_M_manager = &_Mgr::_S_manage;
1193ad841b2Smrg      }
1203ad841b2Smrg
1213ad841b2Smrg    /// Emplace with an object created from @p __il and @p __args as
1223ad841b2Smrg    /// the contained object.
1233ad841b2Smrg    template <typename _Tp, typename _Up, typename... _Args,
1243ad841b2Smrg	      typename _Mgr = _Manager<_Tp>>
1253ad841b2Smrg      void __do_emplace(initializer_list<_Up> __il, _Args&&... __args)
1263ad841b2Smrg      {
1273ad841b2Smrg	reset();
1283ad841b2Smrg	_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
1293ad841b2Smrg	_M_manager = &_Mgr::_S_manage;
1303ad841b2Smrg      }
1313ad841b2Smrg
1324c3eb207Smrg    template <typename _Res, typename _Tp, typename... _Args>
1334c3eb207Smrg      using __any_constructible
1344c3eb207Smrg	= enable_if<__and_<is_copy_constructible<_Tp>,
1354c3eb207Smrg			   is_constructible<_Tp, _Args...>>::value,
1364c3eb207Smrg		    _Res>;
1374c3eb207Smrg
1384c3eb207Smrg    template <typename _Tp, typename... _Args>
1394c3eb207Smrg      using __any_constructible_t
1404c3eb207Smrg	= typename __any_constructible<bool, _Tp, _Args...>::type;
1414c3eb207Smrg
1424c3eb207Smrg    template<typename _VTp, typename... _Args>
1434c3eb207Smrg      using __emplace_t
1444c3eb207Smrg	= typename __any_constructible<_VTp&, _VTp, _Args...>::type;
1454c3eb207Smrg
1463ad841b2Smrg  public:
1473ad841b2Smrg    // construct/destruct
1483ad841b2Smrg
1493ad841b2Smrg    /// Default constructor, creates an empty object.
1503ad841b2Smrg    constexpr any() noexcept : _M_manager(nullptr) { }
1513ad841b2Smrg
1523ad841b2Smrg    /// Copy constructor, copies the state of @p __other
1533ad841b2Smrg    any(const any& __other)
1543ad841b2Smrg    {
1553ad841b2Smrg      if (!__other.has_value())
1563ad841b2Smrg	_M_manager = nullptr;
1573ad841b2Smrg      else
1583ad841b2Smrg	{
1593ad841b2Smrg	  _Arg __arg;
1603ad841b2Smrg	  __arg._M_any = this;
1613ad841b2Smrg	  __other._M_manager(_Op_clone, &__other, &__arg);
1623ad841b2Smrg	}
1633ad841b2Smrg    }
1643ad841b2Smrg
1653ad841b2Smrg    /**
1663ad841b2Smrg     * @brief Move constructor, transfer the state from @p __other
1673ad841b2Smrg     *
1683ad841b2Smrg     * @post @c !__other.has_value() (this postcondition is a GNU extension)
1693ad841b2Smrg     */
1703ad841b2Smrg    any(any&& __other) noexcept
1713ad841b2Smrg    {
1723ad841b2Smrg      if (!__other.has_value())
1733ad841b2Smrg	_M_manager = nullptr;
1743ad841b2Smrg      else
1753ad841b2Smrg	{
1763ad841b2Smrg	  _Arg __arg;
1773ad841b2Smrg	  __arg._M_any = this;
1783ad841b2Smrg	  __other._M_manager(_Op_xfer, &__other, &__arg);
1793ad841b2Smrg	}
1803ad841b2Smrg    }
1813ad841b2Smrg
1823ad841b2Smrg    /// Construct with a copy of @p __value as the contained object.
1834c3eb207Smrg    template <typename _Tp, typename _VTp = _Decay_if_not_any<_Tp>,
1844c3eb207Smrg	      typename _Mgr = _Manager<_VTp>,
1854c3eb207Smrg	      enable_if_t<is_copy_constructible<_VTp>::value
1864c3eb207Smrg			  && !__is_in_place_type<_VTp>::value, bool> = true>
1874c3eb207Smrg      any(_Tp&& __value)
1883ad841b2Smrg      : _M_manager(&_Mgr::_S_manage)
1893ad841b2Smrg      {
1904c3eb207Smrg	_Mgr::_S_create(_M_storage, std::forward<_Tp>(__value));
1913ad841b2Smrg      }
1923ad841b2Smrg
1933ad841b2Smrg    /// Construct with an object created from @p __args as the contained object.
1944c3eb207Smrg    template <typename _Tp, typename... _Args, typename _VTp = decay_t<_Tp>,
1954c3eb207Smrg	      typename _Mgr = _Manager<_VTp>,
1964c3eb207Smrg	      __any_constructible_t<_VTp, _Args&&...> = false>
1973ad841b2Smrg      explicit
1984c3eb207Smrg      any(in_place_type_t<_Tp>, _Args&&... __args)
1993ad841b2Smrg      : _M_manager(&_Mgr::_S_manage)
2003ad841b2Smrg      {
2013ad841b2Smrg	_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
2023ad841b2Smrg      }
2033ad841b2Smrg
2043ad841b2Smrg    /// Construct with an object created from @p __il and @p __args as
2053ad841b2Smrg    /// the contained object.
2064c3eb207Smrg    template <typename _Tp, typename _Up, typename... _Args,
2074c3eb207Smrg	      typename _VTp = decay_t<_Tp>, typename _Mgr = _Manager<_VTp>,
2084c3eb207Smrg	      __any_constructible_t<_VTp, initializer_list<_Up>&,
2093ad841b2Smrg				    _Args&&...> = false>
2103ad841b2Smrg      explicit
2114c3eb207Smrg      any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args)
2123ad841b2Smrg      : _M_manager(&_Mgr::_S_manage)
2133ad841b2Smrg      {
2143ad841b2Smrg	_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
2153ad841b2Smrg      }
2163ad841b2Smrg
2173ad841b2Smrg    /// Destructor, calls @c reset()
2183ad841b2Smrg    ~any() { reset(); }
2193ad841b2Smrg
2203ad841b2Smrg    // assignments
2213ad841b2Smrg
2223ad841b2Smrg    /// Copy the state of another object.
2234c3eb207Smrg    any&
2244c3eb207Smrg    operator=(const any& __rhs)
2253ad841b2Smrg    {
2263ad841b2Smrg      *this = any(__rhs);
2273ad841b2Smrg      return *this;
2283ad841b2Smrg    }
2293ad841b2Smrg
2303ad841b2Smrg    /**
2313ad841b2Smrg     * @brief Move assignment operator
2323ad841b2Smrg     *
2333ad841b2Smrg     * @post @c !__rhs.has_value() (not guaranteed for other implementations)
2343ad841b2Smrg     */
2354c3eb207Smrg    any&
2364c3eb207Smrg    operator=(any&& __rhs) noexcept
2373ad841b2Smrg    {
2383ad841b2Smrg      if (!__rhs.has_value())
2393ad841b2Smrg	reset();
2403ad841b2Smrg      else if (this != &__rhs)
2413ad841b2Smrg	{
2423ad841b2Smrg	  reset();
2433ad841b2Smrg	  _Arg __arg;
2443ad841b2Smrg	  __arg._M_any = this;
2453ad841b2Smrg	  __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
2463ad841b2Smrg	}
2473ad841b2Smrg      return *this;
2483ad841b2Smrg    }
2493ad841b2Smrg
2503ad841b2Smrg    /// Store a copy of @p __rhs as the contained object.
2514c3eb207Smrg    template<typename _Tp>
2524c3eb207Smrg      enable_if_t<is_copy_constructible<_Decay_if_not_any<_Tp>>::value, any&>
2534c3eb207Smrg      operator=(_Tp&& __rhs)
2543ad841b2Smrg      {
2554c3eb207Smrg	*this = any(std::forward<_Tp>(__rhs));
2563ad841b2Smrg	return *this;
2573ad841b2Smrg      }
2583ad841b2Smrg
2593ad841b2Smrg    /// Emplace with an object created from @p __args as the contained object.
2604c3eb207Smrg    template <typename _Tp, typename... _Args>
2614c3eb207Smrg      __emplace_t<decay_t<_Tp>, _Args...>
2623ad841b2Smrg      emplace(_Args&&... __args)
2633ad841b2Smrg      {
2644c3eb207Smrg	using _VTp = decay_t<_Tp>;
2654c3eb207Smrg	__do_emplace<_VTp>(std::forward<_Args>(__args)...);
266*4ac76180Smrg	return *any::_Manager<_VTp>::_S_access(_M_storage);
2673ad841b2Smrg      }
2683ad841b2Smrg
2693ad841b2Smrg    /// Emplace with an object created from @p __il and @p __args as
2703ad841b2Smrg    /// the contained object.
2714c3eb207Smrg    template <typename _Tp, typename _Up, typename... _Args>
2724c3eb207Smrg      __emplace_t<decay_t<_Tp>, initializer_list<_Up>&, _Args&&...>
2733ad841b2Smrg      emplace(initializer_list<_Up> __il, _Args&&... __args)
2743ad841b2Smrg      {
2754c3eb207Smrg	using _VTp = decay_t<_Tp>;
2764c3eb207Smrg	__do_emplace<_VTp, _Up>(__il, std::forward<_Args>(__args)...);
277*4ac76180Smrg	return *any::_Manager<_VTp>::_S_access(_M_storage);
2783ad841b2Smrg      }
2793ad841b2Smrg
2803ad841b2Smrg    // modifiers
2813ad841b2Smrg
2823ad841b2Smrg    /// If not empty, destroy the contained object.
2833ad841b2Smrg    void reset() noexcept
2843ad841b2Smrg    {
2853ad841b2Smrg      if (has_value())
2863ad841b2Smrg      {
2873ad841b2Smrg	_M_manager(_Op_destroy, this, nullptr);
2883ad841b2Smrg	_M_manager = nullptr;
2893ad841b2Smrg      }
2903ad841b2Smrg    }
2913ad841b2Smrg
2923ad841b2Smrg    /// Exchange state with another object.
2933ad841b2Smrg    void swap(any& __rhs) noexcept
2943ad841b2Smrg    {
2953ad841b2Smrg      if (!has_value() && !__rhs.has_value())
2963ad841b2Smrg	return;
2973ad841b2Smrg
2983ad841b2Smrg      if (has_value() && __rhs.has_value())
2993ad841b2Smrg	{
3003ad841b2Smrg	  if (this == &__rhs)
3013ad841b2Smrg	    return;
3023ad841b2Smrg
3033ad841b2Smrg	  any __tmp;
3043ad841b2Smrg	  _Arg __arg;
3053ad841b2Smrg	  __arg._M_any = &__tmp;
3063ad841b2Smrg	  __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
3073ad841b2Smrg	  __arg._M_any = &__rhs;
3083ad841b2Smrg	  _M_manager(_Op_xfer, this, &__arg);
3093ad841b2Smrg	  __arg._M_any = this;
3103ad841b2Smrg	  __tmp._M_manager(_Op_xfer, &__tmp, &__arg);
3113ad841b2Smrg	}
3123ad841b2Smrg      else
3133ad841b2Smrg	{
3143ad841b2Smrg	  any* __empty = !has_value() ? this : &__rhs;
3153ad841b2Smrg	  any* __full = !has_value() ? &__rhs : this;
3163ad841b2Smrg	  _Arg __arg;
3173ad841b2Smrg	  __arg._M_any = __empty;
3183ad841b2Smrg	  __full->_M_manager(_Op_xfer, __full, &__arg);
3193ad841b2Smrg	}
3203ad841b2Smrg    }
3213ad841b2Smrg
3223ad841b2Smrg    // observers
3233ad841b2Smrg
3243ad841b2Smrg    /// Reports whether there is a contained object or not.
3253ad841b2Smrg    bool has_value() const noexcept { return _M_manager != nullptr; }
3263ad841b2Smrg
3273ad841b2Smrg#if __cpp_rtti
3283ad841b2Smrg    /// The @c typeid of the contained object, or @c typeid(void) if empty.
3293ad841b2Smrg    const type_info& type() const noexcept
3303ad841b2Smrg    {
3313ad841b2Smrg      if (!has_value())
3323ad841b2Smrg	return typeid(void);
3333ad841b2Smrg      _Arg __arg;
3343ad841b2Smrg      _M_manager(_Op_get_type_info, this, &__arg);
3353ad841b2Smrg      return *__arg._M_typeinfo;
3363ad841b2Smrg    }
3373ad841b2Smrg#endif
3383ad841b2Smrg
3393ad841b2Smrg    template<typename _Tp>
3403ad841b2Smrg      static constexpr bool __is_valid_cast()
3413ad841b2Smrg      { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
3423ad841b2Smrg
3433ad841b2Smrg  private:
3443ad841b2Smrg    enum _Op {
3453ad841b2Smrg	_Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer
3463ad841b2Smrg    };
3473ad841b2Smrg
3483ad841b2Smrg    union _Arg
3493ad841b2Smrg    {
3503ad841b2Smrg	void* _M_obj;
3513ad841b2Smrg	const std::type_info* _M_typeinfo;
3523ad841b2Smrg	any* _M_any;
3533ad841b2Smrg    };
3543ad841b2Smrg
3553ad841b2Smrg    void (*_M_manager)(_Op, const any*, _Arg*);
3563ad841b2Smrg    _Storage _M_storage;
3573ad841b2Smrg
3583ad841b2Smrg    template<typename _Tp>
3593ad841b2Smrg      friend void* __any_caster(const any* __any);
3603ad841b2Smrg
3613ad841b2Smrg    // Manage in-place contained object.
3623ad841b2Smrg    template<typename _Tp>
3633ad841b2Smrg      struct _Manager_internal
3643ad841b2Smrg      {
3653ad841b2Smrg	static void
3663ad841b2Smrg	_S_manage(_Op __which, const any* __anyp, _Arg* __arg);
3673ad841b2Smrg
3683ad841b2Smrg	template<typename _Up>
3693ad841b2Smrg	  static void
3703ad841b2Smrg	  _S_create(_Storage& __storage, _Up&& __value)
3713ad841b2Smrg	  {
3723ad841b2Smrg	    void* __addr = &__storage._M_buffer;
3733ad841b2Smrg	    ::new (__addr) _Tp(std::forward<_Up>(__value));
3743ad841b2Smrg	  }
3753ad841b2Smrg
3763ad841b2Smrg	template<typename... _Args>
3773ad841b2Smrg	  static void
3783ad841b2Smrg	  _S_create(_Storage& __storage, _Args&&... __args)
3793ad841b2Smrg	  {
3803ad841b2Smrg	    void* __addr = &__storage._M_buffer;
3813ad841b2Smrg	    ::new (__addr) _Tp(std::forward<_Args>(__args)...);
3823ad841b2Smrg	  }
383*4ac76180Smrg
384*4ac76180Smrg	static _Tp*
385*4ac76180Smrg	_S_access(const _Storage& __storage)
386*4ac76180Smrg	{
387*4ac76180Smrg	  // The contained object is in __storage._M_buffer
388*4ac76180Smrg	  const void* __addr = &__storage._M_buffer;
389*4ac76180Smrg	  return static_cast<_Tp*>(const_cast<void*>(__addr));
390*4ac76180Smrg	}
3913ad841b2Smrg      };
3923ad841b2Smrg
3933ad841b2Smrg    // Manage external contained object.
3943ad841b2Smrg    template<typename _Tp>
3953ad841b2Smrg      struct _Manager_external
3963ad841b2Smrg      {
3973ad841b2Smrg	static void
3983ad841b2Smrg	_S_manage(_Op __which, const any* __anyp, _Arg* __arg);
3993ad841b2Smrg
4003ad841b2Smrg	template<typename _Up>
4013ad841b2Smrg	  static void
4023ad841b2Smrg	  _S_create(_Storage& __storage, _Up&& __value)
4033ad841b2Smrg	  {
4043ad841b2Smrg	    __storage._M_ptr = new _Tp(std::forward<_Up>(__value));
4053ad841b2Smrg	  }
4063ad841b2Smrg	template<typename... _Args>
4073ad841b2Smrg	  static void
4083ad841b2Smrg	  _S_create(_Storage& __storage, _Args&&... __args)
4093ad841b2Smrg	  {
4103ad841b2Smrg	    __storage._M_ptr = new _Tp(std::forward<_Args>(__args)...);
4113ad841b2Smrg	  }
412*4ac76180Smrg	static _Tp*
413*4ac76180Smrg	_S_access(const _Storage& __storage)
414*4ac76180Smrg	{
415*4ac76180Smrg	  // The contained object is in *__storage._M_ptr
416*4ac76180Smrg	  return static_cast<_Tp*>(__storage._M_ptr);
417*4ac76180Smrg	}
4183ad841b2Smrg      };
4193ad841b2Smrg  };
4203ad841b2Smrg
4213ad841b2Smrg  /// Exchange the states of two @c any objects.
4223ad841b2Smrg  inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); }
4233ad841b2Smrg
4244c3eb207Smrg  /// Create an `any` holding a `_Tp` constructed from `__args...`.
4253ad841b2Smrg  template <typename _Tp, typename... _Args>
4264c3eb207Smrg    inline
4274c3eb207Smrg    enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>, _Args...>, any>
4284c3eb207Smrg    make_any(_Args&&... __args)
4293ad841b2Smrg    {
4303ad841b2Smrg      return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
4313ad841b2Smrg    }
4323ad841b2Smrg
4334c3eb207Smrg  /// Create an `any` holding a `_Tp` constructed from `__il` and `__args...`.
4343ad841b2Smrg  template <typename _Tp, typename _Up, typename... _Args>
4354c3eb207Smrg    inline
4364c3eb207Smrg    enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>,
4374c3eb207Smrg				   initializer_list<_Up>&, _Args...>, any>
4384c3eb207Smrg    make_any(initializer_list<_Up> __il, _Args&&... __args)
4393ad841b2Smrg    {
4403ad841b2Smrg      return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
4413ad841b2Smrg    }
4423ad841b2Smrg
4433ad841b2Smrg  /**
4443ad841b2Smrg   * @brief Access the contained object.
4453ad841b2Smrg   *
4463ad841b2Smrg   * @tparam  _ValueType  A const-reference or CopyConstructible type.
4473ad841b2Smrg   * @param   __any       The object to access.
4483ad841b2Smrg   * @return  The contained object.
4493ad841b2Smrg   * @throw   bad_any_cast If <code>
4503ad841b2Smrg   *          __any.type() != typeid(remove_reference_t<_ValueType>)
4513ad841b2Smrg   *          </code>
4523ad841b2Smrg   */
4533ad841b2Smrg  template<typename _ValueType>
4543ad841b2Smrg    inline _ValueType any_cast(const any& __any)
4553ad841b2Smrg    {
456627f7eb2Smrg      using _Up = __remove_cvref_t<_ValueType>;
4573ad841b2Smrg      static_assert(any::__is_valid_cast<_ValueType>(),
4583ad841b2Smrg	  "Template argument must be a reference or CopyConstructible type");
459cef8759bSmrg      static_assert(is_constructible_v<_ValueType, const _Up&>,
460cef8759bSmrg	  "Template argument must be constructible from a const value.");
461cef8759bSmrg      auto __p = any_cast<_Up>(&__any);
4623ad841b2Smrg      if (__p)
4633ad841b2Smrg	return static_cast<_ValueType>(*__p);
4643ad841b2Smrg      __throw_bad_any_cast();
4653ad841b2Smrg    }
4663ad841b2Smrg
4673ad841b2Smrg  /**
4683ad841b2Smrg   * @brief Access the contained object.
4693ad841b2Smrg   *
4703ad841b2Smrg   * @tparam  _ValueType  A reference or CopyConstructible type.
4713ad841b2Smrg   * @param   __any       The object to access.
4723ad841b2Smrg   * @return  The contained object.
4733ad841b2Smrg   * @throw   bad_any_cast If <code>
4743ad841b2Smrg   *          __any.type() != typeid(remove_reference_t<_ValueType>)
4753ad841b2Smrg   *          </code>
4763ad841b2Smrg   *
4773ad841b2Smrg   * @{
4783ad841b2Smrg   */
4793ad841b2Smrg  template<typename _ValueType>
4803ad841b2Smrg    inline _ValueType any_cast(any& __any)
4813ad841b2Smrg    {
482627f7eb2Smrg      using _Up = __remove_cvref_t<_ValueType>;
4833ad841b2Smrg      static_assert(any::__is_valid_cast<_ValueType>(),
4843ad841b2Smrg	  "Template argument must be a reference or CopyConstructible type");
485cef8759bSmrg      static_assert(is_constructible_v<_ValueType, _Up&>,
486cef8759bSmrg	  "Template argument must be constructible from an lvalue.");
487cef8759bSmrg      auto __p = any_cast<_Up>(&__any);
4883ad841b2Smrg      if (__p)
4893ad841b2Smrg	return static_cast<_ValueType>(*__p);
4903ad841b2Smrg      __throw_bad_any_cast();
4913ad841b2Smrg    }
4923ad841b2Smrg
493cef8759bSmrg  template<typename _ValueType>
4943ad841b2Smrg    inline _ValueType any_cast(any&& __any)
4953ad841b2Smrg    {
496627f7eb2Smrg      using _Up = __remove_cvref_t<_ValueType>;
4973ad841b2Smrg      static_assert(any::__is_valid_cast<_ValueType>(),
4983ad841b2Smrg	  "Template argument must be a reference or CopyConstructible type");
499cef8759bSmrg      static_assert(is_constructible_v<_ValueType, _Up>,
500cef8759bSmrg	  "Template argument must be constructible from an rvalue.");
501cef8759bSmrg      auto __p = any_cast<_Up>(&__any);
5023ad841b2Smrg      if (__p)
5033ad841b2Smrg	return static_cast<_ValueType>(std::move(*__p));
5043ad841b2Smrg      __throw_bad_any_cast();
5053ad841b2Smrg    }
5064c3eb207Smrg  /// @}
5073ad841b2Smrg
508cef8759bSmrg  /// @cond undocumented
5093ad841b2Smrg  template<typename _Tp>
5103ad841b2Smrg    void* __any_caster(const any* __any)
5113ad841b2Smrg    {
512cef8759bSmrg      // any_cast<T> returns non-null if __any->type() == typeid(T) and
513cef8759bSmrg      // typeid(T) ignores cv-qualifiers so remove them:
514cef8759bSmrg      using _Up = remove_cv_t<_Tp>;
515cef8759bSmrg      // The contained value has a decayed type, so if decay_t<U> is not U,
516cef8759bSmrg      // then it's not possible to have a contained value of type U:
517cef8759bSmrg      if constexpr (!is_same_v<decay_t<_Up>, _Up>)
518cef8759bSmrg	return nullptr;
519cef8759bSmrg      // Only copy constructible types can be used for contained values:
520cef8759bSmrg      else if constexpr (!is_copy_constructible_v<_Up>)
521cef8759bSmrg	return nullptr;
522cef8759bSmrg      // First try comparing function addresses, which works without RTTI
523cef8759bSmrg      else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage
524cef8759bSmrg#if __cpp_rtti
525cef8759bSmrg	  || __any->type() == typeid(_Tp)
526cef8759bSmrg#endif
527cef8759bSmrg	  )
5283ad841b2Smrg	{
529*4ac76180Smrg	  return any::_Manager<_Up>::_S_access(__any->_M_storage);
5303ad841b2Smrg	}
5313ad841b2Smrg      return nullptr;
5323ad841b2Smrg    }
533cef8759bSmrg  /// @endcond
5343ad841b2Smrg
5353ad841b2Smrg  /**
5363ad841b2Smrg   * @brief Access the contained object.
5373ad841b2Smrg   *
5383ad841b2Smrg   * @tparam  _ValueType  The type of the contained object.
5393ad841b2Smrg   * @param   __any       A pointer to the object to access.
5403ad841b2Smrg   * @return  The address of the contained object if <code>
5413ad841b2Smrg   *          __any != nullptr && __any.type() == typeid(_ValueType)
5423ad841b2Smrg   *          </code>, otherwise a null pointer.
5433ad841b2Smrg   *
5443ad841b2Smrg   * @{
5453ad841b2Smrg   */
5463ad841b2Smrg  template<typename _ValueType>
5473ad841b2Smrg    inline const _ValueType* any_cast(const any* __any) noexcept
5483ad841b2Smrg    {
549cef8759bSmrg      if constexpr (is_object_v<_ValueType>)
5503ad841b2Smrg	if (__any)
5513ad841b2Smrg	  return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
5523ad841b2Smrg      return nullptr;
5533ad841b2Smrg    }
5543ad841b2Smrg
5553ad841b2Smrg  template<typename _ValueType>
5563ad841b2Smrg    inline _ValueType* any_cast(any* __any) noexcept
5573ad841b2Smrg    {
558cef8759bSmrg      if constexpr (is_object_v<_ValueType>)
5593ad841b2Smrg	if (__any)
5603ad841b2Smrg	  return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
5613ad841b2Smrg      return nullptr;
5623ad841b2Smrg    }
5634c3eb207Smrg  /// @}
5643ad841b2Smrg
5653ad841b2Smrg  template<typename _Tp>
5663ad841b2Smrg    void
5673ad841b2Smrg    any::_Manager_internal<_Tp>::
5683ad841b2Smrg    _S_manage(_Op __which, const any* __any, _Arg* __arg)
5693ad841b2Smrg    {
5703ad841b2Smrg      // The contained object is in _M_storage._M_buffer
5713ad841b2Smrg      auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer);
5723ad841b2Smrg      switch (__which)
5733ad841b2Smrg      {
5743ad841b2Smrg      case _Op_access:
5753ad841b2Smrg	__arg->_M_obj = const_cast<_Tp*>(__ptr);
5763ad841b2Smrg	break;
5773ad841b2Smrg      case _Op_get_type_info:
5783ad841b2Smrg#if __cpp_rtti
5793ad841b2Smrg	__arg->_M_typeinfo = &typeid(_Tp);
5803ad841b2Smrg#endif
5813ad841b2Smrg	break;
5823ad841b2Smrg      case _Op_clone:
5833ad841b2Smrg	::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
5843ad841b2Smrg	__arg->_M_any->_M_manager = __any->_M_manager;
5853ad841b2Smrg	break;
5863ad841b2Smrg      case _Op_destroy:
5873ad841b2Smrg	__ptr->~_Tp();
5883ad841b2Smrg	break;
5893ad841b2Smrg      case _Op_xfer:
5903ad841b2Smrg	::new(&__arg->_M_any->_M_storage._M_buffer) _Tp
5913ad841b2Smrg	  (std::move(*const_cast<_Tp*>(__ptr)));
5923ad841b2Smrg	__ptr->~_Tp();
5933ad841b2Smrg	__arg->_M_any->_M_manager = __any->_M_manager;
5943ad841b2Smrg	const_cast<any*>(__any)->_M_manager = nullptr;
5953ad841b2Smrg	break;
5963ad841b2Smrg      }
5973ad841b2Smrg    }
5983ad841b2Smrg
5993ad841b2Smrg  template<typename _Tp>
6003ad841b2Smrg    void
6013ad841b2Smrg    any::_Manager_external<_Tp>::
6023ad841b2Smrg    _S_manage(_Op __which, const any* __any, _Arg* __arg)
6033ad841b2Smrg    {
6043ad841b2Smrg      // The contained object is *_M_storage._M_ptr
6053ad841b2Smrg      auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr);
6063ad841b2Smrg      switch (__which)
6073ad841b2Smrg      {
6083ad841b2Smrg      case _Op_access:
6093ad841b2Smrg	__arg->_M_obj = const_cast<_Tp*>(__ptr);
6103ad841b2Smrg	break;
6113ad841b2Smrg      case _Op_get_type_info:
6123ad841b2Smrg#if __cpp_rtti
6133ad841b2Smrg	__arg->_M_typeinfo = &typeid(_Tp);
6143ad841b2Smrg#endif
6153ad841b2Smrg	break;
6163ad841b2Smrg      case _Op_clone:
6173ad841b2Smrg	__arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr);
6183ad841b2Smrg	__arg->_M_any->_M_manager = __any->_M_manager;
6193ad841b2Smrg	break;
6203ad841b2Smrg      case _Op_destroy:
6213ad841b2Smrg	delete __ptr;
6223ad841b2Smrg	break;
6233ad841b2Smrg      case _Op_xfer:
6243ad841b2Smrg	__arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr;
6253ad841b2Smrg	__arg->_M_any->_M_manager = __any->_M_manager;
6263ad841b2Smrg	const_cast<any*>(__any)->_M_manager = nullptr;
6273ad841b2Smrg	break;
6283ad841b2Smrg      }
6293ad841b2Smrg    }
6303ad841b2Smrg
6313ad841b2Smrg  /// @}
6323ad841b2Smrg
633627f7eb2Smrg  namespace __detail::__variant
634627f7eb2Smrg  {
635627f7eb2Smrg    template<typename> struct _Never_valueless_alt; // see <variant>
636627f7eb2Smrg
637627f7eb2Smrg    // Provide the strong exception-safety guarantee when emplacing an
638627f7eb2Smrg    // any into a variant.
639627f7eb2Smrg    template<>
640627f7eb2Smrg      struct _Never_valueless_alt<std::any>
641627f7eb2Smrg      : std::true_type
642627f7eb2Smrg      { };
643627f7eb2Smrg  }  // namespace __detail::__variant
644627f7eb2Smrg
6453ad841b2Smrg_GLIBCXX_END_NAMESPACE_VERSION
6463ad841b2Smrg} // namespace std
6473ad841b2Smrg
648627f7eb2Smrg#endif // C++17
6493ad841b2Smrg#endif // _GLIBCXX_ANY
650