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

// Copyright (C) 2014-2015 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
    {
      void* _M_ptr;
      std::aligned_storage<sizeof(_M_ptr), sizeof(_M_ptr)>::type _M_buffer;
    };

    template<typename _Tp, typename _Safe = is_trivially_copyable<_Tp>,
	     bool _Fits = (sizeof(_Tp) <= sizeof(_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) : _M_manager(__other._M_manager)
    {
      if (!__other.empty())
	{
	  _Arg __arg;
	  __arg._M_any = this;
	  _M_manager(_Op_clone, &__other, &__arg);
	}
    }

    /**
     * @brief Move constructor, transfer the state from @p __other
     *
     * @post @c __other.empty() (not guaranteed for other implementations)
     */
    any(any&& __other) noexcept
    : _M_manager(__other._M_manager),
      _M_storage(__other._M_storage)
    { __other._M_manager = nullptr; }

    /// Construct with a copy of @p __value as the contained object.
    template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
	      typename _Mgr = _Manager<_Tp>>
      any(_ValueType&& __value)
      : _M_manager(&_Mgr::_S_manage),
        _M_storage(_Mgr::_S_create(std::forward<_ValueType>(__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 
    any& operator=(const any& __rhs)
    {
      any(__rhs).swap(*this);
      return *this;
    }

    /**
     * @brief Move assignment operator
     *
     * @post @c __rhs.empty() (not guaranteed for other implementations)
     */
    any& operator=(any&& __rhs) noexcept
    {
      any(std::move(__rhs)).swap(*this);
      return *this;
    }

    /// Store a copy of @p __rhs as the contained object.
    template<typename _ValueType>
      any& operator=(_ValueType&& __rhs)
      {
	any(std::forward<_ValueType>(__rhs)).swap(*this);
	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
    {
      std::swap(_M_manager, __rhs._M_manager);
      std::swap(_M_storage, __rhs._M_storage);
    }

    // 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 };

    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)
      {
	if (__any->_M_manager != &_Manager<decay_t<_Tp>>::_S_manage)
	  return nullptr;
	_Arg __arg;
	__any->_M_manager(_Op_access, __any, &__arg);
	return __arg._M_obj;
      }

    // 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 _Storage
	  _S_create(_Up&& __value)
	  {
	    _Storage __storage;
	    void* __addr = &__storage._M_buffer;
	    ::new (__addr) _Tp(std::forward<_Up>(__value));
	    return __storage;
	  }

	template<typename _Alloc, typename _Up>
	  static _Storage
	  _S_alloc(const _Alloc&, _Up&& __value)
	  {
	    return _S_create(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 _Storage
	  _S_create(_Up&& __value)
	  {
	    _Storage __storage;
	    __storage._M_ptr = new _Tp(std::forward<_Up>(__value));
	    return __storage;
	  }
      };
  };

  /// 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>
    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();
    }
  // @}

  /**
   * @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);
	break;
      case _Op_destroy:
	__ptr->~_Tp();
	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);
	break;
      case _Op_destroy:
	delete __ptr;
	break;
      }
    }

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

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_ANY
