// <experimental/any> -*- C++ -*-

// Copyright (C) 2014-2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file experimental/any
 *  This is a TS C++ Library header.
 */

#ifndef _GLIBCXX_EXPERIMENTAL_ANY
#define _GLIBCXX_EXPERIMENTAL_ANY 1

#pragma GCC system_header

#if __cplusplus <= 201103L
# include <bits/c++14_warning.h>
#else

#include <typeinfo>
#include <new>
#include <utility>
#include <type_traits>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace experimental
{
inline namespace fundamentals_v1
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @defgroup any Type-safe container of any type
   * @ingroup experimental
   *
   * A type-safe container for single values of value types, as
   * described in n3804 "Any Library Proposal (Revision 3)".
   *
   * @{
   */

#define __cpp_lib_experimental_any 201411

  /**
   *  @brief Exception class thrown by a failed @c any_cast
   *  @ingroup exceptions
   */
  class bad_any_cast : public bad_cast
  {
  public:
    virtual const char* what() const noexcept { return "bad any_cast"; }
  };

  [[gnu::noreturn]] inline void __throw_bad_any_cast()
  {
#if __cpp_exceptions
    throw bad_any_cast{};
#else
    __builtin_abort();
#endif
  }

  /**
   *  @brief A type-safe container of any type.
   * 
   *  An @c any object's state is either empty or it stores a contained object
   *  of CopyConstructible type.
   */
  class any
  {
    // Holds either pointer to a heap object or the contained object itself.
    union _Storage
    {
      // This constructor intentionally doesn't initialize anything.
      _Storage() = default;

      // Prevent trivial copies of this type, buffer might hold a non-POD.
      _Storage(const _Storage&) = delete;
      _Storage& operator=(const _Storage&) = delete;

      void* _M_ptr;
      aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer;
    };

    template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>,
	     bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))
			  && (alignof(_Tp) <= alignof(_Storage))>
      using _Internal = std::integral_constant<bool, _Safe::value && _Fits>;

    template<typename _Tp>
      struct _Manager_internal; // uses small-object optimization

    template<typename _Tp>
      struct _Manager_external; // creates contained object on the heap

    template<typename _Tp>
      using _Manager = conditional_t<_Internal<_Tp>::value,
				     _Manager_internal<_Tp>,
				     _Manager_external<_Tp>>;

    template<typename _Tp, typename _Decayed = decay_t<_Tp>>
      using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>;

  public:
    // construct/destruct

    /// Default constructor, creates an empty object.
    any() noexcept : _M_manager(nullptr) { }

    /// Copy constructor, copies the state of @p __other
    any(const any& __other)
    {
      if (__other.empty())
	_M_manager = nullptr;
      else
	{
	  _Arg __arg;
	  __arg._M_any = this;
	  __other._M_manager(_Op_clone, &__other, &__arg);
	}
    }

    /**
     * @brief Move constructor, transfer the state from @p __other
     *
     * @post @c __other.empty() (this postcondition is a GNU extension)
     */
    any(any&& __other) noexcept
    {
      if (__other.empty())
	_M_manager = nullptr;
      else
	{
	  _Arg __arg;
	  __arg._M_any = this;
	  __other._M_manager(_Op_xfer, &__other, &__arg);
	}
    }

    /// Construct with a copy of @p __value as the contained object.
    template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
	      typename _Mgr = _Manager<_Tp>,
              typename enable_if<is_constructible<_Tp, _ValueType&&>::value,
                                 bool>::type = true>
      any(_ValueType&& __value)
      : _M_manager(&_Mgr::_S_manage)
      {
        _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value));
	static_assert(is_copy_constructible<_Tp>::value,
		      "The contained object must be CopyConstructible");
      }

    /// Construct with a copy of @p __value as the contained object.
    template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
	      typename _Mgr = _Manager<_Tp>,
              typename enable_if<!is_constructible<_Tp, _ValueType&&>::value,
                                 bool>::type = false>
      any(_ValueType&& __value)
      : _M_manager(&_Mgr::_S_manage)
      {
        _Mgr::_S_create(_M_storage, __value);
	static_assert(is_copy_constructible<_Tp>::value,
		      "The contained object must be CopyConstructible");
      }

    /// Destructor, calls @c clear()
    ~any() { clear(); }

    // assignments

    /// Copy the state of another object.
    any& operator=(const any& __rhs)
    {
      if (__rhs.empty())
	clear();
      else if (this != &__rhs)
	{
	  if (!empty())
	    _M_manager(_Op_destroy, this, nullptr);
	  _Arg __arg;
	  __arg._M_any = this;
	  __rhs._M_manager(_Op_clone, &__rhs, &__arg);
	}
      return *this;
    }

    /**
     * @brief Move assignment operator
     *
     * @post @c __rhs.empty() (not guaranteed for other implementations)
     */
    any& operator=(any&& __rhs) noexcept
    {
      if (__rhs.empty())
	clear();
      else if (this != &__rhs)
	{
	  if (!empty())
	    _M_manager(_Op_destroy, this, nullptr);
	  _Arg __arg;
	  __arg._M_any = this;
	  __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
	}
      return *this;
    }

    /// Store a copy of @p __rhs as the contained object.
    template<typename _ValueType>
      enable_if_t<!is_same<any, decay_t<_ValueType>>::value, any&>
      operator=(_ValueType&& __rhs)
      {
	*this = any(std::forward<_ValueType>(__rhs));
	return *this;
      }

    // modifiers

    /// If not empty, destroy the contained object.
    void clear() noexcept
    {
      if (!empty())
      {
	_M_manager(_Op_destroy, this, nullptr);
	_M_manager = nullptr;
      }
    }

    /// Exchange state with another object.
    void swap(any& __rhs) noexcept
    {
      if (empty() && __rhs.empty())
	return;

      if (!empty() && !__rhs.empty())
	{
	  if (this == &__rhs)
	    return;

	  any __tmp;
	  _Arg __arg;
	  __arg._M_any = &__tmp;
	  __rhs._M_manager(_Op_xfer, &__rhs, &__arg);
	  __arg._M_any = &__rhs;
	  _M_manager(_Op_xfer, this, &__arg);
	  __arg._M_any = this;
	  __tmp._M_manager(_Op_xfer, &__tmp, &__arg);
	}
      else
	{
	  any* __empty = empty() ? this : &__rhs;
	  any* __full = empty() ? &__rhs : this;
	  _Arg __arg;
	  __arg._M_any = __empty;
	  __full->_M_manager(_Op_xfer, __full, &__arg);
	}
    }

    // observers

    /// Reports whether there is a contained object or not.
    bool empty() const noexcept { return _M_manager == nullptr; }

