// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_ANY
#define _LIBCPP_ANY

/*
   any synopsis

namespace std {

  class bad_any_cast : public bad_cast
  {
  public:
    virtual const char* what() const noexcept;
  };

  class any
  {
  public:

    // 6.3.1 any construct/destruct
    any() noexcept;

    any(const any& other);
    any(any&& other) noexcept;

    template <class ValueType>
      any(ValueType&& value);

    ~any();

    // 6.3.2 any assignments
    any& operator=(const any& rhs);
    any& operator=(any&& rhs) noexcept;

    template <class ValueType>
      any& operator=(ValueType&& rhs);

    // 6.3.3 any modifiers
    template <class ValueType, class... Args>
      decay_t<ValueType>& emplace(Args&&... args);
    template <class ValueType, class U, class... Args>
      decay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
    void reset() noexcept;
    void swap(any& rhs) noexcept;

    // 6.3.4 any observers
    bool has_value() const noexcept;
    const type_info& type() const noexcept;
  };

   // 6.4 Non-member functions
  void swap(any& x, any& y) noexcept;

  template <class T, class ...Args>
    any make_any(Args&& ...args);
  template <class T, class U, class ...Args>
    any make_any(initializer_list<U>, Args&& ...args);

  template<class ValueType>
    ValueType any_cast(const any& operand);
  template<class ValueType>
    ValueType any_cast(any& operand);
  template<class ValueType>
    ValueType any_cast(any&& operand);

  template<class ValueType>
    const ValueType* any_cast(const any* operand) noexcept;
  template<class ValueType>
    ValueType* any_cast(any* operand) noexcept;

} // namespace std

*/

#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#  include <__cxx03/any>
#else
#  include <__config>
#  include <__memory/allocator.h>
#  include <__memory/allocator_destructor.h>
#  include <__memory/allocator_traits.h>
#  include <__memory/unique_ptr.h>
#  include <__type_traits/add_cv_quals.h>
#  include <__type_traits/add_pointer.h>
#  include <__type_traits/aligned_storage.h>
#  include <__type_traits/conditional.h>
#  include <__type_traits/decay.h>
#  include <__type_traits/enable_if.h>
#  include <__type_traits/is_constructible.h>
#  include <__type_traits/is_function.h>
#  include <__type_traits/is_nothrow_constructible.h>
#  include <__type_traits/is_reference.h>
#  include <__type_traits/is_same.h>
#  include <__type_traits/is_void.h>
#  include <__type_traits/remove_cv.h>
#  include <__type_traits/remove_cvref.h>
#  include <__type_traits/remove_reference.h>
#  include <__utility/forward.h>
#  include <__utility/in_place.h>
#  include <__utility/move.h>
#  include <__utility/unreachable.h>
#  include <__verbose_abort>
#  include <initializer_list>
#  include <typeinfo>
#  include <version>

#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#    pragma GCC system_header
#  endif

_LIBCPP_PUSH_MACROS
#  include <__undef_macros>

namespace std {
class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast {
public:
  const char* what() const _NOEXCEPT override;
};
} // namespace std

_LIBCPP_BEGIN_NAMESPACE_STD

#  if _LIBCPP_STD_VER >= 17

