// -*- 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:
     //TODO(EricWF) Enable or delete these.
    //bad_any_cast() _NOEXCEPT;
    //virtual ~bad_any_cast() _NOEXCEPT;
    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
    _VSTD::abort();
#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