#if __cpp_rtti
    /// The @c typeid of the contained object, or @c typeid(void) if empty.
    const type_info& type() const noexcept
    {
      if (empty())
	return typeid(void);
      _Arg __arg;
      _M_manager(_Op_get_type_info, this, &__arg);
      return *__arg._M_typeinfo;
    }
#endif

    template<typename _Tp>
      static constexpr bool __is_valid_cast()
      { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }

  private:
    enum _Op {
	_Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer
    };

    union _Arg
    {
	void* _M_obj;
	const std::type_info* _M_typeinfo;
	any* _M_any;
    };

    void (*_M_manager)(_Op, const any*, _Arg*);
    _Storage _M_storage;

    template<typename _Tp>
      friend void* __any_caster(const any* __any);

    // Manage in-place contained object.
    template<typename _Tp>
      struct _Manager_internal
      {
	static void
	_S_manage(_Op __which, const any* __anyp, _Arg* __arg);

	template<typename _Up>
	  static void
	  _S_create(_Storage& __storage, _Up&& __value)
	  {
	    void* __addr = &__storage._M_buffer;
	    ::new (__addr) _Tp(std::forward<_Up>(__value));
	  }
      };

    // Manage external contained object.
    template<typename _Tp>
      struct _Manager_external
      {
	static void
	_S_manage(_Op __which, const any* __anyp, _Arg* __arg);

	template<typename _Up>
	  static void
	  _S_create(_Storage& __storage, _Up&& __value)
	  {
	    __storage._M_ptr = new _Tp(std::forward<_Up>(__value));
	  }
      };
  };

  /// Exchange the states of two @c any objects.
  inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); }

  /**
   * @brief Access the contained object.
   *
   * @tparam  _ValueType  A const-reference or CopyConstructible type.
   * @param   __any       The object to access.
   * @return  The contained object.
   * @throw   bad_any_cast If <code>
   *          __any.type() != typeid(remove_reference_t<_ValueType>)
   *          </code>
   */
  template<typename _ValueType>
    inline _ValueType any_cast(const any& __any)
    {
      static_assert(any::__is_valid_cast<_ValueType>(),
	  "Template argument must be a reference or CopyConstructible type");
      auto __p = any_cast<add_const_t<remove_reference_t<_ValueType>>>(&__any);
      if (__p)
	return *__p;
      __throw_bad_any_cast();
    }

  /**
   * @brief Access the contained object.
   *
   * @tparam  _ValueType  A reference or CopyConstructible type.
   * @param   __any       The object to access.
   * @return  The contained object.
   * @throw   bad_any_cast If <code>
   *          __any.type() != typeid(remove_reference_t<_ValueType>)
   *          </code>
   *
   * @{
   */
  template<typename _ValueType>
    inline _ValueType any_cast(any& __any)
    {
      static_assert(any::__is_valid_cast<_ValueType>(),
	  "Template argument must be a reference or CopyConstructible type");
      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
      if (__p)
	return *__p;
      __throw_bad_any_cast();
    }

  template<typename _ValueType,
           typename enable_if<!is_move_constructible<_ValueType>::value
                              || is_lvalue_reference<_ValueType>::value,
                              bool>::type = true>
    inline _ValueType any_cast(any&& __any)
    {
      static_assert(any::__is_valid_cast<_ValueType>(),
	  "Template argument must be a reference or CopyConstructible type");
      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
      if (__p)
	return *__p;
      __throw_bad_any_cast();
    }

  template<typename _ValueType,
           typename enable_if<is_move_constructible<_ValueType>::value
                              && !is_lvalue_reference<_ValueType>::value,
                              bool>::type = false>
    inline _ValueType any_cast(any&& __any)
    {
      static_assert(any::__is_valid_cast<_ValueType>(),
	  "Template argument must be a reference or CopyConstructible type");
      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
      if (__p)
	return std::move(*__p);
      __throw_bad_any_cast();
    }
  // @}

  template<typename _Tp>
    void* __any_caster(const any* __any)
    {
      if (__any->_M_manager != &any::_Manager<decay_t<_Tp>>::_S_manage)
	return nullptr;
      any::_Arg __arg;
      __any->_M_manager(any::_Op_access, __any, &__arg);
      return __arg._M_obj;
    }

  /**
   * @brief Access the contained object.
   *
   * @tparam  _ValueType  The type of the contained object.
   * @param   __any       A pointer to the object to access.
   * @return  The address of the contained object if <code>
   *          __any != nullptr && __any.type() == typeid(_ValueType)
   *          </code>, otherwise a null pointer.
   *
   * @{
   */
  template<typename _ValueType>
    inline const _ValueType* any_cast(const any* __any) noexcept
    {
      if (__any)
	return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
      return nullptr;
    }

  template<typename _ValueType>
    inline _ValueType* any_cast(any* __any) noexcept
    {
      if (__any)
	return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
      return nullptr;
    }
  // @}

  template<typename _Tp>
    void
    any::_Manager_internal<_Tp>::
    _S_manage(_Op __which, const any* __any, _Arg* __arg)
    {
      // The contained object is in _M_storage._M_buffer
      auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer);
      switch (__which)
      {
      case _Op_access:
	__arg->_M_obj = const_cast<_Tp*>(__ptr);
	break;
      case _Op_get_type_info:
#if __cpp_rtti
	__arg->_M_typeinfo = &typeid(_Tp);
#endif
	break;
      case _Op_clone:
	::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
	__arg->_M_any->_M_manager = __any->_M_manager;
	break;
      case _Op_destroy:
	__ptr->~_Tp();
	break;
      case _Op_xfer:
	::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
	__ptr->~_Tp();
	__arg->_M_any->_M_manager = __any->_M_manager;
	const_cast<any*>(__any)->_M_manager = nullptr;
	break;
      }
    }

  template<typename _Tp>
    void
    any::_Manager_external<_Tp>::
    _S_manage(_Op __which, const any* __any, _Arg* __arg)
    {
      // The contained object is *_M_storage._M_ptr
      auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr);
      switch (__which)
      {
      case _Op_access:
	__arg->_M_obj = const_cast<_Tp*>(__ptr);
	break;
      case _Op_get_type_info:
#if __cpp_rtti
	__arg->_M_typeinfo = &typeid(_Tp);
#endif
	break;
      case _Op_clone:
	__arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr);
	__arg->_M_any->_M_manager = __any->_M_manager;
	break;
      case _Op_destroy:
	delete __ptr;
	break;
      case _Op_xfer:
	__arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr;
	__arg->_M_any->_M_manager = __any->_M_manager;
	const_cast<any*>(__any)->_M_manager = nullptr;
	break;
      }
    }

  // @} group any
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace fundamentals_v1
} // namespace experimental
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_ANY
