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

// Copyright (C) 2014-2021 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.
 *  @ingroup libfund-ts
 */

#ifndef _GLIBCXX_EXPERIMENTAL_ANY
#define _GLIBCXX_EXPERIMENTAL_ANY 1

#pragma GCC system_header

#if __cplusplus >= 201402L

#include <typeinfo>
#include <new>
#include <type_traits>
#include <bits/move.h>
#include <experimental/bits/lfts_config.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace experimental
{
inline namespace fundamentals_v1
{
  /**
   * @defgroup any Type-safe container of any type
   * @ingroup libfund-ts
   *
   * 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"; }
  };

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

  /**
   *  @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)
    {
      *this = any(__rhs);
      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)
	{
	  clear();
	  _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.
    _GLIBCXX_NODISCARD 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 enable_if_t<is_object<_Tp>::value, 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();
    }
  /// @}

  /// @cond undocumented
  template<typename _Tp>
    enable_if_t<is_object<_Tp>::value, void*>
    __any_caster(const any* __any)
    {
      // any_cast<T> returns non-null if __any->type() == typeid(T) and
      // typeid(T) ignores cv-qualifiers so remove them:
      using _Up = remove_cv_t<_Tp>;
      // The contained value has a decayed type, so if decay_t<U> is not U,
      // then it's not possible to have a contained value of type U.
      using __does_not_decay = is_same<decay_t<_Up>, _Up>;
      // Only copy constructible types can be used for contained values.
      using __is_copyable = is_copy_constructible<_Up>;
      // If the type _Tp could never be stored in an any we don't want to
      // instantiate _Manager<_Tp>, so use _Manager<any::_Op> instead, which
      // is explicitly specialized and has a no-op _S_manage function.
      using _Vp = __conditional_t<__and_<__does_not_decay, __is_copyable>{},
				  _Up, any::_Op>;
      // First try comparing function addresses, which works without RTTI
      if (__any->_M_manager == &any::_Manager<_Vp>::_S_manage
#if __cpp_rtti
	  || __any->type() == typeid(_Tp)
#endif
	  )
	{
	  any::_Arg __arg;
	  __any->_M_manager(any::_Op_access, __any, &__arg);
	  return __arg._M_obj;
	}
      return nullptr;
    }

  // This overload exists so that std::any_cast<void(*)()>(a) is well-formed.
  template<typename _Tp>
    enable_if_t<!is_object<_Tp>::value, _Tp*>
    __any_caster(const any*) noexcept
    { return nullptr; }
  /// @endcond

  /**
   * @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
	  (std::move(*const_cast<_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;
      }
    }

  // Dummy specialization used by __any_caster.
  template<>
    struct any::_Manager_internal<any::_Op>
    {
      static void
      _S_manage(_Op, const any*, _Arg*) { }
    };

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

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_ANY
