xref: /freebsd/contrib/llvm-project/libcxx/include/any (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_ANY
110b57cec5SDimitry Andric#define _LIBCPP_ANY
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric   any synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std {
170b57cec5SDimitry Andric
180b57cec5SDimitry Andric  class bad_any_cast : public bad_cast
190b57cec5SDimitry Andric  {
200b57cec5SDimitry Andric  public:
210b57cec5SDimitry Andric    virtual const char* what() const noexcept;
220b57cec5SDimitry Andric  };
230b57cec5SDimitry Andric
240b57cec5SDimitry Andric  class any
250b57cec5SDimitry Andric  {
260b57cec5SDimitry Andric  public:
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric    // 6.3.1 any construct/destruct
290b57cec5SDimitry Andric    any() noexcept;
300b57cec5SDimitry Andric
310b57cec5SDimitry Andric    any(const any& other);
320b57cec5SDimitry Andric    any(any&& other) noexcept;
330b57cec5SDimitry Andric
340b57cec5SDimitry Andric    template <class ValueType>
350b57cec5SDimitry Andric      any(ValueType&& value);
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric    ~any();
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric    // 6.3.2 any assignments
400b57cec5SDimitry Andric    any& operator=(const any& rhs);
410b57cec5SDimitry Andric    any& operator=(any&& rhs) noexcept;
420b57cec5SDimitry Andric
430b57cec5SDimitry Andric    template <class ValueType>
440b57cec5SDimitry Andric      any& operator=(ValueType&& rhs);
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric    // 6.3.3 any modifiers
470b57cec5SDimitry Andric    template <class ValueType, class... Args>
480b57cec5SDimitry Andric      decay_t<ValueType>& emplace(Args&&... args);
490b57cec5SDimitry Andric    template <class ValueType, class U, class... Args>
500b57cec5SDimitry Andric      decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
510b57cec5SDimitry Andric    void reset() noexcept;
520b57cec5SDimitry Andric    void swap(any& rhs) noexcept;
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric    // 6.3.4 any observers
550b57cec5SDimitry Andric    bool has_value() const noexcept;
560b57cec5SDimitry Andric    const type_info& type() const noexcept;
570b57cec5SDimitry Andric  };
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric   // 6.4 Non-member functions
600b57cec5SDimitry Andric  void swap(any& x, any& y) noexcept;
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric  template <class T, class ...Args>
630b57cec5SDimitry Andric    any make_any(Args&& ...args);
640b57cec5SDimitry Andric  template <class T, class U, class ...Args>
650b57cec5SDimitry Andric    any make_any(initializer_list<U>, Args&& ...args);
660b57cec5SDimitry Andric
670b57cec5SDimitry Andric  template<class ValueType>
680b57cec5SDimitry Andric    ValueType any_cast(const any& operand);
690b57cec5SDimitry Andric  template<class ValueType>
700b57cec5SDimitry Andric    ValueType any_cast(any& operand);
710b57cec5SDimitry Andric  template<class ValueType>
720b57cec5SDimitry Andric    ValueType any_cast(any&& operand);
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric  template<class ValueType>
750b57cec5SDimitry Andric    const ValueType* any_cast(const any* operand) noexcept;
760b57cec5SDimitry Andric  template<class ValueType>
770b57cec5SDimitry Andric    ValueType* any_cast(any* operand) noexcept;
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric} // namespace std
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric*/
820b57cec5SDimitry Andric
83fe6060f1SDimitry Andric#include <__config>
84bdd1243dSDimitry Andric#include <__memory/allocator.h>
85bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h>
86bdd1243dSDimitry Andric#include <__memory/allocator_traits.h>
87bdd1243dSDimitry Andric#include <__memory/unique_ptr.h>
8806c3fb27SDimitry Andric#include <__type_traits/add_const.h>
8906c3fb27SDimitry Andric#include <__type_traits/add_pointer.h>
9006c3fb27SDimitry Andric#include <__type_traits/aligned_storage.h>
9106c3fb27SDimitry Andric#include <__type_traits/conditional.h>
9206c3fb27SDimitry Andric#include <__type_traits/decay.h>
9306c3fb27SDimitry Andric#include <__type_traits/is_constructible.h>
9406c3fb27SDimitry Andric#include <__type_traits/is_function.h>
95*0fca6ea1SDimitry Andric#include <__type_traits/is_nothrow_constructible.h>
9606c3fb27SDimitry Andric#include <__type_traits/is_reference.h>
9706c3fb27SDimitry Andric#include <__type_traits/is_same.h>
987a6dacacSDimitry Andric#include <__type_traits/is_void.h>
9906c3fb27SDimitry Andric#include <__type_traits/remove_cv.h>
10006c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h>
10106c3fb27SDimitry Andric#include <__type_traits/remove_reference.h>
102fe6060f1SDimitry Andric#include <__utility/forward.h>
10381ad6265SDimitry Andric#include <__utility/in_place.h>
10481ad6265SDimitry Andric#include <__utility/move.h>
10581ad6265SDimitry Andric#include <__utility/unreachable.h>
10606c3fb27SDimitry Andric#include <__verbose_abort>
10781ad6265SDimitry Andric#include <initializer_list>
108fe6060f1SDimitry Andric#include <typeinfo>
1090b57cec5SDimitry Andric#include <version>
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1120b57cec5SDimitry Andric#  pragma GCC system_header
1130b57cec5SDimitry Andric#endif
1140b57cec5SDimitry Andric
11506c3fb27SDimitry Andric_LIBCPP_PUSH_MACROS
11606c3fb27SDimitry Andric#include <__undef_macros>
11706c3fb27SDimitry Andric
1180b57cec5SDimitry Andricnamespace std {
119cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast {
1200b57cec5SDimitry Andricpublic:
121bdd1243dSDimitry Andric  const char* what() const _NOEXCEPT override;
1220b57cec5SDimitry Andric};
1230b57cec5SDimitry Andric} // namespace std
1240b57cec5SDimitry Andric
1250b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
1260b57cec5SDimitry Andric
12706c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1280b57cec5SDimitry Andric
129cb14a3feSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST void __throw_bad_any_cast() {
13006c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1310b57cec5SDimitry Andric  throw bad_any_cast();
1320b57cec5SDimitry Andric#  else
13306c3fb27SDimitry Andric  _LIBCPP_VERBOSE_ABORT("bad_any_cast was thrown in -fno-exceptions mode");
1340b57cec5SDimitry Andric#  endif
1350b57cec5SDimitry Andric}
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric// Forward declarations
1380b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS any;
1390b57cec5SDimitry Andric
1400b57cec5SDimitry Andrictemplate <class _ValueType>
141cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT;
1420b57cec5SDimitry Andric
1430b57cec5SDimitry Andrictemplate <class _ValueType>
144cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;
1450b57cec5SDimitry Andric
146cb14a3feSDimitry Andricnamespace __any_imp {
147bdd1243dSDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1485f757f3fSDimitry Andricusing _Buffer = aligned_storage_t<3 * sizeof(void*), alignof(void*)>;
149bdd1243dSDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_POP
1500b57cec5SDimitry Andric
1510b57cec5SDimitry Andrictemplate <class _Tp>
152cb14a3feSDimitry Andricusing _IsSmallObject =
153cb14a3feSDimitry Andric    integral_constant<bool,
154cb14a3feSDimitry Andric                      sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 &&
155cb14a3feSDimitry Andric                          is_nothrow_move_constructible<_Tp>::value >;
1560b57cec5SDimitry Andric
157cb14a3feSDimitry Andricenum class _Action { _Destroy, _Copy, _Move, _Get, _TypeInfo };
158cb14a3feSDimitry Andric
159cb14a3feSDimitry Andrictemplate <class _Tp>
160cb14a3feSDimitry Andricstruct _SmallHandler;
161cb14a3feSDimitry Andrictemplate <class _Tp>
162cb14a3feSDimitry Andricstruct _LargeHandler;
163cb14a3feSDimitry Andric
164cb14a3feSDimitry Andrictemplate <class _Tp>
165cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __unique_typeinfo {
166cb14a3feSDimitry Andric  static constexpr int __id = 0;
1670b57cec5SDimitry Andric};
168cb14a3feSDimitry Andrictemplate <class _Tp>
169cb14a3feSDimitry Andricconstexpr int __unique_typeinfo<_Tp>::__id;
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andrictemplate <class _Tp>
172cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr const void* __get_fallback_typeid() {
173e8d8bef9SDimitry Andric  return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id;
1740b57cec5SDimitry Andric}
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andrictemplate <class _Tp>
177cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool __compare_typeid(type_info const* __id, const void* __fallback_id) {
1781ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
1790b57cec5SDimitry Andric  if (__id && *__id == typeid(_Tp))
1800b57cec5SDimitry Andric    return true;
1810b57cec5SDimitry Andric#  endif
1825f757f3fSDimitry Andric  return !__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>();
1830b57cec5SDimitry Andric}
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andrictemplate <class _Tp>
186cb14a3feSDimitry Andricusing _Handler = conditional_t< _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric} // namespace __any_imp
1890b57cec5SDimitry Andric
190cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS any {
1910b57cec5SDimitry Andricpublic:
1920b57cec5SDimitry Andric  // construct/destruct
193cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI constexpr any() _NOEXCEPT : __h_(nullptr) {}
1940b57cec5SDimitry Andric
195cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any(any const& __other) : __h_(nullptr) {
196cb14a3feSDimitry Andric    if (__other.__h_)
197cb14a3feSDimitry Andric      __other.__call(_Action::_Copy, this);
1980b57cec5SDimitry Andric  }
1990b57cec5SDimitry Andric
200cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any(any&& __other) _NOEXCEPT : __h_(nullptr) {
201cb14a3feSDimitry Andric    if (__other.__h_)
202cb14a3feSDimitry Andric      __other.__call(_Action::_Move, this);
2030b57cec5SDimitry Andric  }
2040b57cec5SDimitry Andric
205cb14a3feSDimitry Andric  template < class _ValueType,
2060b57cec5SDimitry Andric             class _Tp = decay_t<_ValueType>,
207cb14a3feSDimitry Andric             class     = enable_if_t< !is_same<_Tp, any>::value && !__is_inplace_type<_ValueType>::value &&
208cb14a3feSDimitry Andric                                      is_copy_constructible<_Tp>::value> >
209cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any(_ValueType&& __value);
2100b57cec5SDimitry Andric
211cb14a3feSDimitry Andric  template <class _ValueType,
212cb14a3feSDimitry Andric            class... _Args,
2130b57cec5SDimitry Andric            class _Tp = decay_t<_ValueType>,
214cb14a3feSDimitry Andric            class     = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value > >
215cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
2160b57cec5SDimitry Andric
217cb14a3feSDimitry Andric  template <class _ValueType,
218cb14a3feSDimitry Andric            class _Up,
219cb14a3feSDimitry Andric            class... _Args,
220cb14a3feSDimitry Andric            class _Tp = decay_t<_ValueType>,
221cb14a3feSDimitry Andric            class     = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
222cb14a3feSDimitry Andric                                     is_copy_constructible<_Tp>::value> >
223cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
224cb14a3feSDimitry Andric
225cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~any() { this->reset(); }
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric  // assignments
228cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any& operator=(any const& __rhs) {
2290b57cec5SDimitry Andric    any(__rhs).swap(*this);
2300b57cec5SDimitry Andric    return *this;
2310b57cec5SDimitry Andric  }
2320b57cec5SDimitry Andric
233cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any& operator=(any&& __rhs) _NOEXCEPT {
2345f757f3fSDimitry Andric    any(std::move(__rhs)).swap(*this);
2350b57cec5SDimitry Andric    return *this;
2360b57cec5SDimitry Andric  }
2370b57cec5SDimitry Andric
238cb14a3feSDimitry Andric  template < class _ValueType,
2390b57cec5SDimitry Andric             class _Tp = decay_t<_ValueType>,
240cb14a3feSDimitry Andric             class     = enable_if_t< !is_same<_Tp, any>::value && is_copy_constructible<_Tp>::value> >
241cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any& operator=(_ValueType&& __rhs);
2420b57cec5SDimitry Andric
243cb14a3feSDimitry Andric  template <class _ValueType,
244cb14a3feSDimitry Andric            class... _Args,
2450b57cec5SDimitry Andric            class _Tp = decay_t<_ValueType>,
246cb14a3feSDimitry Andric            class     = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value> >
247cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Tp& emplace(_Args&&...);
248cb14a3feSDimitry Andric
249cb14a3feSDimitry Andric  template <class _ValueType,
250cb14a3feSDimitry Andric            class _Up,
251cb14a3feSDimitry Andric            class... _Args,
252cb14a3feSDimitry Andric            class _Tp = decay_t<_ValueType>,
253cb14a3feSDimitry Andric            class     = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
254cb14a3feSDimitry Andric                                     is_copy_constructible<_Tp>::value> >
255cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Tp& emplace(initializer_list<_Up>, _Args&&...);
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric  // 6.3.3 any modifiers
258cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT {
259cb14a3feSDimitry Andric    if (__h_)
260cb14a3feSDimitry Andric      this->__call(_Action::_Destroy);
261cb14a3feSDimitry Andric  }
2620b57cec5SDimitry Andric
263cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) _NOEXCEPT;
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andric  // 6.3.4 any observers
266cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; }
2670b57cec5SDimitry Andric
2681ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
269cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT {
270bdd1243dSDimitry Andric    if (__h_) {
2710b57cec5SDimitry Andric      return *static_cast<type_info const*>(this->__call(_Action::_TypeInfo));
2720b57cec5SDimitry Andric    } else {
2730b57cec5SDimitry Andric      return typeid(void);
2740b57cec5SDimitry Andric    }
2750b57cec5SDimitry Andric  }
2760b57cec5SDimitry Andric#  endif
2770b57cec5SDimitry Andric
2780b57cec5SDimitry Andricprivate:
2790b57cec5SDimitry Andric  typedef __any_imp::_Action _Action;
280cb14a3feSDimitry Andric  using _HandleFuncPtr = void* (*)(_Action, any const*, any*, const type_info*, const void* __fallback_info);
2810b57cec5SDimitry Andric
2820b57cec5SDimitry Andric  union _Storage {
28306c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}
2840b57cec5SDimitry Andric    void* __ptr;
2850b57cec5SDimitry Andric    __any_imp::_Buffer __buf;
2860b57cec5SDimitry Andric  };
2870b57cec5SDimitry Andric
288cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void*
289cb14a3feSDimitry Andric  __call(_Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr)
290cb14a3feSDimitry Andric      const {
291bdd1243dSDimitry Andric    return __h_(__a, this, __other, __info, __fallback_info);
2920b57cec5SDimitry Andric  }
2930b57cec5SDimitry Andric
294cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void* __call(
295cb14a3feSDimitry Andric      _Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr) {
296bdd1243dSDimitry Andric    return __h_(__a, this, __other, __info, __fallback_info);
2970b57cec5SDimitry Andric  }
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric  template <class>
3000b57cec5SDimitry Andric  friend struct __any_imp::_SmallHandler;
3010b57cec5SDimitry Andric  template <class>
3020b57cec5SDimitry Andric  friend struct __any_imp::_LargeHandler;
3030b57cec5SDimitry Andric
3040b57cec5SDimitry Andric  template <class _ValueType>
305cb14a3feSDimitry Andric  friend add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT;
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric  template <class _ValueType>
308cb14a3feSDimitry Andric  friend add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;
3090b57cec5SDimitry Andric
310bdd1243dSDimitry Andric  _HandleFuncPtr __h_ = nullptr;
311bdd1243dSDimitry Andric  _Storage __s_;
3120b57cec5SDimitry Andric};
3130b57cec5SDimitry Andric
314cb14a3feSDimitry Andricnamespace __any_imp {
3150b57cec5SDimitry Andrictemplate <class _Tp>
316cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS _SmallHandler {
317cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void*
318cb14a3feSDimitry Andric  __handle(_Action __act, any const* __this, any* __other, type_info const* __info, const void* __fallback_info) {
319cb14a3feSDimitry Andric    switch (__act) {
3200b57cec5SDimitry Andric    case _Action::_Destroy:
3210b57cec5SDimitry Andric      __destroy(const_cast<any&>(*__this));
3220b57cec5SDimitry Andric      return nullptr;
3230b57cec5SDimitry Andric    case _Action::_Copy:
3240b57cec5SDimitry Andric      __copy(*__this, *__other);
3250b57cec5SDimitry Andric      return nullptr;
3260b57cec5SDimitry Andric    case _Action::_Move:
3270b57cec5SDimitry Andric      __move(const_cast<any&>(*__this), *__other);
3280b57cec5SDimitry Andric      return nullptr;
3290b57cec5SDimitry Andric    case _Action::_Get:
3300b57cec5SDimitry Andric      return __get(const_cast<any&>(*__this), __info, __fallback_info);
3310b57cec5SDimitry Andric    case _Action::_TypeInfo:
3320b57cec5SDimitry Andric      return __type_info();
3330b57cec5SDimitry Andric    }
33481ad6265SDimitry Andric    __libcpp_unreachable();
3350b57cec5SDimitry Andric  }
3360b57cec5SDimitry Andric
3370b57cec5SDimitry Andric  template <class... _Args>
338cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
339e8d8bef9SDimitry Andric    typedef allocator<_Tp> _Alloc;
340e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _ATraits;
341e8d8bef9SDimitry Andric    _Alloc __a;
342bdd1243dSDimitry Andric    _Tp* __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s_.__buf));
3435f757f3fSDimitry Andric    _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...);
344bdd1243dSDimitry Andric    __dest.__h_ = &_SmallHandler::__handle;
3450b57cec5SDimitry Andric    return *__ret;
3460b57cec5SDimitry Andric  }
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andricprivate:
349cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
350e8d8bef9SDimitry Andric    typedef allocator<_Tp> _Alloc;
351e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _ATraits;
352e8d8bef9SDimitry Andric    _Alloc __a;
353bdd1243dSDimitry Andric    _Tp* __p = static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf));
354e8d8bef9SDimitry Andric    _ATraits::destroy(__a, __p);
355bdd1243dSDimitry Andric    __this.__h_ = nullptr;
3560b57cec5SDimitry Andric  }
3570b57cec5SDimitry Andric
358cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) {
359cb14a3feSDimitry Andric    _SmallHandler::__create(__dest, *static_cast<_Tp const*>(static_cast<void const*>(&__this.__s_.__buf)));
3600b57cec5SDimitry Andric  }
3610b57cec5SDimitry Andric
362cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) {
363cb14a3feSDimitry Andric    _SmallHandler::__create(__dest, std::move(*static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf))));
3640b57cec5SDimitry Andric    __destroy(__this);
3650b57cec5SDimitry Andric  }
3660b57cec5SDimitry Andric
367cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, const void* __fallback_id) {
3680b57cec5SDimitry Andric    if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
369bdd1243dSDimitry Andric      return static_cast<void*>(&__this.__s_.__buf);
3700b57cec5SDimitry Andric    return nullptr;
3710b57cec5SDimitry Andric  }
3720b57cec5SDimitry Andric
373cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
3741ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
3750b57cec5SDimitry Andric    return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
3760b57cec5SDimitry Andric#  else
3770b57cec5SDimitry Andric    return nullptr;
3780b57cec5SDimitry Andric#  endif
3790b57cec5SDimitry Andric  }
3800b57cec5SDimitry Andric};
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andrictemplate <class _Tp>
383cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS _LargeHandler {
384cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void*
385cb14a3feSDimitry Andric  __handle(_Action __act, any const* __this, any* __other, type_info const* __info, void const* __fallback_info) {
386cb14a3feSDimitry Andric    switch (__act) {
3870b57cec5SDimitry Andric    case _Action::_Destroy:
3880b57cec5SDimitry Andric      __destroy(const_cast<any&>(*__this));
3890b57cec5SDimitry Andric      return nullptr;
3900b57cec5SDimitry Andric    case _Action::_Copy:
3910b57cec5SDimitry Andric      __copy(*__this, *__other);
3920b57cec5SDimitry Andric      return nullptr;
3930b57cec5SDimitry Andric    case _Action::_Move:
3940b57cec5SDimitry Andric      __move(const_cast<any&>(*__this), *__other);
3950b57cec5SDimitry Andric      return nullptr;
3960b57cec5SDimitry Andric    case _Action::_Get:
3970b57cec5SDimitry Andric      return __get(const_cast<any&>(*__this), __info, __fallback_info);
3980b57cec5SDimitry Andric    case _Action::_TypeInfo:
3990b57cec5SDimitry Andric      return __type_info();
4000b57cec5SDimitry Andric    }
40181ad6265SDimitry Andric    __libcpp_unreachable();
4020b57cec5SDimitry Andric  }
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric  template <class... _Args>
405cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
4060b57cec5SDimitry Andric    typedef allocator<_Tp> _Alloc;
407e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _ATraits;
4080b57cec5SDimitry Andric    typedef __allocator_destructor<_Alloc> _Dp;
4090b57cec5SDimitry Andric    _Alloc __a;
410e8d8bef9SDimitry Andric    unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
411e8d8bef9SDimitry Andric    _Tp* __ret = __hold.get();
4125f757f3fSDimitry Andric    _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...);
413bdd1243dSDimitry Andric    __dest.__s_.__ptr = __hold.release();
414bdd1243dSDimitry Andric    __dest.__h_       = &_LargeHandler::__handle;
4150b57cec5SDimitry Andric    return *__ret;
4160b57cec5SDimitry Andric  }
4170b57cec5SDimitry Andric
4180b57cec5SDimitry Andricprivate:
419cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
420e8d8bef9SDimitry Andric    typedef allocator<_Tp> _Alloc;
421e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _ATraits;
422e8d8bef9SDimitry Andric    _Alloc __a;
423bdd1243dSDimitry Andric    _Tp* __p = static_cast<_Tp*>(__this.__s_.__ptr);
424e8d8bef9SDimitry Andric    _ATraits::destroy(__a, __p);
425e8d8bef9SDimitry Andric    _ATraits::deallocate(__a, __p, 1);
426bdd1243dSDimitry Andric    __this.__h_ = nullptr;
4270b57cec5SDimitry Andric  }
4280b57cec5SDimitry Andric
429cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) {
430bdd1243dSDimitry Andric    _LargeHandler::__create(__dest, *static_cast<_Tp const*>(__this.__s_.__ptr));
4310b57cec5SDimitry Andric  }
4320b57cec5SDimitry Andric
433cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) {
434bdd1243dSDimitry Andric    __dest.__s_.__ptr = __this.__s_.__ptr;
435bdd1243dSDimitry Andric    __dest.__h_       = &_LargeHandler::__handle;
436bdd1243dSDimitry Andric    __this.__h_       = nullptr;
4370b57cec5SDimitry Andric  }
4380b57cec5SDimitry Andric
439cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, void const* __fallback_info) {
4400b57cec5SDimitry Andric    if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
441bdd1243dSDimitry Andric      return static_cast<void*>(__this.__s_.__ptr);
4420b57cec5SDimitry Andric    return nullptr;
4430b57cec5SDimitry Andric  }
4440b57cec5SDimitry Andric
445cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
4461ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
4470b57cec5SDimitry Andric    return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
4480b57cec5SDimitry Andric#  else
4490b57cec5SDimitry Andric    return nullptr;
4500b57cec5SDimitry Andric#  endif
4510b57cec5SDimitry Andric  }
4520b57cec5SDimitry Andric};
4530b57cec5SDimitry Andric
4540b57cec5SDimitry Andric} // namespace __any_imp
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andrictemplate <class _ValueType, class _Tp, class>
457cb14a3feSDimitry Andricany::any(_ValueType&& __v) : __h_(nullptr) {
4585f757f3fSDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__v));
4590b57cec5SDimitry Andric}
4600b57cec5SDimitry Andric
4610b57cec5SDimitry Andrictemplate <class _ValueType, class... _Args, class _Tp, class>
4620b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, _Args&&... __args) {
4635f757f3fSDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
4640b57cec5SDimitry Andric}
4650b57cec5SDimitry Andric
4660b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class... _Args, class _Tp, class>
4670b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
4685f757f3fSDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
4690b57cec5SDimitry Andric}
4700b57cec5SDimitry Andric
4710b57cec5SDimitry Andrictemplate <class _ValueType, class, class>
472cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any& any::operator=(_ValueType&& __v) {
4735f757f3fSDimitry Andric  any(std::forward<_ValueType>(__v)).swap(*this);
4740b57cec5SDimitry Andric  return *this;
4750b57cec5SDimitry Andric}
4760b57cec5SDimitry Andric
4770b57cec5SDimitry Andrictemplate <class _ValueType, class... _Args, class _Tp, class>
478cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(_Args&&... __args) {
4790b57cec5SDimitry Andric  reset();
4805f757f3fSDimitry Andric  return __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
4810b57cec5SDimitry Andric}
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class... _Args, class _Tp, class>
484cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
4850b57cec5SDimitry Andric  reset();
4865f757f3fSDimitry Andric  return __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
4870b57cec5SDimitry Andric}
4880b57cec5SDimitry Andric
489cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void any::swap(any& __rhs) _NOEXCEPT {
4900b57cec5SDimitry Andric  if (this == &__rhs)
4910b57cec5SDimitry Andric    return;
492bdd1243dSDimitry Andric  if (__h_ && __rhs.__h_) {
4930b57cec5SDimitry Andric    any __tmp;
4940b57cec5SDimitry Andric    __rhs.__call(_Action::_Move, &__tmp);
4950b57cec5SDimitry Andric    this->__call(_Action::_Move, &__rhs);
4960b57cec5SDimitry Andric    __tmp.__call(_Action::_Move, this);
497cb14a3feSDimitry Andric  } else if (__h_) {
4980b57cec5SDimitry Andric    this->__call(_Action::_Move, &__rhs);
499cb14a3feSDimitry Andric  } else if (__rhs.__h_) {
5000b57cec5SDimitry Andric    __rhs.__call(_Action::_Move, this);
5010b57cec5SDimitry Andric  }
5020b57cec5SDimitry Andric}
5030b57cec5SDimitry Andric
5040b57cec5SDimitry Andric// 6.4 Non-member functions
5050b57cec5SDimitry Andric
506cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) _NOEXCEPT { __lhs.swap(__rhs); }
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andrictemplate <class _Tp, class... _Args>
509cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) {
5105f757f3fSDimitry Andric  return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
5110b57cec5SDimitry Andric}
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andrictemplate <class _Tp, class _Up, class... _Args>
514cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) {
5155f757f3fSDimitry Andric  return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
5160b57cec5SDimitry Andric}
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andrictemplate <class _ValueType>
519cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any const& __v) {
520bdd1243dSDimitry Andric  using _RawValueType = __remove_cvref_t<_ValueType>;
5210b57cec5SDimitry Andric  static_assert(is_constructible<_ValueType, _RawValueType const&>::value,
5220b57cec5SDimitry Andric                "ValueType is required to be a const lvalue reference "
5230b57cec5SDimitry Andric                "or a CopyConstructible type");
5245f757f3fSDimitry Andric  auto __tmp = std::any_cast<add_const_t<_RawValueType>>(&__v);
5250b57cec5SDimitry Andric  if (__tmp == nullptr)
5260b57cec5SDimitry Andric    __throw_bad_any_cast();
5270b57cec5SDimitry Andric  return static_cast<_ValueType>(*__tmp);
5280b57cec5SDimitry Andric}
5290b57cec5SDimitry Andric
5300b57cec5SDimitry Andrictemplate <class _ValueType>
531cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any& __v) {
532bdd1243dSDimitry Andric  using _RawValueType = __remove_cvref_t<_ValueType>;
5330b57cec5SDimitry Andric  static_assert(is_constructible<_ValueType, _RawValueType&>::value,
5340b57cec5SDimitry Andric                "ValueType is required to be an lvalue reference "
5350b57cec5SDimitry Andric                "or a CopyConstructible type");
5365f757f3fSDimitry Andric  auto __tmp = std::any_cast<_RawValueType>(&__v);
5370b57cec5SDimitry Andric  if (__tmp == nullptr)
5380b57cec5SDimitry Andric    __throw_bad_any_cast();
5390b57cec5SDimitry Andric  return static_cast<_ValueType>(*__tmp);
5400b57cec5SDimitry Andric}
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andrictemplate <class _ValueType>
543cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any&& __v) {
544bdd1243dSDimitry Andric  using _RawValueType = __remove_cvref_t<_ValueType>;
5450b57cec5SDimitry Andric  static_assert(is_constructible<_ValueType, _RawValueType>::value,
5460b57cec5SDimitry Andric                "ValueType is required to be an rvalue reference "
5470b57cec5SDimitry Andric                "or a CopyConstructible type");
5485f757f3fSDimitry Andric  auto __tmp = std::any_cast<_RawValueType>(&__v);
5490b57cec5SDimitry Andric  if (__tmp == nullptr)
5500b57cec5SDimitry Andric    __throw_bad_any_cast();
5515f757f3fSDimitry Andric  return static_cast<_ValueType>(std::move(*__tmp));
5520b57cec5SDimitry Andric}
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andrictemplate <class _ValueType>
555cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT {
5567a6dacacSDimitry Andric  static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
557cb14a3feSDimitry Andric  static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
5585f757f3fSDimitry Andric  return std::any_cast<_ValueType>(const_cast<any*>(__any));
5590b57cec5SDimitry Andric}
5600b57cec5SDimitry Andric
5610b57cec5SDimitry Andrictemplate <class _RetType>
562cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/ false_type) noexcept {
5630b57cec5SDimitry Andric  return static_cast<_RetType>(__p);
5640b57cec5SDimitry Andric}
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andrictemplate <class _RetType>
567cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction*/ true_type) noexcept {
5680b57cec5SDimitry Andric  return nullptr;
5690b57cec5SDimitry Andric}
5700b57cec5SDimitry Andric
5710b57cec5SDimitry Andrictemplate <class _ValueType>
572cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT {
5730b57cec5SDimitry Andric  using __any_imp::_Action;
5747a6dacacSDimitry Andric  static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
575cb14a3feSDimitry Andric  static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
576bdd1243dSDimitry Andric  typedef add_pointer_t<_ValueType> _ReturnType;
577bdd1243dSDimitry Andric  if (__any && __any->__h_) {
578cb14a3feSDimitry Andric    void* __p = __any->__call(
579cb14a3feSDimitry Andric        _Action::_Get,
580cb14a3feSDimitry Andric        nullptr,
5811ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
5820b57cec5SDimitry Andric        &typeid(_ValueType),
5830b57cec5SDimitry Andric#  else
5840b57cec5SDimitry Andric        nullptr,
5850b57cec5SDimitry Andric#  endif
5860b57cec5SDimitry Andric        __any_imp::__get_fallback_typeid<_ValueType>());
587cb14a3feSDimitry Andric    return std::__pointer_or_func_cast<_ReturnType>(__p, is_function<_ValueType>{});
5880b57cec5SDimitry Andric  }
5890b57cec5SDimitry Andric  return nullptr;
5900b57cec5SDimitry Andric}
5910b57cec5SDimitry Andric
59206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 17
5930b57cec5SDimitry Andric
5940b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
5950b57cec5SDimitry Andric
59606c3fb27SDimitry Andric_LIBCPP_POP_MACROS
59706c3fb27SDimitry Andric
598bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
599bdd1243dSDimitry Andric#  include <chrono>
600bdd1243dSDimitry Andric#endif
601bdd1243dSDimitry Andric
602bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
603bdd1243dSDimitry Andric#  include <atomic>
604bdd1243dSDimitry Andric#  include <concepts>
60506c3fb27SDimitry Andric#  include <cstdlib>
606bdd1243dSDimitry Andric#  include <iosfwd>
607bdd1243dSDimitry Andric#  include <iterator>
608bdd1243dSDimitry Andric#  include <memory>
60906c3fb27SDimitry Andric#  include <stdexcept>
61006c3fb27SDimitry Andric#  include <type_traits>
611bdd1243dSDimitry Andric#  include <variant>
612bdd1243dSDimitry Andric#endif
613bdd1243dSDimitry Andric
6140b57cec5SDimitry Andric#endif // _LIBCPP_ANY
615