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