[[noreturn]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST void __throw_bad_any_cast() {
#    if _LIBCPP_HAS_EXCEPTIONS
  throw bad_any_cast();
#    else
  _LIBCPP_VERBOSE_ABORT("bad_any_cast was thrown in -fno-exceptions mode");
#    endif
}

// Forward declarations
class _LIBCPP_TEMPLATE_VIS any;

template <class _ValueType>
_LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT;

template <class _ValueType>
_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;

namespace __any_imp {
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
using _Buffer = aligned_storage_t<3 * sizeof(void*), alignof(void*)>;
_LIBCPP_SUPPRESS_DEPRECATED_POP

template <class _Tp>
using _IsSmallObject =
    integral_constant<bool,
                      sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 &&
                          is_nothrow_move_constructible<_Tp>::value >;

enum class _Action { _Destroy, _Copy, _Move, _Get, _TypeInfo };

template <class _Tp>
struct _SmallHandler;
template <class _Tp>
struct _LargeHandler;

template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS __unique_typeinfo {
  static constexpr int __id = 0;
};

template <class _Tp>
inline _LIBCPP_HIDE_FROM_ABI constexpr const void* __get_fallback_typeid() {
  return &__unique_typeinfo<remove_cv_t<remove_reference_t<_Tp>>>::__id;
}

template <class _Tp>
inline _LIBCPP_HIDE_FROM_ABI bool __compare_typeid(type_info const* __id, const void* __fallback_id) {
#    if _LIBCPP_HAS_RTTI
  if (__id && *__id == typeid(_Tp))
    return true;
#    endif
  return !__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>();
}

template <class _Tp>
using _Handler = conditional_t< _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;

} // namespace __any_imp

class _LIBCPP_TEMPLATE_VIS any {
public:
  // construct/destruct
  _LIBCPP_HIDE_FROM_ABI constexpr any() _NOEXCEPT : __h_(nullptr) {}

  _LIBCPP_HIDE_FROM_ABI any(any const& __other) : __h_(nullptr) {
    if (__other.__h_)
      __other.__call(_Action::_Copy, this);
  }

  _LIBCPP_HIDE_FROM_ABI any(any&& __other) _NOEXCEPT : __h_(nullptr) {
    if (__other.__h_)
      __other.__call(_Action::_Move, this);
  }

  template < class _ValueType,
             class _Tp = decay_t<_ValueType>,
             class     = enable_if_t< !is_same<_Tp, any>::value && !__is_inplace_type<_ValueType>::value &&
                                      is_copy_constructible<_Tp>::value> >
  _LIBCPP_HIDE_FROM_ABI any(_ValueType&& __value);

  template <class _ValueType,
            class... _Args,
            class _Tp = decay_t<_ValueType>,
            class     = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value > >
  _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, _Args&&... __args);

  template <class _ValueType,
            class _Up,
            class... _Args,
            class _Tp = decay_t<_ValueType>,
            class     = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
                                     is_copy_constructible<_Tp>::value> >
  _LIBCPP_HIDE_FROM_ABI explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);

  _LIBCPP_HIDE_FROM_ABI ~any() { this->reset(); }

  // assignments
  _LIBCPP_HIDE_FROM_ABI any& operator=(any const& __rhs) {
    any(__rhs).swap(*this);
    return *this;
  }

  _LIBCPP_HIDE_FROM_ABI any& operator=(any&& __rhs) _NOEXCEPT {
    any(std::move(__rhs)).swap(*this);
    return *this;
  }

  template < class _ValueType,
             class _Tp = decay_t<_ValueType>,
             class     = enable_if_t< !is_same<_Tp, any>::value && is_copy_constructible<_Tp>::value> >
  _LIBCPP_HIDE_FROM_ABI any& operator=(_ValueType&& __rhs);

  template <class _ValueType,
            class... _Args,
            class _Tp = decay_t<_ValueType>,
            class     = enable_if_t< is_constructible<_Tp, _Args...>::value && is_copy_constructible<_Tp>::value> >
  _LIBCPP_HIDE_FROM_ABI _Tp& emplace(_Args&&...);

  template <class _ValueType,
            class _Up,
            class... _Args,
            class _Tp = decay_t<_ValueType>,
            class     = enable_if_t< is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
                                     is_copy_constructible<_Tp>::value> >
  _LIBCPP_HIDE_FROM_ABI _Tp& emplace(initializer_list<_Up>, _Args&&...);

  // 6.3.3 any modifiers
  _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT {
    if (__h_)
      this->__call(_Action::_Destroy);
  }

  _LIBCPP_HIDE_FROM_ABI void swap(any& __rhs) _NOEXCEPT;

  // 6.3.4 any observers
  _LIBCPP_HIDE_FROM_ABI bool has_value() const _NOEXCEPT { return __h_ != nullptr; }

