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