xref: /llvm-project-15.0.7/libcxx/include/any (revision b48c5010)
1324506b9SEric Fiselier// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
3324506b9SEric Fiselier//
42946cd70SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
52946cd70SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
62946cd70SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7324506b9SEric Fiselier//
8324506b9SEric Fiselier//===----------------------------------------------------------------------===//
9324506b9SEric Fiselier
10324506b9SEric Fiselier#ifndef _LIBCPP_ANY
11324506b9SEric Fiselier#define _LIBCPP_ANY
12324506b9SEric Fiselier
13324506b9SEric Fiselier/*
14324506b9SEric Fiselier   any synopsis
15324506b9SEric Fiselier
16324506b9SEric Fiseliernamespace std {
17324506b9SEric Fiselier
18324506b9SEric Fiselier  class bad_any_cast : public bad_cast
19324506b9SEric Fiselier  {
20324506b9SEric Fiselier  public:
21324506b9SEric Fiselier    virtual const char* what() const noexcept;
22324506b9SEric Fiselier  };
23324506b9SEric Fiselier
24324506b9SEric Fiselier  class any
25324506b9SEric Fiselier  {
26324506b9SEric Fiselier  public:
27324506b9SEric Fiselier
28324506b9SEric Fiselier    // 6.3.1 any construct/destruct
29324506b9SEric Fiselier    any() noexcept;
30324506b9SEric Fiselier
31324506b9SEric Fiselier    any(const any& other);
32324506b9SEric Fiselier    any(any&& other) noexcept;
33324506b9SEric Fiselier
34324506b9SEric Fiselier    template <class ValueType>
35324506b9SEric Fiselier      any(ValueType&& value);
36324506b9SEric Fiselier
37324506b9SEric Fiselier    ~any();
38324506b9SEric Fiselier
39324506b9SEric Fiselier    // 6.3.2 any assignments
40324506b9SEric Fiselier    any& operator=(const any& rhs);
41324506b9SEric Fiselier    any& operator=(any&& rhs) noexcept;
42324506b9SEric Fiselier
43324506b9SEric Fiselier    template <class ValueType>
44324506b9SEric Fiselier      any& operator=(ValueType&& rhs);
45324506b9SEric Fiselier
46324506b9SEric Fiselier    // 6.3.3 any modifiers
475c80f4f6SMarshall Clow    template <class ValueType, class... Args>
485c80f4f6SMarshall Clow      decay_t<ValueType>& emplace(Args&&... args);
495c80f4f6SMarshall Clow    template <class ValueType, class U, class... Args>
505c80f4f6SMarshall Clow      decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
51324506b9SEric Fiselier    void reset() noexcept;
52324506b9SEric Fiselier    void swap(any& rhs) noexcept;
53324506b9SEric Fiselier
54324506b9SEric Fiselier    // 6.3.4 any observers
55324506b9SEric Fiselier    bool has_value() const noexcept;
56324506b9SEric Fiselier    const type_info& type() const noexcept;
57324506b9SEric Fiselier  };
58324506b9SEric Fiselier
59324506b9SEric Fiselier   // 6.4 Non-member functions
60324506b9SEric Fiselier  void swap(any& x, any& y) noexcept;
61324506b9SEric Fiselier
62324506b9SEric Fiselier  template <class T, class ...Args>
63324506b9SEric Fiselier    any make_any(Args&& ...args);
64324506b9SEric Fiselier  template <class T, class U, class ...Args>
65324506b9SEric Fiselier    any make_any(initializer_list<U>, Args&& ...args);
66324506b9SEric Fiselier
67324506b9SEric Fiselier  template<class ValueType>
68324506b9SEric Fiselier    ValueType any_cast(const any& operand);
69324506b9SEric Fiselier  template<class ValueType>
70324506b9SEric Fiselier    ValueType any_cast(any& operand);
71324506b9SEric Fiselier  template<class ValueType>
72324506b9SEric Fiselier    ValueType any_cast(any&& operand);
73324506b9SEric Fiselier
74324506b9SEric Fiselier  template<class ValueType>
75324506b9SEric Fiselier    const ValueType* any_cast(const any* operand) noexcept;
76324506b9SEric Fiselier  template<class ValueType>
77324506b9SEric Fiselier    ValueType* any_cast(any* operand) noexcept;
78324506b9SEric Fiselier
79324506b9SEric Fiselier} // namespace std
80324506b9SEric Fiselier
81324506b9SEric Fiselier*/
82324506b9SEric Fiselier
83385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
842eadbc86SLouis Dionne#include <__availability>
85bfbd73f8SArthur O'Dwyer#include <__config>
866adbc83eSChristopher Di Bella#include <__utility/forward.h>
8752915d78SNikolas Klauser#include <__utility/in_place.h>
8852915d78SNikolas Klauser#include <__utility/move.h>
89e39095a3SLouis Dionne#include <__utility/unreachable.h>
90324506b9SEric Fiselier#include <cstdlib>
913cd4531bSNikolas Klauser#include <initializer_list>
92bfbd73f8SArthur O'Dwyer#include <memory>
93bfbd73f8SArthur O'Dwyer#include <type_traits>
94bfbd73f8SArthur O'Dwyer#include <typeinfo>
95f56972e2SMarshall Clow#include <version>
96324506b9SEric Fiselier
97de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
98de4a57cbSLouis Dionne#  include <chrono>
99de4a57cbSLouis Dionne#endif
100de4a57cbSLouis Dionne
101324506b9SEric Fiselier#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
102324506b9SEric Fiselier#  pragma GCC system_header
103324506b9SEric Fiselier#endif
104324506b9SEric Fiselier
105324506b9SEric Fiseliernamespace std {
1068a063df1SLouis Dionneclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast
107324506b9SEric Fiselier{
108324506b9SEric Fiselierpublic:
109324506b9SEric Fiselier    virtual const char* what() const _NOEXCEPT;
110324506b9SEric Fiselier};
111324506b9SEric Fiselier} // namespace std
112324506b9SEric Fiselier
113324506b9SEric Fiselier_LIBCPP_BEGIN_NAMESPACE_STD
114324506b9SEric Fiselier
115324506b9SEric Fiselier#if _LIBCPP_STD_VER > 14
116324506b9SEric Fiselier
117dc7200b4SLouis Dionne_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
1188a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
1190fc8cec7SMarshall Clowvoid __throw_bad_any_cast()
1200fc8cec7SMarshall Clow{
1210fc8cec7SMarshall Clow#ifndef _LIBCPP_NO_EXCEPTIONS
1220fc8cec7SMarshall Clow    throw bad_any_cast();
1230fc8cec7SMarshall Clow#else
1240fc8cec7SMarshall Clow    _VSTD::abort();
1250fc8cec7SMarshall Clow#endif
1260fc8cec7SMarshall Clow}
1270fc8cec7SMarshall Clow
128324506b9SEric Fiselier// Forward declarations
129e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS any;
130324506b9SEric Fiselier
131324506b9SEric Fiseliertemplate <class _ValueType>
132324506b9SEric Fiselier_LIBCPP_INLINE_VISIBILITY
133324506b9SEric Fiselieradd_pointer_t<add_const_t<_ValueType>>
134324506b9SEric Fiselierany_cast(any const *) _NOEXCEPT;
135324506b9SEric Fiselier
136324506b9SEric Fiseliertemplate <class _ValueType>
137324506b9SEric Fiselier_LIBCPP_INLINE_VISIBILITY
138324506b9SEric Fiselieradd_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT;
139324506b9SEric Fiselier
140324506b9SEric Fiseliernamespace __any_imp
141324506b9SEric Fiselier{
142324506b9SEric Fiselier  using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>;
143324506b9SEric Fiselier
144324506b9SEric Fiselier  template <class _Tp>
145324506b9SEric Fiselier  using _IsSmallObject = integral_constant<bool
146324506b9SEric Fiselier        , sizeof(_Tp) <= sizeof(_Buffer)
147324506b9SEric Fiselier          && alignment_of<_Buffer>::value
148324506b9SEric Fiselier             % alignment_of<_Tp>::value == 0
149324506b9SEric Fiselier          && is_nothrow_move_constructible<_Tp>::value
150324506b9SEric Fiselier        >;
151324506b9SEric Fiselier
152324506b9SEric Fiselier  enum class _Action {
153324506b9SEric Fiselier    _Destroy,
154324506b9SEric Fiselier    _Copy,
155324506b9SEric Fiselier    _Move,
156324506b9SEric Fiselier    _Get,
157324506b9SEric Fiselier    _TypeInfo
158324506b9SEric Fiselier  };
159324506b9SEric Fiselier
160324506b9SEric Fiselier  template <class _Tp> struct _SmallHandler;
161324506b9SEric Fiselier  template <class _Tp> struct _LargeHandler;
162324506b9SEric Fiselier
163324506b9SEric Fiselier  template <class _Tp>
164e2f2d1edSEric Fiselier  struct  _LIBCPP_TEMPLATE_VIS __unique_typeinfo { static constexpr int __id = 0; };
165324506b9SEric Fiselier  template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id;
166324506b9SEric Fiselier
167324506b9SEric Fiselier  template <class _Tp>
168324506b9SEric Fiselier  inline _LIBCPP_INLINE_VISIBILITY
169324506b9SEric Fiselier  constexpr const void* __get_fallback_typeid() {
170bb09ef95SLouis Dionne      return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id;
171324506b9SEric Fiselier  }
172324506b9SEric Fiselier
173324506b9SEric Fiselier  template <class _Tp>
174324506b9SEric Fiselier  inline _LIBCPP_INLINE_VISIBILITY
175324506b9SEric Fiselier  bool __compare_typeid(type_info const* __id, const void* __fallback_id)
176324506b9SEric Fiselier  {
177324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI)
178324506b9SEric Fiselier      if (__id && *__id == typeid(_Tp))
179324506b9SEric Fiselier          return true;
180324506b9SEric Fiselier#endif
181324506b9SEric Fiselier      if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>())
182324506b9SEric Fiselier          return true;
183324506b9SEric Fiselier      return false;
184324506b9SEric Fiselier  }
185324506b9SEric Fiselier
186324506b9SEric Fiselier  template <class _Tp>
187324506b9SEric Fiselier  using _Handler = conditional_t<
188324506b9SEric Fiselier    _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
189324506b9SEric Fiselier
190324506b9SEric Fiselier} // namespace __any_imp
191324506b9SEric Fiselier
192e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS any
193324506b9SEric Fiselier{
194324506b9SEric Fiselierpublic:
195324506b9SEric Fiselier  // construct/destruct
196324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
197324506b9SEric Fiselier  constexpr any() _NOEXCEPT : __h(nullptr) {}
198324506b9SEric Fiselier
199324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
200324506b9SEric Fiselier  any(any const & __other) : __h(nullptr)
201324506b9SEric Fiselier  {
202324506b9SEric Fiselier    if (__other.__h) __other.__call(_Action::_Copy, this);
203324506b9SEric Fiselier  }
204324506b9SEric Fiselier
205324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
206324506b9SEric Fiselier  any(any && __other) _NOEXCEPT : __h(nullptr)
207324506b9SEric Fiselier  {
208324506b9SEric Fiselier    if (__other.__h) __other.__call(_Action::_Move, this);
209324506b9SEric Fiselier  }
210324506b9SEric Fiselier
211324506b9SEric Fiselier  template <
212324506b9SEric Fiselier      class _ValueType
213b18fd965SEric Fiselier    , class _Tp = decay_t<_ValueType>
214324506b9SEric Fiselier    , class = enable_if_t<
215b18fd965SEric Fiselier        !is_same<_Tp, any>::value &&
216034555f1SEric Fiselier        !__is_inplace_type<_ValueType>::value &&
217b18fd965SEric Fiselier        is_copy_constructible<_Tp>::value>
218324506b9SEric Fiselier    >
219324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
220324506b9SEric Fiselier  any(_ValueType && __value);
221324506b9SEric Fiselier
222b18fd965SEric Fiselier  template <class _ValueType, class ..._Args,
223b18fd965SEric Fiselier    class _Tp = decay_t<_ValueType>,
224324506b9SEric Fiselier    class = enable_if_t<
225324506b9SEric Fiselier        is_constructible<_Tp, _Args...>::value &&
226324506b9SEric Fiselier        is_copy_constructible<_Tp>::value
227324506b9SEric Fiselier    >
228324506b9SEric Fiselier  >
229324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
230b18fd965SEric Fiselier  explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
231324506b9SEric Fiselier
232b18fd965SEric Fiselier  template <class _ValueType, class _Up, class ..._Args,
233b18fd965SEric Fiselier    class _Tp = decay_t<_ValueType>,
234324506b9SEric Fiselier    class = enable_if_t<
235324506b9SEric Fiselier        is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
236324506b9SEric Fiselier        is_copy_constructible<_Tp>::value>
237324506b9SEric Fiselier  >
238324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
239b18fd965SEric Fiselier  explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
240324506b9SEric Fiselier
241324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
242324506b9SEric Fiselier  ~any() { this->reset(); }
243324506b9SEric Fiselier
244324506b9SEric Fiselier  // assignments
245324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
246324506b9SEric Fiselier  any & operator=(any const & __rhs) {
247324506b9SEric Fiselier    any(__rhs).swap(*this);
248324506b9SEric Fiselier    return *this;
249324506b9SEric Fiselier  }
250324506b9SEric Fiselier
251324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
252324506b9SEric Fiselier  any & operator=(any && __rhs) _NOEXCEPT {
253324506b9SEric Fiselier    any(_VSTD::move(__rhs)).swap(*this);
254324506b9SEric Fiselier    return *this;
255324506b9SEric Fiselier  }
256324506b9SEric Fiselier
257324506b9SEric Fiselier  template <
258324506b9SEric Fiselier      class _ValueType
259b18fd965SEric Fiselier    , class _Tp = decay_t<_ValueType>
260324506b9SEric Fiselier    , class = enable_if_t<
261b18fd965SEric Fiselier          !is_same<_Tp, any>::value
26250253ed1SEric Fiselier          && is_copy_constructible<_Tp>::value>
263324506b9SEric Fiselier    >
264324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
265324506b9SEric Fiselier  any & operator=(_ValueType && __rhs);
266324506b9SEric Fiselier
267b18fd965SEric Fiselier  template <class _ValueType, class ..._Args,
268b18fd965SEric Fiselier    class _Tp = decay_t<_ValueType>,
269324506b9SEric Fiselier    class = enable_if_t<
270324506b9SEric Fiselier        is_constructible<_Tp, _Args...>::value &&
271324506b9SEric Fiselier        is_copy_constructible<_Tp>::value>
272324506b9SEric Fiselier    >
273324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
274*b48c5010SNikolas Klauser  _Tp& emplace(_Args&&...);
275324506b9SEric Fiselier
276b18fd965SEric Fiselier  template <class _ValueType, class _Up, class ..._Args,
277b18fd965SEric Fiselier    class _Tp = decay_t<_ValueType>,
278324506b9SEric Fiselier    class = enable_if_t<
279324506b9SEric Fiselier        is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
280324506b9SEric Fiselier        is_copy_constructible<_Tp>::value>
281324506b9SEric Fiselier  >
282324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2835c80f4f6SMarshall Clow  _Tp& emplace(initializer_list<_Up>, _Args&&...);
284324506b9SEric Fiselier
285324506b9SEric Fiselier  // 6.3.3 any modifiers
286324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
287324506b9SEric Fiselier  void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); }
288324506b9SEric Fiselier
289324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
290324506b9SEric Fiselier  void swap(any & __rhs) _NOEXCEPT;
291324506b9SEric Fiselier
292324506b9SEric Fiselier  // 6.3.4 any observers
293324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
294324506b9SEric Fiselier  bool has_value() const _NOEXCEPT { return __h != nullptr; }
295324506b9SEric Fiselier
296324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI)
297324506b9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
298324506b9SEric Fiselier  const type_info & type() const _NOEXCEPT {
299324506b9SEric Fiselier    if (__h) {
300324506b9SEric Fiselier        return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
301324506b9SEric Fiselier    } else {
302324506b9SEric Fiselier        return typeid(void);
303324506b9SEric Fiselier    }
304324506b9SEric Fiselier  }
305324506b9SEric Fiselier#endif
306324506b9SEric Fiselier
307324506b9SEric Fiselierprivate:
308324506b9SEric Fiselier    typedef __any_imp::_Action _Action;
309324506b9SEric Fiselier    using _HandleFuncPtr =  void* (*)(_Action, any const *, any *, const type_info *,
310324506b9SEric Fiselier      const void* __fallback_info);
311324506b9SEric Fiselier
312324506b9SEric Fiselier    union _Storage {
313324506b9SEric Fiselier        constexpr _Storage() : __ptr(nullptr) {}
314324506b9SEric Fiselier        void *  __ptr;
315324506b9SEric Fiselier        __any_imp::_Buffer __buf;
316324506b9SEric Fiselier    };
317324506b9SEric Fiselier
318dc7200b4SLouis Dionne    _LIBCPP_INLINE_VISIBILITY
319324506b9SEric Fiselier    void * __call(_Action __a, any * __other = nullptr,
320324506b9SEric Fiselier                  type_info const * __info = nullptr,
321324506b9SEric Fiselier                   const void* __fallback_info = nullptr) const
322324506b9SEric Fiselier    {
323324506b9SEric Fiselier        return __h(__a, this, __other, __info, __fallback_info);
324324506b9SEric Fiselier    }
325324506b9SEric Fiselier
326dc7200b4SLouis Dionne    _LIBCPP_INLINE_VISIBILITY
327324506b9SEric Fiselier    void * __call(_Action __a, any * __other = nullptr,
328324506b9SEric Fiselier                  type_info const * __info = nullptr,
329324506b9SEric Fiselier                  const void* __fallback_info = nullptr)
330324506b9SEric Fiselier    {
331324506b9SEric Fiselier        return __h(__a, this, __other, __info, __fallback_info);
332324506b9SEric Fiselier    }
333324506b9SEric Fiselier
334324506b9SEric Fiselier    template <class>
335324506b9SEric Fiselier    friend struct __any_imp::_SmallHandler;
336324506b9SEric Fiselier    template <class>
337324506b9SEric Fiselier    friend struct __any_imp::_LargeHandler;
338324506b9SEric Fiselier
339324506b9SEric Fiselier    template <class _ValueType>
340324506b9SEric Fiselier    friend add_pointer_t<add_const_t<_ValueType>>
341324506b9SEric Fiselier    any_cast(any const *) _NOEXCEPT;
342324506b9SEric Fiselier
343324506b9SEric Fiselier    template <class _ValueType>
344324506b9SEric Fiselier    friend add_pointer_t<_ValueType>
345324506b9SEric Fiselier    any_cast(any *) _NOEXCEPT;
346324506b9SEric Fiselier
347324506b9SEric Fiselier    _HandleFuncPtr __h = nullptr;
348324506b9SEric Fiselier    _Storage __s;
349324506b9SEric Fiselier};
350324506b9SEric Fiselier
351324506b9SEric Fiseliernamespace __any_imp
352324506b9SEric Fiselier{
353324506b9SEric Fiselier  template <class _Tp>
354e2f2d1edSEric Fiselier  struct _LIBCPP_TEMPLATE_VIS _SmallHandler
355324506b9SEric Fiselier  {
356324506b9SEric Fiselier     _LIBCPP_INLINE_VISIBILITY
357324506b9SEric Fiselier     static void* __handle(_Action __act, any const * __this, any * __other,
358324506b9SEric Fiselier                           type_info const * __info, const void* __fallback_info)
359324506b9SEric Fiselier     {
360324506b9SEric Fiselier        switch (__act)
361324506b9SEric Fiselier        {
362324506b9SEric Fiselier        case _Action::_Destroy:
363324506b9SEric Fiselier          __destroy(const_cast<any &>(*__this));
364324506b9SEric Fiselier          return nullptr;
365324506b9SEric Fiselier        case _Action::_Copy:
366324506b9SEric Fiselier            __copy(*__this, *__other);
367324506b9SEric Fiselier            return nullptr;
368324506b9SEric Fiselier        case _Action::_Move:
369324506b9SEric Fiselier          __move(const_cast<any &>(*__this), *__other);
370324506b9SEric Fiselier          return nullptr;
371324506b9SEric Fiselier        case _Action::_Get:
372324506b9SEric Fiselier            return __get(const_cast<any &>(*__this), __info, __fallback_info);
373324506b9SEric Fiselier        case _Action::_TypeInfo:
374324506b9SEric Fiselier          return __type_info();
375324506b9SEric Fiselier        }
376e39095a3SLouis Dionne        __libcpp_unreachable();
377324506b9SEric Fiselier    }
378324506b9SEric Fiselier
379324506b9SEric Fiselier    template <class ..._Args>
380324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
3815c80f4f6SMarshall Clow    static _Tp& __create(any & __dest, _Args&&... __args) {
38239c87951SMarshall Clow        typedef allocator<_Tp> _Alloc;
38339c87951SMarshall Clow        typedef allocator_traits<_Alloc> _ATraits;
38439c87951SMarshall Clow        _Alloc __a;
38539c87951SMarshall Clow        _Tp * __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s.__buf));
38639c87951SMarshall Clow        _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
387324506b9SEric Fiselier        __dest.__h = &_SmallHandler::__handle;
3885c80f4f6SMarshall Clow        return *__ret;
389324506b9SEric Fiselier    }
390324506b9SEric Fiselier
391324506b9SEric Fiselier  private:
392324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
393324506b9SEric Fiselier    static void __destroy(any & __this) {
39439c87951SMarshall Clow        typedef allocator<_Tp> _Alloc;
39539c87951SMarshall Clow        typedef allocator_traits<_Alloc> _ATraits;
39639c87951SMarshall Clow        _Alloc __a;
39739c87951SMarshall Clow        _Tp * __p = static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
39839c87951SMarshall Clow        _ATraits::destroy(__a, __p);
399324506b9SEric Fiselier        __this.__h = nullptr;
400324506b9SEric Fiselier    }
401324506b9SEric Fiselier
402324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
403324506b9SEric Fiselier    static void __copy(any const & __this, any & __dest) {
404324506b9SEric Fiselier        _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
405324506b9SEric Fiselier            static_cast<void const *>(&__this.__s.__buf)));
406324506b9SEric Fiselier    }
407324506b9SEric Fiselier
408324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
409324506b9SEric Fiselier    static void __move(any & __this, any & __dest) {
410324506b9SEric Fiselier        _SmallHandler::__create(__dest, _VSTD::move(
411324506b9SEric Fiselier            *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
412324506b9SEric Fiselier        __destroy(__this);
413324506b9SEric Fiselier    }
414324506b9SEric Fiselier
415324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
416324506b9SEric Fiselier    static void* __get(any & __this,
417324506b9SEric Fiselier                       type_info const * __info,
418324506b9SEric Fiselier                       const void* __fallback_id)
419324506b9SEric Fiselier    {
420324506b9SEric Fiselier        if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
421324506b9SEric Fiselier            return static_cast<void*>(&__this.__s.__buf);
422324506b9SEric Fiselier        return nullptr;
423324506b9SEric Fiselier    }
424324506b9SEric Fiselier
425324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
426324506b9SEric Fiselier    static void* __type_info()
427324506b9SEric Fiselier    {
428324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI)
429324506b9SEric Fiselier        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
430324506b9SEric Fiselier#else
431324506b9SEric Fiselier        return nullptr;
432324506b9SEric Fiselier#endif
433324506b9SEric Fiselier    }
434324506b9SEric Fiselier  };
435324506b9SEric Fiselier
436324506b9SEric Fiselier  template <class _Tp>
437e2f2d1edSEric Fiselier  struct _LIBCPP_TEMPLATE_VIS _LargeHandler
438324506b9SEric Fiselier  {
439324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
440324506b9SEric Fiselier    static void* __handle(_Action __act, any const * __this,
441324506b9SEric Fiselier                          any * __other, type_info const * __info,
442324506b9SEric Fiselier                          void const* __fallback_info)
443324506b9SEric Fiselier    {
444324506b9SEric Fiselier        switch (__act)
445324506b9SEric Fiselier        {
446324506b9SEric Fiselier        case _Action::_Destroy:
447324506b9SEric Fiselier          __destroy(const_cast<any &>(*__this));
448324506b9SEric Fiselier          return nullptr;
449324506b9SEric Fiselier        case _Action::_Copy:
450324506b9SEric Fiselier          __copy(*__this, *__other);
451324506b9SEric Fiselier          return nullptr;
452324506b9SEric Fiselier        case _Action::_Move:
453324506b9SEric Fiselier          __move(const_cast<any &>(*__this), *__other);
454324506b9SEric Fiselier          return nullptr;
455324506b9SEric Fiselier        case _Action::_Get:
456324506b9SEric Fiselier            return __get(const_cast<any &>(*__this), __info, __fallback_info);
457324506b9SEric Fiselier        case _Action::_TypeInfo:
458324506b9SEric Fiselier          return __type_info();
459324506b9SEric Fiselier        }
460e39095a3SLouis Dionne        __libcpp_unreachable();
461324506b9SEric Fiselier    }
462324506b9SEric Fiselier
463324506b9SEric Fiselier    template <class ..._Args>
464324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
4655c80f4f6SMarshall Clow    static _Tp& __create(any & __dest, _Args&&... __args) {
466324506b9SEric Fiselier        typedef allocator<_Tp> _Alloc;
46739c87951SMarshall Clow        typedef allocator_traits<_Alloc> _ATraits;
468324506b9SEric Fiselier        typedef __allocator_destructor<_Alloc> _Dp;
469324506b9SEric Fiselier        _Alloc __a;
47039c87951SMarshall Clow        unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
47139c87951SMarshall Clow        _Tp * __ret = __hold.get();
47239c87951SMarshall Clow        _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
473324506b9SEric Fiselier        __dest.__s.__ptr = __hold.release();
474324506b9SEric Fiselier        __dest.__h = &_LargeHandler::__handle;
4755c80f4f6SMarshall Clow        return *__ret;
476324506b9SEric Fiselier    }
477324506b9SEric Fiselier
478324506b9SEric Fiselier  private:
479324506b9SEric Fiselier
480324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
481324506b9SEric Fiselier    static void __destroy(any & __this){
48239c87951SMarshall Clow        typedef allocator<_Tp> _Alloc;
48339c87951SMarshall Clow        typedef allocator_traits<_Alloc> _ATraits;
48439c87951SMarshall Clow        _Alloc __a;
48539c87951SMarshall Clow        _Tp * __p = static_cast<_Tp *>(__this.__s.__ptr);
48639c87951SMarshall Clow        _ATraits::destroy(__a, __p);
48739c87951SMarshall Clow        _ATraits::deallocate(__a, __p, 1);
488324506b9SEric Fiselier        __this.__h = nullptr;
489324506b9SEric Fiselier    }
490324506b9SEric Fiselier
491324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
492324506b9SEric Fiselier    static void __copy(any const & __this, any & __dest) {
493324506b9SEric Fiselier        _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
494324506b9SEric Fiselier    }
495324506b9SEric Fiselier
496324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
497324506b9SEric Fiselier    static void __move(any & __this, any & __dest) {
498324506b9SEric Fiselier      __dest.__s.__ptr = __this.__s.__ptr;
499324506b9SEric Fiselier      __dest.__h = &_LargeHandler::__handle;
500324506b9SEric Fiselier      __this.__h = nullptr;
501324506b9SEric Fiselier    }
502324506b9SEric Fiselier
503324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
504324506b9SEric Fiselier    static void* __get(any & __this, type_info const * __info,
505324506b9SEric Fiselier                       void const* __fallback_info)
506324506b9SEric Fiselier    {
507324506b9SEric Fiselier        if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
508324506b9SEric Fiselier            return static_cast<void*>(__this.__s.__ptr);
509324506b9SEric Fiselier        return nullptr;
510324506b9SEric Fiselier
511324506b9SEric Fiselier    }
512324506b9SEric Fiselier
513324506b9SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
514324506b9SEric Fiselier    static void* __type_info()
515324506b9SEric Fiselier    {
516324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI)
517324506b9SEric Fiselier        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
518324506b9SEric Fiselier#else
519324506b9SEric Fiselier        return nullptr;
520324506b9SEric Fiselier#endif
521324506b9SEric Fiselier    }
522324506b9SEric Fiselier  };
523324506b9SEric Fiselier
524324506b9SEric Fiselier} // namespace __any_imp
525324506b9SEric Fiselier
526324506b9SEric Fiselier
527b18fd965SEric Fiseliertemplate <class _ValueType, class _Tp, class>
528324506b9SEric Fiselierany::any(_ValueType && __v) : __h(nullptr)
529324506b9SEric Fiselier{
530b18fd965SEric Fiselier  __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
531324506b9SEric Fiselier}
532324506b9SEric Fiselier
533b18fd965SEric Fiseliertemplate <class _ValueType, class ..._Args, class _Tp, class>
534b18fd965SEric Fiselierany::any(in_place_type_t<_ValueType>, _Args&&... __args) {
535b18fd965SEric Fiselier  __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
536205ead8cSLouis Dionne}
537324506b9SEric Fiselier
538b18fd965SEric Fiseliertemplate <class _ValueType, class _Up, class ..._Args, class _Tp, class>
539b18fd965SEric Fiselierany::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
540b18fd965SEric Fiselier  __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
541324506b9SEric Fiselier}
542324506b9SEric Fiselier
543b18fd965SEric Fiseliertemplate <class _ValueType, class, class>
544324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
545324506b9SEric Fiselierany & any::operator=(_ValueType && __v)
546324506b9SEric Fiselier{
547324506b9SEric Fiselier  any(_VSTD::forward<_ValueType>(__v)).swap(*this);
548324506b9SEric Fiselier  return *this;
549324506b9SEric Fiselier}
550324506b9SEric Fiselier
551b18fd965SEric Fiseliertemplate <class _ValueType, class ..._Args, class _Tp, class>
552324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
5535c80f4f6SMarshall Clow_Tp& any::emplace(_Args&&... __args) {
554324506b9SEric Fiselier  reset();
5555c80f4f6SMarshall Clow  return __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
556324506b9SEric Fiselier}
557324506b9SEric Fiselier
558b18fd965SEric Fiseliertemplate <class _ValueType, class _Up, class ..._Args, class _Tp, class>
559324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
5605c80f4f6SMarshall Clow_Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
561324506b9SEric Fiselier  reset();
5625c80f4f6SMarshall Clow  return __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
563324506b9SEric Fiselier}
564324506b9SEric Fiselier
565324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
566324506b9SEric Fiseliervoid any::swap(any & __rhs) _NOEXCEPT
567324506b9SEric Fiselier{
568b18fd965SEric Fiselier    if (this == &__rhs)
569b18fd965SEric Fiselier      return;
570324506b9SEric Fiselier    if (__h && __rhs.__h) {
571324506b9SEric Fiselier        any __tmp;
572324506b9SEric Fiselier        __rhs.__call(_Action::_Move, &__tmp);
573324506b9SEric Fiselier        this->__call(_Action::_Move, &__rhs);
574324506b9SEric Fiselier        __tmp.__call(_Action::_Move, this);
575324506b9SEric Fiselier    }
576324506b9SEric Fiselier    else if (__h) {
577324506b9SEric Fiselier        this->__call(_Action::_Move, &__rhs);
578324506b9SEric Fiselier    }
579324506b9SEric Fiselier    else if (__rhs.__h) {
580324506b9SEric Fiselier        __rhs.__call(_Action::_Move, this);
581324506b9SEric Fiselier    }
582324506b9SEric Fiselier}
583324506b9SEric Fiselier
584324506b9SEric Fiselier// 6.4 Non-member functions
585324506b9SEric Fiselier
586324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
587324506b9SEric Fiseliervoid swap(any & __lhs, any & __rhs) _NOEXCEPT
588324506b9SEric Fiselier{
589324506b9SEric Fiselier    __lhs.swap(__rhs);
590324506b9SEric Fiselier}
591324506b9SEric Fiselier
592324506b9SEric Fiseliertemplate <class _Tp, class ..._Args>
593324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
594324506b9SEric Fiselierany make_any(_Args&&... __args) {
595034555f1SEric Fiselier    return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...);
596324506b9SEric Fiselier}
597324506b9SEric Fiselier
598324506b9SEric Fiseliertemplate <class _Tp, class _Up, class ..._Args>
599324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
600324506b9SEric Fiselierany make_any(initializer_list<_Up> __il, _Args&&... __args) {
601034555f1SEric Fiselier    return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...);
602324506b9SEric Fiselier}
603324506b9SEric Fiselier
604324506b9SEric Fiseliertemplate <class _ValueType>
605324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
6068a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
607324506b9SEric Fiselier_ValueType any_cast(any const & __v)
608324506b9SEric Fiselier{
609b18fd965SEric Fiselier    using _RawValueType = __uncvref_t<_ValueType>;
610b18fd965SEric Fiselier    static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
6119c737fddSEric Fiselier                  "ValueType is required to be a const lvalue reference "
6129c737fddSEric Fiselier                  "or a CopyConstructible type");
613b18fd965SEric Fiselier    auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
614324506b9SEric Fiselier    if (__tmp == nullptr)
6150fc8cec7SMarshall Clow        __throw_bad_any_cast();
616b18fd965SEric Fiselier    return static_cast<_ValueType>(*__tmp);
617324506b9SEric Fiselier}
618324506b9SEric Fiselier
619324506b9SEric Fiseliertemplate <class _ValueType>
620324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
6218a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
622324506b9SEric Fiselier_ValueType any_cast(any & __v)
623324506b9SEric Fiselier{
624b18fd965SEric Fiselier    using _RawValueType = __uncvref_t<_ValueType>;
625b18fd965SEric Fiselier    static_assert(is_constructible<_ValueType, _RawValueType &>::value,
6269c737fddSEric Fiselier                  "ValueType is required to be an lvalue reference "
6279c737fddSEric Fiselier                  "or a CopyConstructible type");
628b18fd965SEric Fiselier    auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
629324506b9SEric Fiselier    if (__tmp == nullptr)
6300fc8cec7SMarshall Clow        __throw_bad_any_cast();
631b18fd965SEric Fiselier    return static_cast<_ValueType>(*__tmp);
632324506b9SEric Fiselier}
633324506b9SEric Fiselier
634324506b9SEric Fiseliertemplate <class _ValueType>
635324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
6368a063df1SLouis Dionne_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
637324506b9SEric Fiselier_ValueType any_cast(any && __v)
638324506b9SEric Fiselier{
639b18fd965SEric Fiselier    using _RawValueType = __uncvref_t<_ValueType>;
640b18fd965SEric Fiselier    static_assert(is_constructible<_ValueType, _RawValueType>::value,
6419c737fddSEric Fiselier                  "ValueType is required to be an rvalue reference "
6429c737fddSEric Fiselier                  "or a CopyConstructible type");
643b18fd965SEric Fiselier    auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
644324506b9SEric Fiselier    if (__tmp == nullptr)
6450fc8cec7SMarshall Clow        __throw_bad_any_cast();
646b18fd965SEric Fiselier    return static_cast<_ValueType>(_VSTD::move(*__tmp));
647324506b9SEric Fiselier}
648324506b9SEric Fiselier
649324506b9SEric Fiseliertemplate <class _ValueType>
650324506b9SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
651324506b9SEric Fiselieradd_pointer_t<add_const_t<_ValueType>>
652324506b9SEric Fiselierany_cast(any const * __any) _NOEXCEPT
653324506b9SEric Fiselier{
654324506b9SEric Fiselier    static_assert(!is_reference<_ValueType>::value,
655324506b9SEric Fiselier                  "_ValueType may not be a reference.");
656324506b9SEric Fiselier    return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any));
657324506b9SEric Fiselier}
658324506b9SEric Fiselier
659c5777f4dSEric Fiseliertemplate <class _RetType>
660c5777f4dSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
661c5777f4dSEric Fiselier_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept {
662c5777f4dSEric Fiselier  return static_cast<_RetType>(__p);
663c5777f4dSEric Fiselier}
664c5777f4dSEric Fiselier
665c5777f4dSEric Fiseliertemplate <class _RetType>
666c5777f4dSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
667c5777f4dSEric Fiselier_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept {
668c5777f4dSEric Fiselier  return nullptr;
669c5777f4dSEric Fiselier}
670c5777f4dSEric Fiselier
671324506b9SEric Fiseliertemplate <class _ValueType>
672c358d98bSLouis Dionne_LIBCPP_HIDE_FROM_ABI
673324506b9SEric Fiselieradd_pointer_t<_ValueType>
674324506b9SEric Fiselierany_cast(any * __any) _NOEXCEPT
675324506b9SEric Fiselier{
676324506b9SEric Fiselier    using __any_imp::_Action;
677324506b9SEric Fiselier    static_assert(!is_reference<_ValueType>::value,
678324506b9SEric Fiselier                  "_ValueType may not be a reference.");
679324506b9SEric Fiselier    typedef typename add_pointer<_ValueType>::type _ReturnType;
680324506b9SEric Fiselier    if (__any && __any->__h) {
681c5777f4dSEric Fiselier      void *__p = __any->__call(_Action::_Get, nullptr,
682324506b9SEric Fiselier#if !defined(_LIBCPP_NO_RTTI)
683324506b9SEric Fiselier                          &typeid(_ValueType),
684324506b9SEric Fiselier#else
685324506b9SEric Fiselier                          nullptr,
686324506b9SEric Fiselier#endif
687c5777f4dSEric Fiselier                          __any_imp::__get_fallback_typeid<_ValueType>());
688c5777f4dSEric Fiselier        return _VSTD::__pointer_or_func_cast<_ReturnType>(
689c5777f4dSEric Fiselier            __p, is_function<_ValueType>{});
690324506b9SEric Fiselier    }
691324506b9SEric Fiselier    return nullptr;
692324506b9SEric Fiselier}
693324506b9SEric Fiselier
694324506b9SEric Fiselier#endif // _LIBCPP_STD_VER > 14
695324506b9SEric Fiselier
696324506b9SEric Fiselier_LIBCPP_END_NAMESPACE_STD
697324506b9SEric Fiselier
698324506b9SEric Fiselier#endif // _LIBCPP_ANY
699