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