#    if _LIBCPP_HAS_RTTI
  _LIBCPP_HIDE_FROM_ABI const type_info& type() const _NOEXCEPT {
    if (__h_) {
      return *static_cast<type_info const*>(this->__call(_Action::_TypeInfo));
    } else {
      return typeid(void);
    }
  }
#    endif

private:
  typedef __any_imp::_Action _Action;
  using _HandleFuncPtr = void* (*)(_Action, any const*, any*, const type_info*, const void* __fallback_info);

  union _Storage {
    _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}
    void* __ptr;
    __any_imp::_Buffer __buf;
  };

  _LIBCPP_HIDE_FROM_ABI void*
  __call(_Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr)
      const {
    return __h_(__a, this, __other, __info, __fallback_info);
  }

  _LIBCPP_HIDE_FROM_ABI void* __call(
      _Action __a, any* __other = nullptr, type_info const* __info = nullptr, const void* __fallback_info = nullptr) {
    return __h_(__a, this, __other, __info, __fallback_info);
  }

  template <class>
  friend struct __any_imp::_SmallHandler;
  template <class>
  friend struct __any_imp::_LargeHandler;

  template <class _ValueType>
  friend add_pointer_t<add_const_t<_ValueType>> any_cast(any const*) _NOEXCEPT;

  template <class _ValueType>
  friend add_pointer_t<_ValueType> any_cast(any*) _NOEXCEPT;

  _HandleFuncPtr __h_ = nullptr;
  _Storage __s_;
};

namespace __any_imp {
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS _SmallHandler {
  _LIBCPP_HIDE_FROM_ABI static void*
  __handle(_Action __act, any const* __this, any* __other, type_info const* __info, const void* __fallback_info) {
    switch (__act) {
    case _Action::_Destroy:
      __destroy(const_cast<any&>(*__this));
      return nullptr;
    case _Action::_Copy:
      __copy(*__this, *__other);
      return nullptr;
    case _Action::_Move:
      __move(const_cast<any&>(*__this), *__other);
      return nullptr;
    case _Action::_Get:
      return __get(const_cast<any&>(*__this), __info, __fallback_info);
    case _Action::_TypeInfo:
      return __type_info();
    }
    __libcpp_unreachable();
  }

  template <class... _Args>
  _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
    typedef allocator<_Tp> _Alloc;
    typedef allocator_traits<_Alloc> _ATraits;
    _Alloc __a;
    _Tp* __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s_.__buf));
    _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...);
    __dest.__h_ = &_SmallHandler::__handle;
    return *__ret;
  }

private:
  _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
    typedef allocator<_Tp> _Alloc;
    typedef allocator_traits<_Alloc> _ATraits;
    _Alloc __a;
    _Tp* __p = static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf));
    _ATraits::destroy(__a, __p);
    __this.__h_ = nullptr;
  }

  _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) {
    _SmallHandler::__create(__dest, *static_cast<_Tp const*>(static_cast<void const*>(&__this.__s_.__buf)));
  }

  _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) {
    _SmallHandler::__create(__dest, std::move(*static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf))));
    __destroy(__this);
  }

  _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, const void* __fallback_id) {
    if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id))
      return static_cast<void*>(&__this.__s_.__buf);
    return nullptr;
  }

  _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
#    if _LIBCPP_HAS_RTTI
    return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
#    else
    return nullptr;
#    endif
  }
};

