// -*- 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>

#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 inline _LIBCPP_ALWAYS_INLINE
void __throw_bad_any_cast()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    throw bad_any_cast();
#else
    _VSTD::abort();
#endif
}

// Forward declarations
class any;

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

template <class _ValueType>
typename add_pointer<_ValueType>::type
_LIBCPP_INLINE_VISIBILITY
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>
    >
  _LIBCPP_INLINE_VISIBILITY
  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>
    >
  _LIBCPP_INLINE_VISIBILITY
  any & operator=(_ValueType && __rhs);

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

  _LIBCPP_INLINE_VISIBILITY
  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_TEMPLATE_VIS _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_TEMPLATE_VIS _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>
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>
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
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
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>
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
