// -*- C++ -*-
//===------------------------------ any -----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_EXPERIMENTAL_ANY
#define _LIBCPP_EXPERIMENTAL_ANY

/*
   experimental/any synopsis

namespace std {
namespace experimental {
inline namespace fundamentals_v1 {

  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
    void clear() noexcept;
    void swap(any& rhs) noexcept;

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

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

  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 fundamentals_v1
} // namespace experimental
} // namespace std

*/

#include <experimental/__config>
#include <memory>
#include <new>
#include <typeinfo>
#include <type_traits>
#include <cstdlib>
#include <cassert>

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

_LIBCPP_BEGIN_NAMESPACE_LFTS

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

#if _LIBCPP_STD_VER > 11                                            // C++ > 11

_LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY
inline void __throw_bad_any_cast()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    throw bad_any_cast();
#else
    assert(!"bad_any_cast");
#endif
}

// Forward declarations
class any;

template <class _ValueType>
typename add_pointer<typename add_const<_ValueType>::type>::type
any_cast(any const *) _NOEXCEPT;

template <class _ValueType>
typename add_pointer<_ValueType>::type
any_cast(any *) _NOEXCEPT;

namespace __any_imp
{
  typedef typename aligned_storage<3*sizeof(void*), alignment_of<void*>::value>::type
    _Buffer;

  template <class _Tp>
  struct _IsSmallObject
    : public integral_constant<bool
        , sizeof(_Tp) <= sizeof(_Buffer)
          && alignment_of<_Buffer>::value
             % alignment_of<_Tp>::value == 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>
  using _Handler = typename conditional<_IsSmallObject<_Tp>::value
                                      , _SmallHandler<_Tp>
                                      , _LargeHandler<_Tp>
                                    >::type;
  template <class _ValueType>
  using _EnableIfNotAny = typename
    enable_if<
      !is_same<typename decay<_ValueType>::type, any>::value
    >::type;

} // namespace __any_imp

class any
{
public:
  // 6.3.1 any construct/destruct
  _LIBCPP_INLINE_VISIBILITY
  any() _NOEXCEPT : __h(nullptr) {}

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

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

  template <
      class _ValueType
    , class = __any_imp::_EnableIfNotAny<_ValueType>
    >
  any(_ValueType && __value);

  _LIBCPP_INLINE_VISIBILITY
  ~any()
  {
    this->clear();
  }

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

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

  template <
      class _ValueType
    , class = __any_imp::_EnableIfNotAny<_ValueType>
    >
  any & operator=(_ValueType && __rhs);

  // 6.3.3 any modifiers
  _LIBCPP_INLINE_VISIBILITY
  void clear() _NOEXCEPT
  {
    if (__h) this->__call(_Action::_Destroy);
  }

  void swap(any & __rhs) _NOEXCEPT;

  // 6.3.4 any observers
  _LIBCPP_INLINE_VISIBILITY
  bool empty() const _NOEXCEPT
  {
    return __h == nullptr;
  }

#if !defined(_LIBCPP_NO_RTTI)
  _LIBCPP_INLINE_VISIBILITY
  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;

    typedef void* (*_HandleFuncPtr)(_Action, any const *, any *, const type_info *);

    union _Storage
    {
        void *  __ptr;
        __any_imp::_Buffer __buf;
    };

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

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

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

    template <class _ValueType>
    friend typename add_pointer<typename add_const<_ValueType>::type>::type
    any_cast(any const *) _NOEXCEPT;

    template <class _ValueType>
    friend typename add_pointer<_ValueType>::type
    any_cast(any *) _NOEXCEPT;

    _HandleFuncPtr __h;
    _Storage __s;
};

namespace __any_imp
{

  template <class _Tp>
  struct _LIBCPP_TYPE_VIS_ONLY _SmallHandler
  {
     _LIBCPP_INLINE_VISIBILITY
     static void* __handle(_Action __act, any const * __this, any * __other,
                           type_info const * __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);
        case _Action::_TypeInfo:
          return __type_info();
        }
    }

    template <class _Up>
    _LIBCPP_INLINE_VISIBILITY
    static void __create(any & __dest, _Up && __v)
    {
        ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Up>(__v));
        __dest.__h = &_SmallHandler::__handle;
    }

  private:
    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
    static void __destroy(any & __this)
    {
        _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
        __value.~_Tp();
        __this.__h = nullptr;
    }

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

    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
    static void __move(any & __this, any & __dest)
    {
        _SmallHandler::__create(__dest, _VSTD::move(
            *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
        __destroy(__this);
    }

    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
    static void* __get(any & __this, type_info const * __info)
    {
#if !defined(_LIBCPP_NO_RTTI)
        if (typeid(_Tp) == *__info) {
            return static_cast<void*>(&__this.__s.__buf);
        }
        return nullptr;
#else
        return static_cast<void*>(&__this.__s.__buf);
#endif
    }

    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
    static void* __type_info()
    {
#if !defined(_LIBCPP_NO_RTTI)
        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
#else
        return nullptr;
#endif
    }
  };

  template <class _Tp>
  struct _LIBCPP_TYPE_VIS_ONLY _LargeHandler
  {
    _LIBCPP_INLINE_VISIBILITY
    static void* __handle(_Action __act, any const * __this, any * __other,
                          type_info const * __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);
        case _Action::_TypeInfo:
          return __type_info();
        }
    }

    template <class _Up>
    _LIBCPP_INLINE_VISIBILITY
    static void __create(any & __dest, _Up && __v)
    {
        typedef allocator<_Tp> _Alloc;
        typedef __allocator_destructor<_Alloc> _Dp;
        _Alloc __a;
        unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
        ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Up>(__v));
        __dest.__s.__ptr = __hold.release();
        __dest.__h = &_LargeHandler::__handle;
    }

  private:

    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
    static void __destroy(any & __this)
    {
        delete static_cast<_Tp*>(__this.__s.__ptr);
        __this.__h = nullptr;
    }

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

    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
    static void __move(any & __this, any & __dest)
    {
      __dest.__s.__ptr = __this.__s.__ptr;
      __dest.__h = &_LargeHandler::__handle;
      __this.__h = nullptr;
    }

    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
    static void* __get(any & __this, type_info const * __info)
    {
#if !defined(_LIBCPP_NO_RTTI)
        if (typeid(_Tp) == *__info) {
            return static_cast<void*>(__this.__s.__ptr);
        }
        return nullptr;
#else
        return static_cast<void*>(__this.__s.__ptr);
#endif
    }

    _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
    static void* __type_info()
    {
#if !defined(_LIBCPP_NO_RTTI)
        return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
#else
        return nullptr;
#endif
    }
  };

} // namespace __any_imp


