xref: /freebsd/contrib/llvm-project/libcxx/include/any (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric// -*- C++ -*-
2*0b57cec5SDimitry Andric//===------------------------------ any -----------------------------------===//
3*0b57cec5SDimitry Andric//
4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric//
8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric#ifndef _LIBCPP_ANY
11*0b57cec5SDimitry Andric#define _LIBCPP_ANY
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric/*
14*0b57cec5SDimitry Andric   any synopsis
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andricnamespace std {
17*0b57cec5SDimitry Andric
18*0b57cec5SDimitry Andric  class bad_any_cast : public bad_cast
19*0b57cec5SDimitry Andric  {
20*0b57cec5SDimitry Andric  public:
21*0b57cec5SDimitry Andric    virtual const char* what() const noexcept;
22*0b57cec5SDimitry Andric  };
23*0b57cec5SDimitry Andric
24*0b57cec5SDimitry Andric  class any
25*0b57cec5SDimitry Andric  {
26*0b57cec5SDimitry Andric  public:
27*0b57cec5SDimitry Andric
28*0b57cec5SDimitry Andric    // 6.3.1 any construct/destruct
29*0b57cec5SDimitry Andric    any() noexcept;
30*0b57cec5SDimitry Andric
31*0b57cec5SDimitry Andric    any(const any& other);
32*0b57cec5SDimitry Andric    any(any&& other) noexcept;
33*0b57cec5SDimitry Andric
34*0b57cec5SDimitry Andric    template <class ValueType>
35*0b57cec5SDimitry Andric      any(ValueType&& value);
36*0b57cec5SDimitry Andric
37*0b57cec5SDimitry Andric    ~any();
38*0b57cec5SDimitry Andric
39*0b57cec5SDimitry Andric    // 6.3.2 any assignments
40*0b57cec5SDimitry Andric    any& operator=(const any& rhs);
41*0b57cec5SDimitry Andric    any& operator=(any&& rhs) noexcept;
42*0b57cec5SDimitry Andric
43*0b57cec5SDimitry Andric    template <class ValueType>
44*0b57cec5SDimitry Andric      any& operator=(ValueType&& rhs);
45*0b57cec5SDimitry Andric
46*0b57cec5SDimitry Andric    // 6.3.3 any modifiers
47*0b57cec5SDimitry Andric    template <class ValueType, class... Args>
48*0b57cec5SDimitry Andric      decay_t<ValueType>& emplace(Args&&... args);
49*0b57cec5SDimitry Andric    template <class ValueType, class U, class... Args>
50*0b57cec5SDimitry Andric      decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
51*0b57cec5SDimitry Andric    void reset() noexcept;
52*0b57cec5SDimitry Andric    void swap(any& rhs) noexcept;
53*0b57cec5SDimitry Andric
54*0b57cec5SDimitry Andric    // 6.3.4 any observers
55*0b57cec5SDimitry Andric    bool has_value() const noexcept;
56*0b57cec5SDimitry Andric    const type_info& type() const noexcept;
57*0b57cec5SDimitry Andric  };
58*0b57cec5SDimitry Andric
59*0b57cec5SDimitry Andric   // 6.4 Non-member functions
60*0b57cec5SDimitry Andric  void swap(any& x, any& y) noexcept;
61*0b57cec5SDimitry Andric
62*0b57cec5SDimitry Andric  template <class T, class ...Args>
63*0b57cec5SDimitry Andric    any make_any(Args&& ...args);
64*0b57cec5SDimitry Andric  template <class T, class U, class ...Args>
65*0b57cec5SDimitry Andric    any make_any(initializer_list<U>, Args&& ...args);
66*0b57cec5SDimitry Andric
67*0b57cec5SDimitry Andric  template<class ValueType>
68*0b57cec5SDimitry Andric    ValueType any_cast(const any& operand);
69*0b57cec5SDimitry Andric  template<class ValueType>
70*0b57cec5SDimitry Andric    ValueType any_cast(any& operand);
71*0b57cec5SDimitry Andric  template<class ValueType>
72*0b57cec5SDimitry Andric    ValueType any_cast(any&& operand);
73*0b57cec5SDimitry Andric
74*0b57cec5SDimitry Andric  template<class ValueType>
75*0b57cec5SDimitry Andric    const ValueType* any_cast(const any* operand) noexcept;
76*0b57cec5SDimitry Andric  template<class ValueType>
77*0b57cec5SDimitry Andric    ValueType* any_cast(any* operand) noexcept;
78*0b57cec5SDimitry Andric
79*0b57cec5SDimitry Andric} // namespace std
80*0b57cec5SDimitry Andric
81*0b57cec5SDimitry Andric*/
82*0b57cec5SDimitry Andric
83*0b57cec5SDimitry Andric#include <experimental/__config>
84*0b57cec5SDimitry Andric#include <memory>
85*0b57cec5SDimitry Andric#include <new>
86*0b57cec5SDimitry Andric#include <typeinfo>
87*0b57cec5SDimitry Andric#include <type_traits>
88*0b57cec5SDimitry Andric#include <cstdlib>
89*0b57cec5SDimitry Andric#include <version>
90*0b57cec5SDimitry Andric
91*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
92*0b57cec5SDimitry Andric#pragma GCC system_header
93*0b57cec5SDimitry Andric#endif
94*0b57cec5SDimitry Andric
95*0b57cec5SDimitry Andricnamespace std {
96*0b57cec5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
97*0b57cec5SDimitry Andric{
98*0b57cec5SDimitry Andricpublic:
99*0b57cec5SDimitry Andric    virtual const char* what() const _NOEXCEPT;
100*0b57cec5SDimitry Andric};
101*0b57cec5SDimitry Andric} // namespace std
102*0b57cec5SDimitry Andric
103*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
104*0b57cec5SDimitry Andric
105*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
106*0b57cec5SDimitry Andric
107*0b57cec5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
108*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
109*0b57cec5SDimitry Andricvoid __throw_bad_any_cast()
110*0b57cec5SDimitry Andric{
111*0b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
112*0b57cec5SDimitry Andric    throw bad_any_cast();
113*0b57cec5SDimitry Andric#else
114*0b57cec5SDimitry Andric    _VSTD::abort();
115*0b57cec5SDimitry Andric#endif
116*0b57cec5SDimitry Andric}
117*0b57cec5SDimitry Andric
118*0b57cec5SDimitry Andric// Forward declarations
119*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS any;
120*0b57cec5SDimitry Andric
121*0b57cec5SDimitry Andrictemplate <class _ValueType>
122*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
123*0b57cec5SDimitry Andricadd_pointer_t<add_const_t<_ValueType>>
124*0b57cec5SDimitry Andricany_cast(any const *) _NOEXCEPT;
125*0b57cec5SDimitry Andric
126*0b57cec5SDimitry Andrictemplate <class _ValueType>
127*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
128*0b57cec5SDimitry Andricadd_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
129*0b57cec5SDimitry Andric
130*0b57cec5SDimitry Andricnamespace __any_imp
131*0b57cec5SDimitry Andric{
132*0b57cec5SDimitry Andric  using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
133*0b57cec5SDimitry Andric
134*0b57cec5SDimitry Andric  template <class _Tp>
135*0b57cec5SDimitry Andric  using _IsSmallObject = integral_constant<bool
136*0b57cec5SDimitry Andric        , sizeof(_Tp) <= sizeof(_Buffer)
137*0b57cec5SDimitry Andric          && alignment_of<_Buffer>::value
138*0b57cec5SDimitry Andric             % alignment_of<_Tp>::value == 0
139*0b57cec5SDimitry Andric          && is_nothrow_move_constructible<_Tp>::value
140*0b57cec5SDimitry Andric        >;
141*0b57cec5SDimitry Andric
142*0b57cec5SDimitry Andric  enum class _Action {
143*0b57cec5SDimitry Andric    _Destroy,
144*0b57cec5SDimitry Andric    _Copy,
145*0b57cec5SDimitry Andric    _Move,
146*0b57cec5SDimitry Andric    _Get,
147*0b57cec5SDimitry Andric    _TypeInfo
148*0b57cec5SDimitry Andric  };
149*0b57cec5SDimitry Andric
150*0b57cec5SDimitry Andric  template <class _Tp> struct _SmallHandler;
151*0b57cec5SDimitry Andric  template <class _Tp> struct _LargeHandler;
152*0b57cec5SDimitry Andric
153*0b57cec5SDimitry Andric  template <class _Tp>
154*0b57cec5SDimitry Andric  struct  _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; };
155*0b57cec5SDimitry Andric  template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
156*0b57cec5SDimitry Andric
157*0b57cec5SDimitry Andric  template <class _Tp>
158*0b57cec5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY
159*0b57cec5SDimitry Andric  constexpr const void* __get_fallback_typeid() {
160*0b57cec5SDimitry Andric      return &__unique_typeinfo<decay_t<_Tp>>::__id;
161*0b57cec5SDimitry Andric  }
162*0b57cec5SDimitry Andric
163*0b57cec5SDimitry Andric  template <class _Tp>
164*0b57cec5SDimitry Andric  inline _LIBCPP_INLINE_VISIBILITY
165*0b57cec5SDimitry Andric  bool __compare_typeid(type_info const* __id, const void* __fallback_id)
166*0b57cec5SDimitry Andric  {
167*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI)
168*0b57cec5SDimitry Andric      if (__id && *__id == typeid(_Tp))
169*0b57cec5SDimitry Andric          return true;
170*0b57cec5SDimitry Andric#endif
171*0b57cec5SDimitry Andric      if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
172*0b57cec5SDimitry Andric          return true;
173*0b57cec5SDimitry Andric      return false;
174*0b57cec5SDimitry Andric  }
175*0b57cec5SDimitry Andric
176*0b57cec5SDimitry Andric  template <class _Tp>
177*0b57cec5SDimitry Andric  using _Handler = conditional_t<
178*0b57cec5SDimitry Andric    _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
179*0b57cec5SDimitry Andric
180*0b57cec5SDimitry Andric} // namespace __any_imp
181*0b57cec5SDimitry Andric
182*0b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS any
183*0b57cec5SDimitry Andric{
184*0b57cec5SDimitry Andricpublic:
185*0b57cec5SDimitry Andric  // construct/destruct
186*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
187*0b57cec5SDimitry Andric  constexpr any() _NOEXCEPT : __h(nullptr) {}
188*0b57cec5SDimitry Andric
189*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
190*0b57cec5SDimitry Andric  any(any const & __other) : __h(nullptr)
191*0b57cec5SDimitry Andric  {
192*0b57cec5SDimitry Andric    if (__other.__h) __other.__call(_Action::_Copy, this);
193*0b57cec5SDimitry Andric  }
194*0b57cec5SDimitry Andric
195*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
196*0b57cec5SDimitry Andric  any(any && __other) _NOEXCEPT : __h(nullptr)
197*0b57cec5SDimitry Andric  {
198*0b57cec5SDimitry Andric    if (__other.__h) __other.__call(_Action::_Move, this);
199*0b57cec5SDimitry Andric  }
200*0b57cec5SDimitry Andric
201*0b57cec5SDimitry Andric  template <
202*0b57cec5SDimitry Andric      class _ValueType
203*0b57cec5SDimitry Andric    , class _Tp = decay_t<_ValueType>
204*0b57cec5SDimitry Andric    , class = enable_if_t<
205*0b57cec5SDimitry Andric        !is_same<_Tp, any>::value &&
206*0b57cec5SDimitry Andric        !__is_inplace_type<_ValueType>::value &&
207*0b57cec5SDimitry Andric        is_copy_constructible<_Tp>::value>
208*0b57cec5SDimitry Andric    >
209*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
210*0b57cec5SDimitry Andric  any(_ValueType && __value);
211*0b57cec5SDimitry Andric
212*0b57cec5SDimitry Andric  template <class _ValueType, class ..._Args,
213*0b57cec5SDimitry Andric    class _Tp = decay_t<_ValueType>,
214*0b57cec5SDimitry Andric    class = enable_if_t<
215*0b57cec5SDimitry Andric        is_constructible<_Tp, _Args...>::value &&
216*0b57cec5SDimitry Andric        is_copy_constructible<_Tp>::value
217*0b57cec5SDimitry Andric    >
218*0b57cec5SDimitry Andric  >
219*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
220*0b57cec5SDimitry Andric  explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
221*0b57cec5SDimitry Andric
222*0b57cec5SDimitry Andric  template <class _ValueType, class _Up, class ..._Args,
223*0b57cec5SDimitry Andric    class _Tp = decay_t<_ValueType>,
224*0b57cec5SDimitry Andric    class = enable_if_t<
225*0b57cec5SDimitry Andric        is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
226*0b57cec5SDimitry Andric        is_copy_constructible<_Tp>::value>
227*0b57cec5SDimitry Andric  >
228*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
229*0b57cec5SDimitry Andric  explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
230*0b57cec5SDimitry Andric
231*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
232*0b57cec5SDimitry Andric  ~any() { this->reset(); }
233*0b57cec5SDimitry Andric
234*0b57cec5SDimitry Andric  // assignments
235*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
236*0b57cec5SDimitry Andric  any & operator=(any const & __rhs) {
237*0b57cec5SDimitry Andric    any(__rhs).swap(*this);
238*0b57cec5SDimitry Andric    return *this;
239*0b57cec5SDimitry Andric  }
240*0b57cec5SDimitry Andric
241*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
242*0b57cec5SDimitry Andric  any & operator=(any && __rhs) _NOEXCEPT {
243*0b57cec5SDimitry Andric    any(_VSTD::move(__rhs)).swap(*this);
244*0b57cec5SDimitry Andric    return *this;
245*0b57cec5SDimitry Andric  }
246*0b57cec5SDimitry Andric
247*0b57cec5SDimitry Andric  template <
248*0b57cec5SDimitry Andric      class _ValueType
249*0b57cec5SDimitry Andric    , class _Tp = decay_t<_ValueType>
250*0b57cec5SDimitry Andric    , class = enable_if_t<
251*0b57cec5SDimitry Andric          !is_same<_Tp, any>::value
252*0b57cec5SDimitry Andric          && is_copy_constructible<_Tp>::value>
253*0b57cec5SDimitry Andric    >
254*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
255*0b57cec5SDimitry Andric  any & operator=(_ValueType && __rhs);
256*0b57cec5SDimitry Andric
257*0b57cec5SDimitry Andric  template <class _ValueType, class ..._Args,
258*0b57cec5SDimitry Andric    class _Tp = decay_t<_ValueType>,
259*0b57cec5SDimitry Andric    class = enable_if_t<
260*0b57cec5SDimitry Andric        is_constructible<_Tp, _Args...>::value &&
261*0b57cec5SDimitry Andric        is_copy_constructible<_Tp>::value>
262*0b57cec5SDimitry Andric    >
263*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
264*0b57cec5SDimitry Andric  _Tp& emplace(_Args&&... args);
265*0b57cec5SDimitry Andric
266*0b57cec5SDimitry Andric  template <class _ValueType, class _Up, class ..._Args,
267*0b57cec5SDimitry Andric    class _Tp = decay_t<_ValueType>,
268*0b57cec5SDimitry Andric    class = enable_if_t<
269*0b57cec5SDimitry Andric        is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
270*0b57cec5SDimitry Andric        is_copy_constructible<_Tp>::value>
271*0b57cec5SDimitry Andric  >
272*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
273*0b57cec5SDimitry Andric  _Tp& emplace(initializer_list<_Up>, _Args&&...);
274*0b57cec5SDimitry Andric
275*0b57cec5SDimitry Andric  // 6.3.3 any modifiers
276*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
277*0b57cec5SDimitry Andric  void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); }
278*0b57cec5SDimitry Andric
279*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
280*0b57cec5SDimitry Andric  void swap(any & __rhs) _NOEXCEPT;
281*0b57cec5SDimitry Andric
282*0b57cec5SDimitry Andric  // 6.3.4 any observers
283*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
284*0b57cec5SDimitry Andric  bool has_value() const _NOEXCEPT { return __h != nullptr; }
285*0b57cec5SDimitry Andric
286*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI)
287*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
288*0b57cec5SDimitry Andric  const type_info & type() const _NOEXCEPT {
289*0b57cec5SDimitry Andric    if (__h) {
290*0b57cec5SDimitry Andric        return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
291*0b57cec5SDimitry Andric    } else {
292*0b57cec5SDimitry Andric        return typeid(void);
293*0b57cec5SDimitry Andric    }
294*0b57cec5SDimitry Andric  }
295*0b57cec5SDimitry Andric#endif
296*0b57cec5SDimitry Andric
297*0b57cec5SDimitry Andricprivate:
298*0b57cec5SDimitry Andric    typedef __any_imp::_Action _Action;
299*0b57cec5SDimitry Andric    using _HandleFuncPtr =  void* (*)(_Action, any const *, any *, const type_info *,
300*0b57cec5SDimitry Andric      const void* __fallback_info);
301*0b57cec5SDimitry Andric
302*0b57cec5SDimitry Andric    union _Storage {
303*0b57cec5SDimitry Andric        constexpr _Storage() : __ptr(nullptr) {}
304*0b57cec5SDimitry Andric        void *  __ptr;
305*0b57cec5SDimitry Andric        __any_imp::_Buffer __buf;
306*0b57cec5SDimitry Andric    };
307*0b57cec5SDimitry Andric
308*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
309*0b57cec5SDimitry Andric    void * __call(_Action __a, any * __other = nullptr,
310*0b57cec5SDimitry Andric                  type_info const * __info = nullptr,
311*0b57cec5SDimitry Andric                   const void* __fallback_info = nullptr) const
312*0b57cec5SDimitry Andric    {
313*0b57cec5SDimitry Andric        return __h(__a, this, __other, __info, __fallback_info);
314*0b57cec5SDimitry Andric    }
315*0b57cec5SDimitry Andric
316*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
317*0b57cec5SDimitry Andric    void * __call(_Action __a, any * __other = nullptr,
318*0b57cec5SDimitry Andric                  type_info const * __info = nullptr,
319*0b57cec5SDimitry Andric                  const void* __fallback_info = nullptr)
320*0b57cec5SDimitry Andric    {
321*0b57cec5SDimitry Andric        return __h(__a, this, __other, __info, __fallback_info);
322*0b57cec5SDimitry Andric    }
323*0b57cec5SDimitry Andric
324*0b57cec5SDimitry Andric    template <class>
325*0b57cec5SDimitry Andric    friend struct __any_imp::_SmallHandler;
326*0b57cec5SDimitry Andric    template <class>
327*0b57cec5SDimitry Andric    friend struct __any_imp::_LargeHandler;
328*0b57cec5SDimitry Andric
329*0b57cec5SDimitry Andric    template <class _ValueType>
330*0b57cec5SDimitry Andric    friend add_pointer_t<add_const_t<_ValueType>>
331*0b57cec5SDimitry Andric    any_cast(any const *) _NOEXCEPT;
332*0b57cec5SDimitry Andric
333*0b57cec5SDimitry Andric    template <class _ValueType>
334*0b57cec5SDimitry Andric    friend add_pointer_t<_ValueType>
335*0b57cec5SDimitry Andric    any_cast(any *) _NOEXCEPT;
336*0b57cec5SDimitry Andric
337*0b57cec5SDimitry Andric    _HandleFuncPtr __h = nullptr;
338*0b57cec5SDimitry Andric    _Storage __s;
339*0b57cec5SDimitry Andric};
340*0b57cec5SDimitry Andric
341*0b57cec5SDimitry Andricnamespace __any_imp
342*0b57cec5SDimitry Andric{
343*0b57cec5SDimitry Andric  template <class _Tp>
344*0b57cec5SDimitry Andric  struct _LIBCPP_TEMPLATE_VIS _SmallHandler
345*0b57cec5SDimitry Andric  {
346*0b57cec5SDimitry Andric     _LIBCPP_INLINE_VISIBILITY
347*0b57cec5SDimitry Andric     static void* __handle(_Action __act, any const * __this, any * __other,
348*0b57cec5SDimitry Andric                           type_info const * __info, const void* __fallback_info)
349*0b57cec5SDimitry Andric     {
350*0b57cec5SDimitry Andric        switch (__act)
351*0b57cec5SDimitry Andric        {
352*0b57cec5SDimitry Andric        case _Action::_Destroy:
353*0b57cec5SDimitry Andric          __destroy(const_cast<any &>(*__this));
354*0b57cec5SDimitry Andric          return nullptr;
355*0b57cec5SDimitry Andric        case _Action::_Copy:
356*0b57cec5SDimitry Andric            __copy(*__this, *__other);
357*0b57cec5SDimitry Andric            return nullptr;
358*0b57cec5SDimitry Andric        case _Action::_Move:
359*0b57cec5SDimitry Andric          __move(const_cast<any &>(*__this), *__other);
360*0b57cec5SDimitry Andric          return nullptr;
361*0b57cec5SDimitry Andric        case _Action::_Get:
362*0b57cec5SDimitry Andric            return __get(const_cast<any &>(*__this), __info, __fallback_info);
363*0b57cec5SDimitry Andric        case _Action::_TypeInfo:
364*0b57cec5SDimitry Andric          return __type_info();
365*0b57cec5SDimitry Andric        }
366*0b57cec5SDimitry Andric    }
367*0b57cec5SDimitry Andric
368*0b57cec5SDimitry Andric    template <class ..._Args>
369*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
370*0b57cec5SDimitry Andric    static _Tp& __create(any & __dest, _Args&&... __args) {
371*0b57cec5SDimitry Andric        _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
372*0b57cec5SDimitry Andric        __dest.__h = &_SmallHandler::__handle;
373*0b57cec5SDimitry Andric        return *__ret;
374*0b57cec5SDimitry Andric    }
375*0b57cec5SDimitry Andric
376*0b57cec5SDimitry Andric  private:
377*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
378*0b57cec5SDimitry Andric    static void __destroy(any & __this) {
379*0b57cec5SDimitry Andric        _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
380*0b57cec5SDimitry Andric        __value.~_Tp();
381*0b57cec5SDimitry Andric        __this.__h = nullptr;
382*0b57cec5SDimitry Andric    }
383*0b57cec5SDimitry Andric
384*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
385*0b57cec5SDimitry Andric    static void __copy(any const & __this, any & __dest) {
386*0b57cec5SDimitry Andric        _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
387*0b57cec5SDimitry Andric            static_cast<void const *>(&__this.__s.__buf)));
388*0b57cec5SDimitry Andric    }
389*0b57cec5SDimitry Andric
390*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
391*0b57cec5SDimitry Andric    static void __move(any & __this, any & __dest) {
392*0b57cec5SDimitry Andric        _SmallHandler::__create(__dest, _VSTD::move(
393*0b57cec5SDimitry Andric            *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
394*0b57cec5SDimitry Andric        __destroy(__this);
395*0b57cec5SDimitry Andric    }
396*0b57cec5SDimitry Andric
397*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
398*0b57cec5SDimitry Andric    static void* __get(any & __this,
399*0b57cec5SDimitry Andric                       type_info const * __info,
400*0b57cec5SDimitry Andric                       const void* __fallback_id)
401*0b57cec5SDimitry Andric    {
402*0b57cec5SDimitry Andric        if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
403*0b57cec5SDimitry Andric            return static_cast<void*>(&__this.__s.__buf);
404*0b57cec5SDimitry Andric        return nullptr;
405*0b57cec5SDimitry Andric    }
406*0b57cec5SDimitry Andric
407*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
408*0b57cec5SDimitry Andric    static void* __type_info()
409*0b57cec5SDimitry Andric    {
410*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI)
411*0b57cec5SDimitry Andric        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
412*0b57cec5SDimitry Andric#else
413*0b57cec5SDimitry Andric        return nullptr;
414*0b57cec5SDimitry Andric#endif
415*0b57cec5SDimitry Andric    }
416*0b57cec5SDimitry Andric  };
417*0b57cec5SDimitry Andric
418*0b57cec5SDimitry Andric  template <class _Tp>
419*0b57cec5SDimitry Andric  struct _LIBCPP_TEMPLATE_VIS _LargeHandler
420*0b57cec5SDimitry Andric  {
421*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
422*0b57cec5SDimitry Andric    static void* __handle(_Action __act, any const * __this,
423*0b57cec5SDimitry Andric                          any * __other, type_info const * __info,
424*0b57cec5SDimitry Andric                          void const* __fallback_info)
425*0b57cec5SDimitry Andric    {
426*0b57cec5SDimitry Andric        switch (__act)
427*0b57cec5SDimitry Andric        {
428*0b57cec5SDimitry Andric        case _Action::_Destroy:
429*0b57cec5SDimitry Andric          __destroy(const_cast<any &>(*__this));
430*0b57cec5SDimitry Andric          return nullptr;
431*0b57cec5SDimitry Andric        case _Action::_Copy:
432*0b57cec5SDimitry Andric          __copy(*__this, *__other);
433*0b57cec5SDimitry Andric          return nullptr;
434*0b57cec5SDimitry Andric        case _Action::_Move:
435*0b57cec5SDimitry Andric          __move(const_cast<any &>(*__this), *__other);
436*0b57cec5SDimitry Andric          return nullptr;
437*0b57cec5SDimitry Andric        case _Action::_Get:
438*0b57cec5SDimitry Andric            return __get(const_cast<any &>(*__this), __info, __fallback_info);
439*0b57cec5SDimitry Andric        case _Action::_TypeInfo:
440*0b57cec5SDimitry Andric          return __type_info();
441*0b57cec5SDimitry Andric        }
442*0b57cec5SDimitry Andric    }
443*0b57cec5SDimitry Andric
444*0b57cec5SDimitry Andric    template <class ..._Args>
445*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
446*0b57cec5SDimitry Andric    static _Tp& __create(any & __dest, _Args&&... __args) {
447*0b57cec5SDimitry Andric        typedef allocator<_Tp> _Alloc;
448*0b57cec5SDimitry Andric        typedef __allocator_destructor<_Alloc> _Dp;
449*0b57cec5SDimitry Andric        _Alloc __a;
450*0b57cec5SDimitry Andric        unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
451*0b57cec5SDimitry Andric        _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...);
452*0b57cec5SDimitry Andric        __dest.__s.__ptr = __hold.release();
453*0b57cec5SDimitry Andric        __dest.__h = &_LargeHandler::__handle;
454*0b57cec5SDimitry Andric        return *__ret;
455*0b57cec5SDimitry Andric    }
456*0b57cec5SDimitry Andric
457*0b57cec5SDimitry Andric  private:
458*0b57cec5SDimitry Andric
459*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
460*0b57cec5SDimitry Andric    static void __destroy(any & __this){
461*0b57cec5SDimitry Andric        delete static_cast<_Tp*>(__this.__s.__ptr);
462*0b57cec5SDimitry Andric        __this.__h = nullptr;
463*0b57cec5SDimitry Andric    }
464*0b57cec5SDimitry Andric
465*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
466*0b57cec5SDimitry Andric    static void __copy(any const & __this, any & __dest) {
467*0b57cec5SDimitry Andric        _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
468*0b57cec5SDimitry Andric    }
469*0b57cec5SDimitry Andric
470*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
471*0b57cec5SDimitry Andric    static void __move(any & __this, any & __dest) {
472*0b57cec5SDimitry Andric      __dest.__s.__ptr = __this.__s.__ptr;
473*0b57cec5SDimitry Andric      __dest.__h = &_LargeHandler::__handle;
474*0b57cec5SDimitry Andric      __this.__h = nullptr;
475*0b57cec5SDimitry Andric    }
476*0b57cec5SDimitry Andric
477*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
478*0b57cec5SDimitry Andric    static void* __get(any & __this, type_info const * __info,
479*0b57cec5SDimitry Andric                       void const* __fallback_info)
480*0b57cec5SDimitry Andric    {
481*0b57cec5SDimitry Andric        if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
482*0b57cec5SDimitry Andric            return static_cast<void*>(__this.__s.__ptr);
483*0b57cec5SDimitry Andric        return nullptr;
484*0b57cec5SDimitry Andric
485*0b57cec5SDimitry Andric    }
486*0b57cec5SDimitry Andric
487*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
488*0b57cec5SDimitry Andric    static void* __type_info()
489*0b57cec5SDimitry Andric    {
490*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI)
491*0b57cec5SDimitry Andric        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
492*0b57cec5SDimitry Andric#else
493*0b57cec5SDimitry Andric        return nullptr;
494*0b57cec5SDimitry Andric#endif
495*0b57cec5SDimitry Andric    }
496*0b57cec5SDimitry Andric  };
497*0b57cec5SDimitry Andric
498*0b57cec5SDimitry Andric} // namespace __any_imp
499*0b57cec5SDimitry Andric
500*0b57cec5SDimitry Andric
501*0b57cec5SDimitry Andrictemplate <class _ValueType, class _Tp, class>
502*0b57cec5SDimitry Andricany::any(_ValueType && __v) : __h(nullptr)
503*0b57cec5SDimitry Andric{
504*0b57cec5SDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
505*0b57cec5SDimitry Andric}
506*0b57cec5SDimitry Andric
507*0b57cec5SDimitry Andrictemplate <class _ValueType, class ..._Args, class _Tp, class>
508*0b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, _Args&&... __args) {
509*0b57cec5SDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
510*0b57cec5SDimitry Andric}
511*0b57cec5SDimitry Andric
512*0b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class ..._Args, class _Tp, class>
513*0b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
514*0b57cec5SDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
515*0b57cec5SDimitry Andric}
516*0b57cec5SDimitry Andric
517*0b57cec5SDimitry Andrictemplate <class _ValueType, class, class>
518*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
519*0b57cec5SDimitry Andricany & any::operator=(_ValueType && __v)
520*0b57cec5SDimitry Andric{
521*0b57cec5SDimitry Andric  any(_VSTD::forward<_ValueType>(__v)).swap(*this);
522*0b57cec5SDimitry Andric  return *this;
523*0b57cec5SDimitry Andric}
524*0b57cec5SDimitry Andric
525*0b57cec5SDimitry Andrictemplate <class _ValueType, class ..._Args, class _Tp, class>
526*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
527*0b57cec5SDimitry Andric_Tp& any::emplace(_Args&&... __args) {
528*0b57cec5SDimitry Andric  reset();
529*0b57cec5SDimitry Andric  return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
530*0b57cec5SDimitry Andric}
531*0b57cec5SDimitry Andric
532*0b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class ..._Args, class _Tp, class>
533*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
534*0b57cec5SDimitry Andric_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
535*0b57cec5SDimitry Andric  reset();
536*0b57cec5SDimitry Andric  return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
537*0b57cec5SDimitry Andric}
538*0b57cec5SDimitry Andric
539*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
540*0b57cec5SDimitry Andricvoid any::swap(any & __rhs) _NOEXCEPT
541*0b57cec5SDimitry Andric{
542*0b57cec5SDimitry Andric    if (this == &__rhs)
543*0b57cec5SDimitry Andric      return;
544*0b57cec5SDimitry Andric    if (__h && __rhs.__h) {
545*0b57cec5SDimitry Andric        any __tmp;
546*0b57cec5SDimitry Andric        __rhs.__call(_Action::_Move, &__tmp);
547*0b57cec5SDimitry Andric        this->__call(_Action::_Move, &__rhs);
548*0b57cec5SDimitry Andric        __tmp.__call(_Action::_Move, this);
549*0b57cec5SDimitry Andric    }
550*0b57cec5SDimitry Andric    else if (__h) {
551*0b57cec5SDimitry Andric        this->__call(_Action::_Move, &__rhs);
552*0b57cec5SDimitry Andric    }
553*0b57cec5SDimitry Andric    else if (__rhs.__h) {
554*0b57cec5SDimitry Andric        __rhs.__call(_Action::_Move, this);
555*0b57cec5SDimitry Andric    }
556*0b57cec5SDimitry Andric}
557*0b57cec5SDimitry Andric
558*0b57cec5SDimitry Andric// 6.4 Non-member functions
559*0b57cec5SDimitry Andric
560*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
561*0b57cec5SDimitry Andricvoid swap(any & __lhs, any & __rhs) _NOEXCEPT
562*0b57cec5SDimitry Andric{
563*0b57cec5SDimitry Andric    __lhs.swap(__rhs);
564*0b57cec5SDimitry Andric}
565*0b57cec5SDimitry Andric
566*0b57cec5SDimitry Andrictemplate <class _Tp, class ..._Args>
567*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
568*0b57cec5SDimitry Andricany make_any(_Args&&... __args) {
569*0b57cec5SDimitry Andric    return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...);
570*0b57cec5SDimitry Andric}
571*0b57cec5SDimitry Andric
572*0b57cec5SDimitry Andrictemplate <class _Tp, class _Up, class ..._Args>
573*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
574*0b57cec5SDimitry Andricany make_any(initializer_list<_Up> __il, _Args&&... __args) {
575*0b57cec5SDimitry Andric    return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
576*0b57cec5SDimitry Andric}
577*0b57cec5SDimitry Andric
578*0b57cec5SDimitry Andrictemplate <class _ValueType>
579*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
580*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
581*0b57cec5SDimitry Andric_ValueType any_cast(any const & __v)
582*0b57cec5SDimitry Andric{
583*0b57cec5SDimitry Andric    using _RawValueType = __uncvref_t<_ValueType>;
584*0b57cec5SDimitry Andric    static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
585*0b57cec5SDimitry Andric                  "ValueType is required to be a const lvalue reference "
586*0b57cec5SDimitry Andric                  "or a CopyConstructible type");
587*0b57cec5SDimitry Andric    auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
588*0b57cec5SDimitry Andric    if (__tmp == nullptr)
589*0b57cec5SDimitry Andric        __throw_bad_any_cast();
590*0b57cec5SDimitry Andric    return static_cast<_ValueType>(*__tmp);
591*0b57cec5SDimitry Andric}
592*0b57cec5SDimitry Andric
593*0b57cec5SDimitry Andrictemplate <class _ValueType>
594*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
595*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
596*0b57cec5SDimitry Andric_ValueType any_cast(any & __v)
597*0b57cec5SDimitry Andric{
598*0b57cec5SDimitry Andric    using _RawValueType = __uncvref_t<_ValueType>;
599*0b57cec5SDimitry Andric    static_assert(is_constructible<_ValueType, _RawValueType &>::value,
600*0b57cec5SDimitry Andric                  "ValueType is required to be an lvalue reference "
601*0b57cec5SDimitry Andric                  "or a CopyConstructible type");
602*0b57cec5SDimitry Andric    auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
603*0b57cec5SDimitry Andric    if (__tmp == nullptr)
604*0b57cec5SDimitry Andric        __throw_bad_any_cast();
605*0b57cec5SDimitry Andric    return static_cast<_ValueType>(*__tmp);
606*0b57cec5SDimitry Andric}
607*0b57cec5SDimitry Andric
608*0b57cec5SDimitry Andrictemplate <class _ValueType>
609*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
610*0b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
611*0b57cec5SDimitry Andric_ValueType any_cast(any && __v)
612*0b57cec5SDimitry Andric{
613*0b57cec5SDimitry Andric    using _RawValueType = __uncvref_t<_ValueType>;
614*0b57cec5SDimitry Andric    static_assert(is_constructible<_ValueType, _RawValueType>::value,
615*0b57cec5SDimitry Andric                  "ValueType is required to be an rvalue reference "
616*0b57cec5SDimitry Andric                  "or a CopyConstructible type");
617*0b57cec5SDimitry Andric    auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
618*0b57cec5SDimitry Andric    if (__tmp == nullptr)
619*0b57cec5SDimitry Andric        __throw_bad_any_cast();
620*0b57cec5SDimitry Andric    return static_cast<_ValueType>(_VSTD::move(*__tmp));
621*0b57cec5SDimitry Andric}
622*0b57cec5SDimitry Andric
623*0b57cec5SDimitry Andrictemplate <class _ValueType>
624*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
625*0b57cec5SDimitry Andricadd_pointer_t<add_const_t<_ValueType>>
626*0b57cec5SDimitry Andricany_cast(any const * __any) _NOEXCEPT
627*0b57cec5SDimitry Andric{
628*0b57cec5SDimitry Andric    static_assert(!is_reference<_ValueType>::value,
629*0b57cec5SDimitry Andric                  "_ValueType may not be a reference.");
630*0b57cec5SDimitry Andric    return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
631*0b57cec5SDimitry Andric}
632*0b57cec5SDimitry Andric
633*0b57cec5SDimitry Andrictemplate <class _RetType>
634*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
635*0b57cec5SDimitry Andric_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
636*0b57cec5SDimitry Andric  return static_cast<_RetType>(__p);
637*0b57cec5SDimitry Andric}
638*0b57cec5SDimitry Andric
639*0b57cec5SDimitry Andrictemplate <class _RetType>
640*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
641*0b57cec5SDimitry Andric_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
642*0b57cec5SDimitry Andric  return nullptr;
643*0b57cec5SDimitry Andric}
644*0b57cec5SDimitry Andric
645*0b57cec5SDimitry Andrictemplate <class _ValueType>
646*0b57cec5SDimitry Andricadd_pointer_t<_ValueType>
647*0b57cec5SDimitry Andricany_cast(any * __any) _NOEXCEPT
648*0b57cec5SDimitry Andric{
649*0b57cec5SDimitry Andric    using __any_imp::_Action;
650*0b57cec5SDimitry Andric    static_assert(!is_reference<_ValueType>::value,
651*0b57cec5SDimitry Andric                  "_ValueType may not be a reference.");
652*0b57cec5SDimitry Andric    typedef typename add_pointer<_ValueType>::type _ReturnType;
653*0b57cec5SDimitry Andric    if (__any && __any->__h) {
654*0b57cec5SDimitry Andric      void *__p = __any->__call(_Action::_Get, nullptr,
655*0b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI)
656*0b57cec5SDimitry Andric                          &typeid(_ValueType),
657*0b57cec5SDimitry Andric#else
658*0b57cec5SDimitry Andric                          nullptr,
659*0b57cec5SDimitry Andric#endif
660*0b57cec5SDimitry Andric                          __any_imp::__get_fallback_typeid<_ValueType>());
661*0b57cec5SDimitry Andric        return _VSTD::__pointer_or_func_cast<_ReturnType>(
662*0b57cec5SDimitry Andric            __p, is_function<_ValueType>{});
663*0b57cec5SDimitry Andric    }
664*0b57cec5SDimitry Andric    return nullptr;
665*0b57cec5SDimitry Andric}
666*0b57cec5SDimitry Andric
667*0b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
668*0b57cec5SDimitry Andric
669*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
670*0b57cec5SDimitry Andric
671*0b57cec5SDimitry Andric#endif // _LIBCPP_ANY
672