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

// Copyright (C) 2014-2019 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 include/any
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_ANY
#define _GLIBCXX_ANY 1

#pragma GCC system_header

#if __cplusplus >= 201703L

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

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   *  @addtogroup utilities
   *  @{
   */

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

#define __cpp_lib_any 201606L

  /**
   *  @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
    {
      constexpr _Storage() : _M_ptr{nullptr} {}

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

    /// Emplace with an object created from @p __args as the contained object.
    template <typename _Tp, typename... _Args,
	      typename _Mgr = _Manager<_Tp>>
      void __do_emplace(_Args&&... __args)
      {
	reset();
        _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
	_M_manager = &_Mgr::_S_manage;
      }

    /// Emplace with an object created from @p __il and @p __args as
    /// the contained object.
    template <typename _Tp, typename _Up, typename... _Args,
	      typename _Mgr = _Manager<_Tp>>
      void __do_emplace(initializer_list<_Up> __il, _Args&&... __args)
      {
	reset();
        _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
	_M_manager = &_Mgr::_S_manage;
      }

  public:
    // construct/destruct

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

    /// Copy constructor, copies the state of @p __other
    any(const any& __other)
    {
      if (!__other.has_value())
	_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.has_value() (this postcondition is a GNU extension)
     */
    any(any&& __other) noexcept
    {
      if (!__other.has_value())
	_M_manager = nullptr;
      else
	{
	  _Arg __arg;
	  __arg._M_any = this;
	  __other._M_manager(_Op_xfer, &__other, &__arg);
	}
    }

    template <typename _Res, typename _Tp, typename... _Args>
    using __any_constructible =
      enable_if<__and_<is_copy_constructible<_Tp>,
			 is_constructible<_Tp, _Args...>>::value,
		  _Res>;

    template <typename _Tp, typename... _Args>
    using __any_constructible_t =
      typename __any_constructible<bool, _Tp, _Args...>::type;

    /// Construct with a copy of @p __value as the contained object.
    template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
	      typename _Mgr = _Manager<_Tp>,
              __any_constructible_t<_Tp, _ValueType&&> = true,
	      enable_if_t<!__is_in_place_type<_Tp>::value, bool> = true>
      any(_ValueType&& __value)
      : _M_manager(&_Mgr::_S_manage)
      {
        _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value));
      }

    /// Construct with a copy of @p __value as the contained object.
    template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
	      typename _Mgr = _Manager<_Tp>,
              enable_if_t<__and_v<is_copy_constructible<_Tp>,
				  __not_<is_constructible<_Tp, _ValueType&&>>,
				  __not_<__is_in_place_type<_Tp>>>,
			  bool> = false>
      any(_ValueType&& __value)
      : _M_manager(&_Mgr::_S_manage)
      {
        _Mgr::_S_create(_M_storage, __value);
      }

    /// Construct with an object created from @p __args as the contained object.
    template <typename _ValueType, typename... _Args,
	      typename _Tp = _Decay<_ValueType>,
	      typename _Mgr = _Manager<_Tp>,
              __any_constructible_t<_Tp, _Args&&...> = false>
      explicit
      any(in_place_type_t<_ValueType>, _Args&&... __args)
      : _M_manager(&_Mgr::_S_manage)
      {
        _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
      }

    /// Construct with an object created from @p __il and @p __args as
    /// the contained object.
    template <typename _ValueType, typename _Up, typename... _Args,
	      typename _Tp = _Decay<_ValueType>,
	      typename _Mgr = _Manager<_Tp>,
              __any_constructible_t<_Tp, initializer_list<_Up>,
				    _Args&&...> = false>
      explicit
      any(in_place_type_t<_ValueType>,
	  initializer_list<_Up> __il, _Args&&... __args)
      : _M_manager(&_Mgr::_S_manage)
      {
        _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
      }

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

    // assignments

    /// Copy the state of another object.
    any& operator=(const any& __rhs)
    {
      *this = any(__rhs);
      return *this;
    }

    /**
     * @brief Move assignment operator
     *
     * @post @c !__rhs.has_value() (not guaranteed for other implementations)
     */
    any& operator=(any&& __rhs) noexcept
    {
      if (!__rhs.has_value())
	reset();
      else if (this != &__rhs)
	{
	  reset();
	  _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_copy_constructible<_Decay<_ValueType>>::value, any&>
      operator=(_ValueType&& __rhs)
      {
	*this = any(std::forward<_ValueType>(__rhs));
	return *this;
      }

    /// Emplace with an object created from @p __args as the contained object.
    template <typename _ValueType, typename... _Args>
      typename __any_constructible<_Decay<_ValueType>&,
				   _Decay<_ValueType>, _Args&&...>::type
      emplace(_Args&&... __args)
      {
	__do_emplace<_Decay<_ValueType>>(std::forward<_Args>(__args)...);
	any::_Arg __arg;
	this->_M_manager(any::_Op_access, this, &__arg);
	return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
      }

    /// Emplace with an object created from @p __il and @p __args as
    /// the contained object.
    template <typename _ValueType, typename _Up, typename... _Args>
      typename __any_constructible<_Decay<_ValueType>&,
				   _Decay<_ValueType>,
				   initializer_list<_Up>,
				   _Args&&...>::type
      emplace(initializer_list<_Up> __il, _Args&&... __args)
      {
	__do_emplace<_Decay<_ValueType>, _Up>(__il,
					      std::forward<_Args>(__args)...);
	any::_Arg __arg;
	this->_M_manager(any::_Op_access, this, &__arg);
	return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
      }

    // modifiers

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

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

      if (has_value() && __rhs.has_value())
	{
	  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 = !has_value() ? this : &__rhs;
	  any* __full = !has_value() ? &__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 has_value() 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 (!has_value())
	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));
	  }

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

    // 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));
	  }
	template<typename... _Args>
	  static void
	  _S_create(_Storage& __storage, _Args&&... __args)
	  {
	    __storage._M_ptr = new _Tp(std::forward<_Args>(__args)...);
	  }
      };
  };

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

  /// Create an any holding a @c _Tp constructed from @c __args.
  template <typename _Tp, typename... _Args>
    any make_any(_Args&&... __args)
    {
      return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
    }

  /// Create an any holding a @c _Tp constructed from @c __il and @c __args.
  template <typename _Tp, typename _Up, typename... _Args>
    any make_any(initializer_list<_Up> __il, _Args&&... __args)
    {
      return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
    }

  /**
   * @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)
    {
      using _Up = __remove_cvref_t<_ValueType>;
      static_assert(any::__is_valid_cast<_ValueType>(),
	  "Template argument must be a reference or CopyConstructible type");
      static_assert(is_constructible_v<_ValueType, const _Up&>,
	  "Template argument must be constructible from a const value.");
      auto __p = any_cast<_Up>(&__any);
      if (__p)
	return static_cast<_ValueType>(*__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)
    {
      using _Up = __remove_cvref_t<_ValueType>;
      static_assert(any::__is_valid_cast<_ValueType>(),
	  "Template argument must be a reference or CopyConstructible type");
      static_assert(is_constructible_v<_ValueType, _Up&>,
	  "Template argument must be constructible from an lvalue.");
      auto __p = any_cast<_Up>(&__any);
      if (__p)
	return static_cast<_ValueType>(*__p);
      __throw_bad_any_cast();
    }

  template<typename _ValueType>
    inline _ValueType any_cast(any&& __any)
    {
      using _Up = __remove_cvref_t<_ValueType>;
      static_assert(any::__is_valid_cast<_ValueType>(),
	  "Template argument must be a reference or CopyConstructible type");
      static_assert(is_constructible_v<_ValueType, _Up>,
	  "Template argument must be constructible from an rvalue.");
      auto __p = any_cast<_Up>(&__any);
      if (__p)
	return static_cast<_ValueType>(std::move(*__p));
      __throw_bad_any_cast();
    }
  // @}

  /// @cond undocumented
  template<typename _Tp>
    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:
      if constexpr (!is_same_v<decay_t<_Up>, _Up>)
	return nullptr;
      // Only copy constructible types can be used for contained values:
      else if constexpr (!is_copy_constructible_v<_Up>)
	return nullptr;
      // First try comparing function addresses, which works without RTTI
      else if (__any->_M_manager == &any::_Manager<_Up>::_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;
    }
  /// @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 constexpr (is_object_v<_ValueType>)
	if (__any)
	  return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
      return nullptr;
    }

  template<typename _ValueType>
    inline _ValueType* any_cast(any* __any) noexcept
    {
      if constexpr (is_object_v<_ValueType>)
	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;
      }
    }

  /// @}

  namespace __detail::__variant
  {
    template<typename> struct _Never_valueless_alt; // see <variant>

    // Provide the strong exception-safety guarantee when emplacing an
    // any into a variant.
    template<>
      struct _Never_valueless_alt<std::any>
      : std::true_type
      { };
  }  // namespace __detail::__variant

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++17
#endif // _GLIBCXX_ANY