template <class _ValueType, class>
_LIBCPP_INLINE_VISIBILITY
any::any(_ValueType && __v) : __h(nullptr)
{
  typedef typename decay<_ValueType>::type _Tp;
  static_assert(is_copy_constructible<_Tp>::value,
                "_ValueType must be CopyConstructible.");
  typedef __any_imp::_Handler<_Tp> _HandlerType;
  _HandlerType::__create(*this, _VSTD::forward<_ValueType>(__v));
}

template <class _ValueType, class>
_LIBCPP_INLINE_VISIBILITY
any & any::operator=(_ValueType && __v)
{
  typedef typename decay<_ValueType>::type _Tp;
  static_assert(is_copy_constructible<_Tp>::value,
                "_ValueType must be CopyConstructible.");
  any(_VSTD::forward<_ValueType>(__v)).swap(*this);
  return *this;
}

inline _LIBCPP_INLINE_VISIBILITY
void any::swap(any & __rhs) _NOEXCEPT
{
    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_INLINE_VISIBILITY
void swap(any & __lhs, any & __rhs) _NOEXCEPT
{
    __lhs.swap(__rhs);
}

template <class _ValueType>
_LIBCPP_INLINE_VISIBILITY
_ValueType any_cast(any const & __v)
{
    static_assert(
        is_reference<_ValueType>::value
        || is_copy_constructible<_ValueType>::value,
        "_ValueType is required to be a reference or a CopyConstructible type.");
    typedef typename add_const<typename remove_reference<_ValueType>::type>::type
            _Tp;
    _Tp * __tmp = any_cast<_Tp>(&__v);
    if (__tmp == nullptr)
        __throw_bad_any_cast();
    return *__tmp;
}

template <class _ValueType>
_LIBCPP_INLINE_VISIBILITY
_ValueType any_cast(any & __v)
{
    static_assert(
        is_reference<_ValueType>::value
        || is_copy_constructible<_ValueType>::value,
        "_ValueType is required to be a reference or a CopyConstructible type.");
    typedef typename remove_reference<_ValueType>::type _Tp;
    _Tp * __tmp = any_cast<_Tp>(&__v);
    if (__tmp == nullptr)
        __throw_bad_any_cast();
    return *__tmp;
}

template <class _ValueType>
_LIBCPP_INLINE_VISIBILITY
_ValueType any_cast(any && __v)
{
    static_assert(
        is_reference<_ValueType>::value
        || is_copy_constructible<_ValueType>::value,
        "_ValueType is required to be a reference or a CopyConstructible type.");
    typedef typename remove_reference<_ValueType>::type _Tp;
    _Tp * __tmp = any_cast<_Tp>(&__v);
    if (__tmp == nullptr)
        __throw_bad_any_cast();
    return *__tmp;
}

template <class _ValueType>
inline _LIBCPP_INLINE_VISIBILITY
typename add_pointer<typename add_const<_ValueType>::type>::type
any_cast(any const * __any) _NOEXCEPT
{
    static_assert(!is_reference<_ValueType>::value,
                  "_ValueType may not be a reference.");
    return any_cast<_ValueType>(const_cast<any *>(__any));
}

template <class _ValueType>
_LIBCPP_INLINE_VISIBILITY
typename add_pointer<_ValueType>::type
any_cast(any * __any) _NOEXCEPT
{
    using __any_imp::_Action;
    static_assert(!is_reference<_ValueType>::value,
                  "_ValueType may not be a reference.");
    typedef typename add_pointer<_ValueType>::type _ReturnType;
    if (__any && __any->__h) {

        return static_cast<_ReturnType>(
            __any->__call(_Action::_Get, nullptr,
#if !defined(_LIBCPP_NO_RTTI)
                &typeid(_ValueType)
#else
                nullptr
#endif
        ));

    }
    return nullptr;
}

#endif // _LIBCPP_STD_VER > 11

_LIBCPP_END_NAMESPACE_LFTS

#endif // _LIBCPP_EXPERIMENTAL_ANY
