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

// Copyright (C) 2015-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 experimental/propagate_const
 *  This is a TS C++ Library header.
 */

#ifndef _GLIBCXX_EXPERIMENTAL_PROPAGATE_CONST
#define _GLIBCXX_EXPERIMENTAL_PROPAGATE_CONST 1

#pragma GCC system_header

#if __cplusplus >= 201402L

#include <type_traits>
#include <bits/functional_hash.h>
#include <bits/move.h>
#include <bits/stl_function.h>
#include <experimental/bits/lfts_config.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace experimental
{
inline namespace fundamentals_v2
{
  /**
   * @defgroup propagate_const Const-propagating wrapper
   * @ingroup experimental
   *
   * A const-propagating wrapper that propagates const to pointer-like members,
   * as described in n4388 "A Proposal to Add a Const-Propagating Wrapper
   * to the Standard Library".
   *
   * @{
   */

/// Const-propagating wrapper.
  template <typename _Tp>
    class propagate_const
    {
    public:
      typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type;

    private:
      template <typename _Up>
	struct __is_propagate_const : false_type
	{ };

      template <typename _Up>
	struct __is_propagate_const<propagate_const<_Up>> : true_type
	{ };

      template <typename _Up>
	friend constexpr const _Up&
	get_underlying(const propagate_const<_Up>& __pt) noexcept;
      template <typename _Up>
	friend constexpr _Up&
	get_underlying(propagate_const<_Up>& __pt) noexcept;

      template <typename _Up>
	static constexpr element_type*
	__to_raw_pointer(_Up* __u)
	{ return __u; }

      template <typename _Up>
	static constexpr element_type*
	__to_raw_pointer(_Up& __u)
	{ return __u.get(); }

      template <typename _Up>
	static constexpr const element_type*
	__to_raw_pointer(const _Up* __u)
	{ return __u; }

      template <typename _Up>
	static constexpr const element_type*
	__to_raw_pointer(const _Up& __u)
	{ return __u.get(); }

    public:
      static_assert(__and_<is_object<typename remove_pointer<_Tp>::type>,
			   __not_<is_array<_Tp>>,
			   __or_<is_class<_Tp>, is_pointer<_Tp>>>::value,
		    "propagate_const requires a class or a pointer to an"
		    " object type");

      // [propagate_const.ctor], constructors
      constexpr propagate_const() = default;
      propagate_const(const propagate_const& __p) = delete;
      constexpr propagate_const(propagate_const&& __p) = default;
      template <typename _Up, typename
		enable_if<__and_<is_constructible<_Tp, _Up&&>,
				 is_convertible<_Up&&, _Tp>>::value, bool
			  >::type=true>
      constexpr propagate_const(propagate_const<_Up>&& __pu)
	: _M_t(std::move(get_underlying(__pu)))
      {}
      template <typename _Up, typename
		enable_if<__and_<is_constructible<_Tp, _Up&&>,
				 __not_<is_convertible<_Up&&, _Tp>>>::value,
			  bool>::type=false>
      constexpr explicit propagate_const(propagate_const<_Up>&& __pu)
	: _M_t(std::move(get_underlying(__pu)))
      {}
      template <typename _Up, typename
		enable_if<__and_<is_constructible<_Tp, _Up&&>,
				 is_convertible<_Up&&, _Tp>,
				 __not_<__is_propagate_const<
					  typename decay<_Up>::type>>
				 >::value, bool>::type=true>
      constexpr propagate_const(_Up&& __u)
	: _M_t(std::forward<_Up>(__u))
      {}
      template <typename _Up, typename
		enable_if<__and_<is_constructible<_Tp, _Up&&>,
				 __not_<is_convertible<_Up&&, _Tp>>,
				 __not_<__is_propagate_const<
					  typename decay<_Up>::type>>
				 >::value, bool>::type=false>
      constexpr explicit propagate_const(_Up&& __u)
	: _M_t(std::forward<_Up>(__u))
      {}

      // [propagate_const.assignment], assignment
      propagate_const& operator=(const propagate_const& __p) = delete;
      constexpr propagate_const& operator=(propagate_const&& __p) = default;

      template <typename _Up, typename =
		typename enable_if<is_convertible<_Up&&, _Tp>::value>::type>
      constexpr propagate_const& operator=(propagate_const<_Up>&& __pu)
      {
	_M_t = std::move(get_underlying(__pu));
	return *this;
      }

      template <typename _Up, typename =
		typename enable_if<__and_<is_convertible<_Up&&, _Tp>,
					  __not_<__is_propagate_const<
						   typename decay<_Up>::type>>
					  >::value>::type>
      constexpr propagate_const& operator=(_Up&& __u)
      {
	_M_t = std::forward<_Up>(__u);
	return *this;
      }

      // [propagate_const.const_observers], const observers
      explicit constexpr operator bool() const
      {
	return bool(_M_t);
      }

      constexpr const element_type* operator->() const
      {
	return get();
      }

      template <typename _Up = _Tp,
		typename enable_if<__or_<is_pointer<_Up>,
					 is_convertible<_Up,
							const element_type*>
					 >::value, bool>::type = true>
      constexpr operator const element_type*() const
      {
	return get();
      }

      constexpr const element_type& operator*() const
      {
	return *get();
      }

      constexpr const element_type* get() const
      {
	return __to_raw_pointer(_M_t);
      }

      // [propagate_const.non_const_observers], non-const observers
      constexpr element_type* operator->()
      {
	return get();
      }

      template <typename _Up = _Tp,
		typename enable_if<__or_<is_pointer<_Up>,
					 is_convertible<_Up,
						        const element_type*>
					 >::value, bool>::type = true>
      constexpr operator element_type*()
      {
	return get();
      }

      constexpr element_type& operator*()
      {
	return *get();
      }

      constexpr element_type* get()
      {
	return __to_raw_pointer(_M_t);
      }

      // [propagate_const.modifiers], modifiers
      constexpr void
      swap(propagate_const& __pt) noexcept(__is_nothrow_swappable<_Tp>::value)
      {
	using std::swap;
	swap(_M_t, get_underlying(__pt));
      }

    private:
      _Tp _M_t;
    };

  // [propagate_const.relational], relational operators
  template <typename _Tp>
    constexpr bool
    operator==(const propagate_const<_Tp>& __pt, nullptr_t)
    {
      return get_underlying(__pt) == nullptr;
    }

  template <typename _Tp>
    constexpr bool
    operator==(nullptr_t, const propagate_const<_Tp>& __pu)
    {
      return nullptr == get_underlying(__pu);
    }

  template <typename _Tp>
    constexpr bool
    operator!=(const propagate_const<_Tp>& __pt, nullptr_t)
    {
      return get_underlying(__pt) != nullptr;
    }

  template <typename _Tp>
    constexpr bool operator!=(nullptr_t, const propagate_const<_Tp>& __pu)
    {
      return nullptr != get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator==(const propagate_const<_Tp>& __pt,
	       const propagate_const<_Up>& __pu)
    {
      return get_underlying(__pt) == get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator!=(const propagate_const<_Tp>& __pt,
	       const propagate_const<_Up>& __pu)
    {
      return get_underlying(__pt) != get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator<(const propagate_const<_Tp>& __pt,
	      const propagate_const<_Up>& __pu)
    {
      return get_underlying(__pt) < get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator>(const propagate_const<_Tp>& __pt,
	      const propagate_const<_Up>& __pu)
    {
      return get_underlying(__pt) > get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator<=(const propagate_const<_Tp>& __pt,
	       const propagate_const<_Up>& __pu)
    {
      return get_underlying(__pt) <= get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator>=(const propagate_const<_Tp>& __pt,
	       const propagate_const<_Up>& __pu)
    {
      return get_underlying(__pt) >= get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator==(const propagate_const<_Tp>& __pt, const _Up& __u)
    {
      return get_underlying(__pt) == __u;
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator!=(const propagate_const<_Tp>& __pt, const _Up& __u)
    {
      return get_underlying(__pt) != __u;
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator<(const propagate_const<_Tp>& __pt, const _Up& __u)
    {
      return get_underlying(__pt) < __u;
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator>(const propagate_const<_Tp>& __pt, const _Up& __u)
    {
      return get_underlying(__pt) > __u;
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator<=(const propagate_const<_Tp>& __pt, const _Up& __u)
    {
      return get_underlying(__pt) <= __u;
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator>=(const propagate_const<_Tp>& __pt, const _Up& __u)
    {
      return get_underlying(__pt) >= __u;
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator==(const _Tp& __t, const propagate_const<_Up>& __pu)
    {
      return __t == get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator!=(const _Tp& __t, const propagate_const<_Up>& __pu)
    {
      return __t != get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator<(const _Tp& __t, const propagate_const<_Up>& __pu)
    {
      return __t < get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator>(const _Tp& __t, const propagate_const<_Up>& __pu)
    {
      return __t > get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator<=(const _Tp& __t, const propagate_const<_Up>& __pu)
    {
      return __t <= get_underlying(__pu);
    }

  template <typename _Tp, typename _Up>
    constexpr bool
    operator>=(const _Tp& __t, const propagate_const<_Up>& __pu)
    {
      return __t >= get_underlying(__pu);
    }

  // [propagate_const.algorithms], specialized algorithms
  template <typename _Tp>
    constexpr void
    swap(propagate_const<_Tp>& __pt, propagate_const<_Tp>& __pt2)
      noexcept(__is_nothrow_swappable<_Tp>::value)
    {
      __pt.swap(__pt2);
    }

  // [propagate_const.underlying], underlying pointer access
  template <typename _Tp>
    constexpr const _Tp&
    get_underlying(const propagate_const<_Tp>& __pt) noexcept
    {
      return __pt._M_t;
    }

  template <typename _Tp>
    constexpr _Tp&
    get_underlying(propagate_const<_Tp>& __pt) noexcept
    {
      return __pt._M_t;
    }

  // @} group propagate_const
} // namespace fundamentals_v2
} // namespace experimental

// [propagate_const.hash], hash support
 template <typename _Tp>
   struct hash<experimental::propagate_const<_Tp>>
   {
     using result_type = size_t;
     using argument_type = experimental::propagate_const<_Tp>;

     size_t
     operator()(const experimental::propagate_const<_Tp>& __t) const
     noexcept(noexcept(hash<_Tp>{}(get_underlying(__t))))
     {
       return hash<_Tp>{}(get_underlying(__t));
     }
   };

 // [propagate_const.comparison_function_objects], comparison function objects
 template <typename _Tp>
   struct equal_to<experimental::propagate_const<_Tp>>
   {
     constexpr bool
     operator()(const experimental::propagate_const<_Tp>& __x,
	        const experimental::propagate_const<_Tp>& __y) const
     {
       return equal_to<_Tp>{}(get_underlying(__x), get_underlying(__y));
     }

     typedef experimental::propagate_const<_Tp> first_argument_type;
     typedef experimental::propagate_const<_Tp> second_argument_type;
     typedef bool result_type;
   };

 template <typename _Tp>
   struct not_equal_to<experimental::propagate_const<_Tp>>
   {
     constexpr bool
     operator()(const experimental::propagate_const<_Tp>& __x,
		const experimental::propagate_const<_Tp>& __y) const
     {
       return not_equal_to<_Tp>{}(get_underlying(__x), get_underlying(__y));
     }

     typedef experimental::propagate_const<_Tp> first_argument_type;
     typedef experimental::propagate_const<_Tp> second_argument_type;
     typedef bool result_type;
   };

 template <typename _Tp>
   struct less<experimental::propagate_const<_Tp>>
   {
     constexpr bool
     operator()(const experimental::propagate_const<_Tp>& __x,
		const experimental::propagate_const<_Tp>& __y) const
     {
       return less<_Tp>{}(get_underlying(__x), get_underlying(__y));
     }

     typedef experimental::propagate_const<_Tp> first_argument_type;
     typedef experimental::propagate_const<_Tp> second_argument_type;
     typedef bool result_type;
   };

 template <typename _Tp>
   struct greater<experimental::propagate_const<_Tp>>
   {
     constexpr bool
     operator()(const experimental::propagate_const<_Tp>& __x,
		const experimental::propagate_const<_Tp>& __y) const
     {
       return greater<_Tp>{}(get_underlying(__x), get_underlying(__y));
     }

     typedef experimental::propagate_const<_Tp> first_argument_type;
     typedef experimental::propagate_const<_Tp> second_argument_type;
     typedef bool result_type;
   };

 template <typename _Tp>
   struct less_equal<experimental::propagate_const<_Tp>>
   {
     constexpr bool
     operator()(const experimental::propagate_const<_Tp>& __x,
	        const experimental::propagate_const<_Tp>& __y) const
     {
       return less_equal<_Tp>{}(get_underlying(__x), get_underlying(__y));
     }

     typedef experimental::propagate_const<_Tp> first_argument_type;
     typedef experimental::propagate_const<_Tp> second_argument_type;
     typedef bool result_type;
   };

 template <typename _Tp>
   struct greater_equal<experimental::propagate_const<_Tp>>
   {
     constexpr bool
     operator()(const experimental::propagate_const<_Tp>& __x,
		const experimental::propagate_const<_Tp>& __y) const
     {
       return greater_equal<_Tp>{}(get_underlying(__x), get_underlying(__y));
     }

     typedef experimental::propagate_const<_Tp> first_argument_type;
     typedef experimental::propagate_const<_Tp> second_argument_type;
     typedef bool result_type;
   };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_PROPAGATE_CONST
