xref: /freebsd/contrib/llvm-project/libcxx/include/any (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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
8381ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
84e8d8bef9SDimitry Andric#include <__availability>
85fe6060f1SDimitry Andric#include <__config>
86bdd1243dSDimitry Andric#include <__memory/allocator.h>
87bdd1243dSDimitry Andric#include <__memory/allocator_destructor.h>
88bdd1243dSDimitry Andric#include <__memory/allocator_traits.h>
89bdd1243dSDimitry Andric#include <__memory/unique_ptr.h>
9006c3fb27SDimitry Andric#include <__type_traits/add_const.h>
9106c3fb27SDimitry Andric#include <__type_traits/add_pointer.h>
9206c3fb27SDimitry Andric#include <__type_traits/aligned_storage.h>
9306c3fb27SDimitry Andric#include <__type_traits/conditional.h>
9406c3fb27SDimitry Andric#include <__type_traits/decay.h>
9506c3fb27SDimitry Andric#include <__type_traits/is_constructible.h>
9606c3fb27SDimitry Andric#include <__type_traits/is_copy_constructible.h>
9706c3fb27SDimitry Andric#include <__type_traits/is_function.h>
9806c3fb27SDimitry Andric#include <__type_traits/is_nothrow_move_constructible.h>
9906c3fb27SDimitry Andric#include <__type_traits/is_reference.h>
10006c3fb27SDimitry Andric#include <__type_traits/is_same.h>
10106c3fb27SDimitry Andric#include <__type_traits/remove_cv.h>
10206c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h>
10306c3fb27SDimitry Andric#include <__type_traits/remove_reference.h>
104fe6060f1SDimitry Andric#include <__utility/forward.h>
10581ad6265SDimitry Andric#include <__utility/in_place.h>
10681ad6265SDimitry Andric#include <__utility/move.h>
10781ad6265SDimitry Andric#include <__utility/unreachable.h>
10806c3fb27SDimitry Andric#include <__verbose_abort>
10981ad6265SDimitry Andric#include <initializer_list>
110fe6060f1SDimitry Andric#include <typeinfo>
1110b57cec5SDimitry Andric#include <version>
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1140b57cec5SDimitry Andric#  pragma GCC system_header
1150b57cec5SDimitry Andric#endif
1160b57cec5SDimitry Andric
11706c3fb27SDimitry Andric_LIBCPP_PUSH_MACROS
11806c3fb27SDimitry Andric#include <__undef_macros>
11906c3fb27SDimitry Andric
1200b57cec5SDimitry Andricnamespace std {
121*cb14a3feSDimitry Andricclass _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast {
1220b57cec5SDimitry Andricpublic:
123bdd1243dSDimitry Andric  const char* what() const _NOEXCEPT override;
1240b57cec5SDimitry Andric};
1250b57cec5SDimitry Andric} // namespace std
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
1280b57cec5SDimitry Andric
12906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 17
1300b57cec5SDimitry Andric
131*cb14a3feSDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST void __throw_bad_any_cast() {
13206c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1330b57cec5SDimitry Andric  throw bad_any_cast();
1340b57cec5SDimitry Andric#  else
13506c3fb27SDimitry Andric  _LIBCPP_VERBOSE_ABORT("bad_any_cast was thrown in -fno-exceptions mode");
1360b57cec5SDimitry Andric#  endif
1370b57cec5SDimitry Andric}
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric// Forward declarations
1400b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS any;
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andrictemplate <class _ValueType>
143*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT;
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andrictemplate <class _ValueType>
146*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;
1470b57cec5SDimitry Andric
148*cb14a3feSDimitry Andricnamespace __any_imp {
149bdd1243dSDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1505f757f3fSDimitry Andricusing _Buffer = aligned_storage_t<3 * sizeof(void*), alignof(void*)>;
151bdd1243dSDimitry Andric_LIBCPP_SUPPRESS_DEPRECATED_POP
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andrictemplate <class _Tp>
154*cb14a3feSDimitry Andricusing _IsSmallObject =
155*cb14a3feSDimitry Andric    integral_constant<bool,
156*cb14a3feSDimitry Andric                      sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 &&
157*cb14a3feSDimitry Andric                          is_nothrow_move_constructible<_Tp>::value >;
1580b57cec5SDimitry Andric
159*cb14a3feSDimitry Andricenum class _Action { _Destroy, _Copy, _Move, _Get, _TypeInfo };
160*cb14a3feSDimitry Andric
161*cb14a3feSDimitry Andrictemplate <class _Tp>
162*cb14a3feSDimitry Andricstruct _SmallHandler;
163*cb14a3feSDimitry Andrictemplate <class _Tp>
164*cb14a3feSDimitry Andricstruct _LargeHandler;
165*cb14a3feSDimitry Andric
166*cb14a3feSDimitry Andrictemplate <class _Tp>
167*cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __unique_typeinfo {
168*cb14a3feSDimitry Andric  static constexpr int __id = 0;
1690b57cec5SDimitry Andric};
170*cb14a3feSDimitry Andrictemplate <class _Tp>
171*cb14a3feSDimitry Andricconstexpr int __unique_typeinfo<_Tp>::__id;
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andrictemplate <class _Tp>
174*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr const void* __get_fallback_typeid() {
175e8d8bef9SDimitry Andric  return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id;
1760b57cec5SDimitry Andric}
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andrictemplate <class _Tp>
179*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool __compare_typeid(type_info const* __id, const void* __fallback_id) {
1801ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
1810b57cec5SDimitry Andric  if (__id && *__id == typeid(_Tp))
1820b57cec5SDimitry Andric    return true;
1830b57cec5SDimitry Andric#  endif
1845f757f3fSDimitry Andric  return !__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>();
1850b57cec5SDimitry Andric}
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andrictemplate <class _Tp>
188*cb14a3feSDimitry Andricusing _Handler = conditional_t< _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andric} // namespace __any_imp
1910b57cec5SDimitry Andric
192*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS any {
1930b57cec5SDimitry Andricpublic:
1940b57cec5SDimitry Andric  // construct/destruct
195*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI constexpr any() _NOEXCEPT : __h_(nullptr) {}
1960b57cec5SDimitry Andric
197*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any(any const& __other) : __h_(nullptr) {
198*cb14a3feSDimitry Andric    if (__other.__h_)
199*cb14a3feSDimitry Andric      __other.__call(_Action::_Copy, this);
2000b57cec5SDimitry Andric  }
2010b57cec5SDimitry Andric
202*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any(any&& __other) _NOEXCEPT : __h_(nullptr) {
203*cb14a3feSDimitry Andric    if (__other.__h_)
204*cb14a3feSDimitry Andric      __other.__call(_Action::_Move, this);
2050b57cec5SDimitry Andric  }
2060b57cec5SDimitry Andric
207*cb14a3feSDimitry Andric  template < class _ValueType,
2080b57cec5SDimitry Andric             class _Tp = decay_t<_ValueType>,
209*cb14a3feSDimitry Andric             class     = enable_if_t< !is_same<_Tp, any>::value && !__is_inplace_type<_ValueType>::value &&
210*cb14a3feSDimitry Andric                                  is_copy_constructible<_Tp>::value> >
211*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any(_ValueType&& __value);
2120b57cec5SDimitry Andric
213*cb14a3feSDimitry Andric  template <class _ValueType,
214*cb14a3feSDimitry Andric            class... _Args,
2150b57cec5SDimitry Andric            class _Tp = decay_t<_ValueType>,
216*cb14a3feSDimitry Andric            class     = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value > >
217*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
2180b57cec5SDimitry Andric
219*cb14a3feSDimitry Andric  template <class _ValueType,
220*cb14a3feSDimitry Andric            class _Up,
221*cb14a3feSDimitry Andric            class... _Args,
222*cb14a3feSDimitry Andric            class _Tp = decay_t<_ValueType>,
223*cb14a3feSDimitry Andric            class     = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
224*cb14a3feSDimitry Andric                                 is_copy_constructible<_Tp>::value> >
225*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
226*cb14a3feSDimitry Andric
227*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI ~any() { this->reset(); }
2280b57cec5SDimitry Andric
2290b57cec5SDimitry Andric  // assignments
230*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any& operator=(any const& __rhs) {
2310b57cec5SDimitry Andric    any(__rhs).swap(*this);
2320b57cec5SDimitry Andric    return *this;
2330b57cec5SDimitry Andric  }
2340b57cec5SDimitry Andric
235*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any& operator=(any&& __rhs) _NOEXCEPT {
2365f757f3fSDimitry Andric    any(std::move(__rhs)).swap(*this);
2370b57cec5SDimitry Andric    return *this;
2380b57cec5SDimitry Andric  }
2390b57cec5SDimitry Andric
240*cb14a3feSDimitry Andric  template < class _ValueType,
2410b57cec5SDimitry Andric             class _Tp = decay_t<_ValueType>,
242*cb14a3feSDimitry Andric             class     = enable_if_t< !is_same<_Tp, any>::value && is_copy_constructible<_Tp>::value> >
243*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI any& operator=(_ValueType&& __rhs);
2440b57cec5SDimitry Andric
245*cb14a3feSDimitry Andric  template <class _ValueType,
246*cb14a3feSDimitry Andric            class... _Args,
2470b57cec5SDimitry Andric            class _Tp = decay_t<_ValueType>,
248*cb14a3feSDimitry Andric            class     = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value> >
249*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Tp& emplace(_Args&&...);
250*cb14a3feSDimitry Andric
251*cb14a3feSDimitry Andric  template <class _ValueType,
252*cb14a3feSDimitry Andric            class _Up,
253*cb14a3feSDimitry Andric            class... _Args,
254*cb14a3feSDimitry Andric            class _Tp = decay_t<_ValueType>,
255*cb14a3feSDimitry Andric            class     = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
256*cb14a3feSDimitry Andric                                 is_copy_constructible<_Tp>::value> >
257*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI _Tp& emplace(initializer_list<_Up>, _Args&&...);
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric  // 6.3.3 any modifiers
260*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT {
261*cb14a3feSDimitry Andric    if (__h_)
262*cb14a3feSDimitry Andric      this->__call(_Action::_Destroy);
263*cb14a3feSDimitry Andric  }
2640b57cec5SDimitry Andric
265*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) _NOEXCEPT;
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric  // 6.3.4 any observers
268*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; }
2690b57cec5SDimitry Andric
2701ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
271*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT {
272bdd1243dSDimitry Andric    if (__h_) {
2730b57cec5SDimitry Andric      return *static_cast<type_info const*>(this->__call(_Action::_TypeInfo));
2740b57cec5SDimitry Andric    } else {
2750b57cec5SDimitry Andric      return typeid(void);
2760b57cec5SDimitry Andric    }
2770b57cec5SDimitry Andric  }
2780b57cec5SDimitry Andric#  endif
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andricprivate:
2810b57cec5SDimitry Andric  typedef __any_imp::_Action _Action;
282*cb14a3feSDimitry Andric  using _HandleFuncPtr = void* (*)(_Action, any const*, any*, const type_info*, const void* __fallback_info);
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andric  union _Storage {
28506c3fb27SDimitry Andric    _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}
2860b57cec5SDimitry Andric    void* __ptr;
2870b57cec5SDimitry Andric    __any_imp::_Buffer __buf;
2880b57cec5SDimitry Andric  };
2890b57cec5SDimitry Andric
290*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void*
291*cb14a3feSDimitry Andric  __call(_Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr)
292*cb14a3feSDimitry Andric      const {
293bdd1243dSDimitry Andric    return __h_(__a, this, __other, __info, __fallback_info);
2940b57cec5SDimitry Andric  }
2950b57cec5SDimitry Andric
296*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void* __call(
297*cb14a3feSDimitry Andric      _Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr) {
298bdd1243dSDimitry Andric    return __h_(__a, this, __other, __info, __fallback_info);
2990b57cec5SDimitry Andric  }
3000b57cec5SDimitry Andric
3010b57cec5SDimitry Andric  template <class>
3020b57cec5SDimitry Andric  friend struct __any_imp::_SmallHandler;
3030b57cec5SDimitry Andric  template <class>
3040b57cec5SDimitry Andric  friend struct __any_imp::_LargeHandler;
3050b57cec5SDimitry Andric
3060b57cec5SDimitry Andric  template <class _ValueType>
307*cb14a3feSDimitry Andric  friend add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT;
3080b57cec5SDimitry Andric
3090b57cec5SDimitry Andric  template <class _ValueType>
310*cb14a3feSDimitry Andric  friend add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;
3110b57cec5SDimitry Andric
312bdd1243dSDimitry Andric  _HandleFuncPtr __h_ = nullptr;
313bdd1243dSDimitry Andric  _Storage __s_;
3140b57cec5SDimitry Andric};
3150b57cec5SDimitry Andric
316*cb14a3feSDimitry Andricnamespace __any_imp {
3170b57cec5SDimitry Andrictemplate <class _Tp>
318*cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS _SmallHandler {
319*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void*
320*cb14a3feSDimitry Andric  __handle(_Action __act, any const* __this, any* __other, type_info const* __info, const void* __fallback_info) {
321*cb14a3feSDimitry Andric    switch (__act) {
3220b57cec5SDimitry Andric    case _Action::_Destroy:
3230b57cec5SDimitry Andric      __destroy(const_cast<any&>(*__this));
3240b57cec5SDimitry Andric      return nullptr;
3250b57cec5SDimitry Andric    case _Action::_Copy:
3260b57cec5SDimitry Andric      __copy(*__this, *__other);
3270b57cec5SDimitry Andric      return nullptr;
3280b57cec5SDimitry Andric    case _Action::_Move:
3290b57cec5SDimitry Andric      __move(const_cast<any&>(*__this), *__other);
3300b57cec5SDimitry Andric      return nullptr;
3310b57cec5SDimitry Andric    case _Action::_Get:
3320b57cec5SDimitry Andric      return __get(const_cast<any&>(*__this), __info, __fallback_info);
3330b57cec5SDimitry Andric    case _Action::_TypeInfo:
3340b57cec5SDimitry Andric      return __type_info();
3350b57cec5SDimitry Andric    }
33681ad6265SDimitry Andric    __libcpp_unreachable();
3370b57cec5SDimitry Andric  }
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric  template <class... _Args>
340*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
341e8d8bef9SDimitry Andric    typedef allocator<_Tp> _Alloc;
342e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _ATraits;
343e8d8bef9SDimitry Andric    _Alloc __a;
344bdd1243dSDimitry Andric    _Tp* __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s_.__buf));
3455f757f3fSDimitry Andric    _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...);
346bdd1243dSDimitry Andric    __dest.__h_ = &_SmallHandler::__handle;
3470b57cec5SDimitry Andric    return *__ret;
3480b57cec5SDimitry Andric  }
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andricprivate:
351*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
352e8d8bef9SDimitry Andric    typedef allocator<_Tp> _Alloc;
353e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _ATraits;
354e8d8bef9SDimitry Andric    _Alloc __a;
355bdd1243dSDimitry Andric    _Tp* __p = static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf));
356e8d8bef9SDimitry Andric    _ATraits::destroy(__a, __p);
357bdd1243dSDimitry Andric    __this.__h_ = nullptr;
3580b57cec5SDimitry Andric  }
3590b57cec5SDimitry Andric
360*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) {
361*cb14a3feSDimitry Andric    _SmallHandler::__create(__dest, *static_cast<_Tp const*>(static_cast<void const*>(&__this.__s_.__buf)));
3620b57cec5SDimitry Andric  }
3630b57cec5SDimitry Andric
364*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) {
365*cb14a3feSDimitry Andric    _SmallHandler::__create(__dest, std::move(*static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf))));
3660b57cec5SDimitry Andric    __destroy(__this);
3670b57cec5SDimitry Andric  }
3680b57cec5SDimitry Andric
369*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, const void* __fallback_id) {
3700b57cec5SDimitry Andric    if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
371bdd1243dSDimitry Andric      return static_cast<void*>(&__this.__s_.__buf);
3720b57cec5SDimitry Andric    return nullptr;
3730b57cec5SDimitry Andric  }
3740b57cec5SDimitry Andric
375*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
3761ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
3770b57cec5SDimitry Andric    return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
3780b57cec5SDimitry Andric#  else
3790b57cec5SDimitry Andric    return nullptr;
3800b57cec5SDimitry Andric#  endif
3810b57cec5SDimitry Andric  }
3820b57cec5SDimitry Andric};
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andrictemplate <class _Tp>
385*cb14a3feSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS _LargeHandler {
386*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void*
387*cb14a3feSDimitry Andric  __handle(_Action __act, any const* __this, any* __other, type_info const* __info, void const* __fallback_info) {
388*cb14a3feSDimitry Andric    switch (__act) {
3890b57cec5SDimitry Andric    case _Action::_Destroy:
3900b57cec5SDimitry Andric      __destroy(const_cast<any&>(*__this));
3910b57cec5SDimitry Andric      return nullptr;
3920b57cec5SDimitry Andric    case _Action::_Copy:
3930b57cec5SDimitry Andric      __copy(*__this, *__other);
3940b57cec5SDimitry Andric      return nullptr;
3950b57cec5SDimitry Andric    case _Action::_Move:
3960b57cec5SDimitry Andric      __move(const_cast<any&>(*__this), *__other);
3970b57cec5SDimitry Andric      return nullptr;
3980b57cec5SDimitry Andric    case _Action::_Get:
3990b57cec5SDimitry Andric      return __get(const_cast<any&>(*__this), __info, __fallback_info);
4000b57cec5SDimitry Andric    case _Action::_TypeInfo:
4010b57cec5SDimitry Andric      return __type_info();
4020b57cec5SDimitry Andric    }
40381ad6265SDimitry Andric    __libcpp_unreachable();
4040b57cec5SDimitry Andric  }
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andric  template <class... _Args>
407*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
4080b57cec5SDimitry Andric    typedef allocator<_Tp> _Alloc;
409e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _ATraits;
4100b57cec5SDimitry Andric    typedef __allocator_destructor<_Alloc> _Dp;
4110b57cec5SDimitry Andric    _Alloc __a;
412e8d8bef9SDimitry Andric    unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
413e8d8bef9SDimitry Andric    _Tp* __ret = __hold.get();
4145f757f3fSDimitry Andric    _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...);
415bdd1243dSDimitry Andric    __dest.__s_.__ptr = __hold.release();
416bdd1243dSDimitry Andric    __dest.__h_       = &_LargeHandler::__handle;
4170b57cec5SDimitry Andric    return *__ret;
4180b57cec5SDimitry Andric  }
4190b57cec5SDimitry Andric
4200b57cec5SDimitry Andricprivate:
421*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
422e8d8bef9SDimitry Andric    typedef allocator<_Tp> _Alloc;
423e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _ATraits;
424e8d8bef9SDimitry Andric    _Alloc __a;
425bdd1243dSDimitry Andric    _Tp* __p = static_cast<_Tp*>(__this.__s_.__ptr);
426e8d8bef9SDimitry Andric    _ATraits::destroy(__a, __p);
427e8d8bef9SDimitry Andric    _ATraits::deallocate(__a, __p, 1);
428bdd1243dSDimitry Andric    __this.__h_ = nullptr;
4290b57cec5SDimitry Andric  }
4300b57cec5SDimitry Andric
431*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) {
432bdd1243dSDimitry Andric    _LargeHandler::__create(__dest, *static_cast<_Tp const*>(__this.__s_.__ptr));
4330b57cec5SDimitry Andric  }
4340b57cec5SDimitry Andric
435*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) {
436bdd1243dSDimitry Andric    __dest.__s_.__ptr = __this.__s_.__ptr;
437bdd1243dSDimitry Andric    __dest.__h_       = &_LargeHandler::__handle;
438bdd1243dSDimitry Andric    __this.__h_       = nullptr;
4390b57cec5SDimitry Andric  }
4400b57cec5SDimitry Andric
441*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, void const* __fallback_info) {
4420b57cec5SDimitry Andric    if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
443bdd1243dSDimitry Andric      return static_cast<void*>(__this.__s_.__ptr);
4440b57cec5SDimitry Andric    return nullptr;
4450b57cec5SDimitry Andric  }
4460b57cec5SDimitry Andric
447*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
4481ac55f4cSDimitry Andric#  if !defined(_LIBCPP_HAS_NO_RTTI)
4490b57cec5SDimitry Andric    return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
4500b57cec5SDimitry Andric#  else
4510b57cec5SDimitry Andric    return nullptr;
4520b57cec5SDimitry Andric#  endif
4530b57cec5SDimitry Andric  }
4540b57cec5SDimitry Andric};
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andric} // namespace __any_imp
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andrictemplate <class _ValueType, class _Tp, class>
459*cb14a3feSDimitry Andricany::any(_ValueType&& __v) : __h_(nullptr) {
4605f757f3fSDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__v));
4610b57cec5SDimitry Andric}
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andrictemplate <class _ValueType, class... _Args, class _Tp, class>
4640b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, _Args&&... __args) {
4655f757f3fSDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
4660b57cec5SDimitry Andric}
4670b57cec5SDimitry Andric
4680b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class... _Args, class _Tp, class>
4690b57cec5SDimitry Andricany::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
4705f757f3fSDimitry Andric  __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
4710b57cec5SDimitry Andric}
4720b57cec5SDimitry Andric
4730b57cec5SDimitry Andrictemplate <class _ValueType, class, class>
474*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any& any::operator=(_ValueType&& __v) {
4755f757f3fSDimitry Andric  any(std::forward<_ValueType>(__v)).swap(*this);
4760b57cec5SDimitry Andric  return *this;
4770b57cec5SDimitry Andric}
4780b57cec5SDimitry Andric
4790b57cec5SDimitry Andrictemplate <class _ValueType, class... _Args, class _Tp, class>
480*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(_Args&&... __args) {
4810b57cec5SDimitry Andric  reset();
4825f757f3fSDimitry Andric  return __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
4830b57cec5SDimitry Andric}
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andrictemplate <class _ValueType, class _Up, class... _Args, class _Tp, class>
486*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
4870b57cec5SDimitry Andric  reset();
4885f757f3fSDimitry Andric  return __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
4890b57cec5SDimitry Andric}
4900b57cec5SDimitry Andric
491*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void any::swap(any& __rhs) _NOEXCEPT {
4920b57cec5SDimitry Andric  if (this == &__rhs)
4930b57cec5SDimitry Andric    return;
494bdd1243dSDimitry Andric  if (__h_ && __rhs.__h_) {
4950b57cec5SDimitry Andric    any __tmp;
4960b57cec5SDimitry Andric    __rhs.__call(_Action::_Move, &__tmp);
4970b57cec5SDimitry Andric    this->__call(_Action::_Move, &__rhs);
4980b57cec5SDimitry Andric    __tmp.__call(_Action::_Move, this);
499*cb14a3feSDimitry Andric  } else if (__h_) {
5000b57cec5SDimitry Andric    this->__call(_Action::_Move, &__rhs);
501*cb14a3feSDimitry Andric  } else if (__rhs.__h_) {
5020b57cec5SDimitry Andric    __rhs.__call(_Action::_Move, this);
5030b57cec5SDimitry Andric  }
5040b57cec5SDimitry Andric}
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andric// 6.4 Non-member functions
5070b57cec5SDimitry Andric
508*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) _NOEXCEPT { __lhs.swap(__rhs); }
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andrictemplate <class _Tp, class... _Args>
511*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) {
5125f757f3fSDimitry Andric  return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
5130b57cec5SDimitry Andric}
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andrictemplate <class _Tp, class _Up, class... _Args>
516*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) {
5175f757f3fSDimitry Andric  return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
5180b57cec5SDimitry Andric}
5190b57cec5SDimitry Andric
5200b57cec5SDimitry Andrictemplate <class _ValueType>
521*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any const& __v) {
522bdd1243dSDimitry Andric  using _RawValueType = __remove_cvref_t<_ValueType>;
5230b57cec5SDimitry Andric  static_assert(is_constructible<_ValueType, _RawValueType const&>::value,
5240b57cec5SDimitry Andric                "ValueType is required to be a const lvalue reference "
5250b57cec5SDimitry Andric                "or a CopyConstructible type");
5265f757f3fSDimitry Andric  auto __tmp = std::any_cast<add_const_t<_RawValueType>>(&__v);
5270b57cec5SDimitry Andric  if (__tmp == nullptr)
5280b57cec5SDimitry Andric    __throw_bad_any_cast();
5290b57cec5SDimitry Andric  return static_cast<_ValueType>(*__tmp);
5300b57cec5SDimitry Andric}
5310b57cec5SDimitry Andric
5320b57cec5SDimitry Andrictemplate <class _ValueType>
533*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any& __v) {
534bdd1243dSDimitry Andric  using _RawValueType = __remove_cvref_t<_ValueType>;
5350b57cec5SDimitry Andric  static_assert(is_constructible<_ValueType, _RawValueType&>::value,
5360b57cec5SDimitry Andric                "ValueType is required to be an lvalue reference "
5370b57cec5SDimitry Andric                "or a CopyConstructible type");
5385f757f3fSDimitry Andric  auto __tmp = std::any_cast<_RawValueType>(&__v);
5390b57cec5SDimitry Andric  if (__tmp == nullptr)
5400b57cec5SDimitry Andric    __throw_bad_any_cast();
5410b57cec5SDimitry Andric  return static_cast<_ValueType>(*__tmp);
5420b57cec5SDimitry Andric}
5430b57cec5SDimitry Andric
5440b57cec5SDimitry Andrictemplate <class _ValueType>
545*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any&& __v) {
546bdd1243dSDimitry Andric  using _RawValueType = __remove_cvref_t<_ValueType>;
5470b57cec5SDimitry Andric  static_assert(is_constructible<_ValueType, _RawValueType>::value,
5480b57cec5SDimitry Andric                "ValueType is required to be an rvalue reference "
5490b57cec5SDimitry Andric                "or a CopyConstructible type");
5505f757f3fSDimitry Andric  auto __tmp = std::any_cast<_RawValueType>(&__v);
5510b57cec5SDimitry Andric  if (__tmp == nullptr)
5520b57cec5SDimitry Andric    __throw_bad_any_cast();
5535f757f3fSDimitry Andric  return static_cast<_ValueType>(std::move(*__tmp));
5540b57cec5SDimitry Andric}
5550b57cec5SDimitry Andric
5560b57cec5SDimitry Andrictemplate <class _ValueType>
557*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT {
558*cb14a3feSDimitry Andric  static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
5595f757f3fSDimitry Andric  return std::any_cast<_ValueType>(const_cast<any*>(__any));
5600b57cec5SDimitry Andric}
5610b57cec5SDimitry Andric
5620b57cec5SDimitry Andrictemplate <class _RetType>
563*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/ false_type) noexcept {
5640b57cec5SDimitry Andric  return static_cast<_RetType>(__p);
5650b57cec5SDimitry Andric}
5660b57cec5SDimitry Andric
5670b57cec5SDimitry Andrictemplate <class _RetType>
568*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction*/ true_type) noexcept {
5690b57cec5SDimitry Andric  return nullptr;
5700b57cec5SDimitry Andric}
5710b57cec5SDimitry Andric
5720b57cec5SDimitry Andrictemplate <class _ValueType>
573*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT {
5740b57cec5SDimitry Andric  using __any_imp::_Action;
575*cb14a3feSDimitry 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_) {
578*cb14a3feSDimitry Andric    void* __p = __any->__call(
579*cb14a3feSDimitry Andric        _Action::_Get,
580*cb14a3feSDimitry 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>());
587*cb14a3feSDimitry 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