// -*- 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 _LIBCPP_NODEBUG = aligned_storage_t<3 * sizeof(void*), alignof(void*)>;
_LIBCPP_SUPPRESS_DEPRECATED_POP

template <class _Tp>
using _IsSmallObject _LIBCPP_NODEBUG =
    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 _LIBCPP_NODEBUG = 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:
  using _Action _LIBCPP_NODEBUG = __any_imp::_Action;
  using _HandleFuncPtr
      _LIBCPP_NODEBUG = 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