template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS _LargeHandler {
  _LIBCPP_HIDE_FROM_ABI static void*
  __handle(_Action __act, any const* __this, any* __other, type_info const* __info, void const* __fallback_info) {
    switch (__act) {
    case _Action::_Destroy:
      __destroy(const_cast<any&>(*__this));
      return nullptr;
    case _Action::_Copy:
      __copy(*__this, *__other);
      return nullptr;
    case _Action::_Move:
      __move(const_cast<any&>(*__this), *__other);
      return nullptr;
    case _Action::_Get:
      return __get(const_cast<any&>(*__this), __info, __fallback_info);
    case _Action::_TypeInfo:
      return __type_info();
    }
    __libcpp_unreachable();
  }

  template <class... _Args>
  _LIBCPP_HIDE_FROM_ABI static _Tp& __create(any& __dest, _Args&&... __args) {
    typedef allocator<_Tp> _Alloc;
    typedef allocator_traits<_Alloc> _ATraits;
    typedef __allocator_destructor<_Alloc> _Dp;
    _Alloc __a;
    unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
    _Tp* __ret = __hold.get();
    _ATraits::construct(__a, __ret, std::forward<_Args>(__args)...);
    __dest.__s_.__ptr = __hold.release();
    __dest.__h_       = &_LargeHandler::__handle;
    return *__ret;
  }

private:
  _LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {
    typedef allocator<_Tp> _Alloc;
    typedef allocator_traits<_Alloc> _ATraits;
    _Alloc __a;
    _Tp* __p = static_cast<_Tp*>(__this.__s_.__ptr);
    _ATraits::destroy(__a, __p);
    _ATraits::deallocate(__a, __p, 1);
    __this.__h_ = nullptr;
  }

  _LIBCPP_HIDE_FROM_ABI static void __copy(any const& __this, any& __dest) {
    _LargeHandler::__create(__dest, *static_cast<_Tp const*>(__this.__s_.__ptr));
  }

  _LIBCPP_HIDE_FROM_ABI static void __move(any& __this, any& __dest) {
    __dest.__s_.__ptr = __this.__s_.__ptr;
    __dest.__h_       = &_LargeHandler::__handle;
    __this.__h_       = nullptr;
  }

  _LIBCPP_HIDE_FROM_ABI static void* __get(any& __this, type_info const* __info, void const* __fallback_info) {
    if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info))
      return static_cast<void*>(__this.__s_.__ptr);
    return nullptr;
  }

  _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
#    if _LIBCPP_HAS_RTTI
    return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
#    else
    return nullptr;
#    endif
  }
};

} // namespace __any_imp

template <class _ValueType, class _Tp, class>
any::any(_ValueType&& __v) : __h_(nullptr) {
  __any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__v));
}

template <class _ValueType, class... _Args, class _Tp, class>
any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
  __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
}

template <class _ValueType, class _Up, class... _Args, class _Tp, class>
any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
  __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
}

template <class _ValueType, class, class>
inline _LIBCPP_HIDE_FROM_ABI any& any::operator=(_ValueType&& __v) {
  any(std::forward<_ValueType>(__v)).swap(*this);
  return *this;
}

template <class _ValueType, class... _Args, class _Tp, class>
inline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(_Args&&... __args) {
  reset();
  return __any_imp::_Handler<_Tp>::__create(*this, std::forward<_Args>(__args)...);
}

template <class _ValueType, class _Up, class... _Args, class _Tp, class>
inline _LIBCPP_HIDE_FROM_ABI _Tp& any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
  reset();
  return __any_imp::_Handler<_Tp>::__create(*this, __il, std::forward<_Args>(__args)...);
}

inline _LIBCPP_HIDE_FROM_ABI void any::swap(any& __rhs) _NOEXCEPT {
  if (this == &__rhs)
    return;
  if (__h_ && __rhs.__h_) {
    any __tmp;
    __rhs.__call(_Action::_Move, &__tmp);
    this->__call(_Action::_Move, &__rhs);
    __tmp.__call(_Action::_Move, this);
  } else if (__h_) {
    this->__call(_Action::_Move, &__rhs);
  } else if (__rhs.__h_) {
    __rhs.__call(_Action::_Move, this);
  }
}

// 6.4 Non-member functions

inline _LIBCPP_HIDE_FROM_ABI void swap(any& __lhs, any& __rhs) _NOEXCEPT { __lhs.swap(__rhs); }

template <class _Tp, class... _Args>
inline _LIBCPP_HIDE_FROM_ABI any make_any(_Args&&... __args) {
  return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
}

template <class _Tp, class _Up, class... _Args>
inline _LIBCPP_HIDE_FROM_ABI any make_any(initializer_list<_Up> __il, _Args&&... __args) {
  return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
}

template <class _ValueType>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any const& __v) {
  using _RawValueType = __remove_cvref_t<_ValueType>;
  static_assert(is_constructible<_ValueType, _RawValueType const&>::value,
                "ValueType is required to be a const lvalue reference "
                "or a CopyConstructible type");
  auto __tmp = std::any_cast<add_const_t<_RawValueType>>(&__v);
  if (__tmp == nullptr)
    __throw_bad_any_cast();
  return static_cast<_ValueType>(*__tmp);
}

template <class _ValueType>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any& __v) {
  using _RawValueType = __remove_cvref_t<_ValueType>;
  static_assert(is_constructible<_ValueType, _RawValueType&>::value,
                "ValueType is required to be an lvalue reference "
                "or a CopyConstructible type");
  auto __tmp = std::any_cast<_RawValueType>(&__v);
  if (__tmp == nullptr)
    __throw_bad_any_cast();
  return static_cast<_ValueType>(*__tmp);
}

template <class _ValueType>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any&& __v) {
  using _RawValueType = __remove_cvref_t<_ValueType>;
  static_assert(is_constructible<_ValueType, _RawValueType>::value,
                "ValueType is required to be an rvalue reference "
                "or a CopyConstructible type");
  auto __tmp = std::any_cast<_RawValueType>(&__v);
  if (__tmp == nullptr)
    __throw_bad_any_cast();
  return static_cast<_ValueType>(std::move(*__tmp));
}

template <class _ValueType>
inline _LIBCPP_HIDE_FROM_ABI add_pointer_t<add_const_t<_ValueType>> any_cast(any const* __any) _NOEXCEPT {
  static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
  static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
  return std::any_cast<_ValueType>(const_cast<any*>(__any));
}

template <class _RetType>
inline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void* __p, /*IsFunction*/ false_type) noexcept {
  return static_cast<_RetType>(__p);
}

template <class _RetType>
inline _LIBCPP_HIDE_FROM_ABI _RetType __pointer_or_func_cast(void*, /*IsFunction*/ true_type) noexcept {
  return nullptr;
}

template <class _ValueType>
_LIBCPP_HIDE_FROM_ABI add_pointer_t<_ValueType> any_cast(any* __any) _NOEXCEPT {
  using __any_imp::_Action;
  static_assert(!is_void_v<_ValueType>, "_ValueType may not be void.");
  static_assert(!is_reference<_ValueType>::value, "_ValueType may not be a reference.");
  typedef add_pointer_t<_ValueType> _ReturnType;
  if (__any && __any->__h_) {
    void* __p = __any->__call(
        _Action::_Get,
        nullptr,
#    if _LIBCPP_HAS_RTTI
        &typeid(_ValueType),
#    else
        nullptr,
#    endif
        __any_imp::__get_fallback_typeid<_ValueType>());
    return std::__pointer_or_func_cast<_ReturnType>(__p, is_function<_ValueType>{});
  }
  return nullptr;
}

#  endif // _LIBCPP_STD_VER >= 17

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17
#    include <chrono>
#  endif

#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#    include <atomic>
#    include <concepts>
#    include <cstdlib>
#    include <iosfwd>
#    include <iterator>
#    include <memory>
#    include <stdexcept>
#    include <type_traits>
#    include <variant>
#  endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_ANY
