// <concepts> -*- C++ -*-

// Copyright (C) 2019-2020 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/concepts
 *  This is a Standard C++ Library header.
 *  @ingroup concepts
 */

#ifndef _GLIBCXX_CONCEPTS
#define _GLIBCXX_CONCEPTS 1

#if __cplusplus > 201703L && __cpp_concepts >= 201907L

#pragma GCC system_header

/**
 * @defgroup concepts Concepts
 * @ingroup utilities
 *
 * Concepts for checking type requirements.
 */

#include <type_traits>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#define __cpp_lib_concepts 202002L

  // [concepts.lang], language-related concepts

  namespace __detail
  {
    template<typename _Tp, typename _Up>
      concept __same_as = std::is_same_v<_Tp, _Up>;
  } // namespace __detail

  /// [concept.same], concept same_as
  template<typename _Tp, typename _Up>
    concept same_as
      = __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>;

  /// [concept.derived], concept derived_from
  template<typename _Derived, typename _Base>
    concept derived_from = __is_base_of(_Base, _Derived)
      && is_convertible_v<const volatile _Derived*, const volatile _Base*>;

  /// [concept.convertible], concept convertible_to
  template<typename _From, typename _To>
    concept convertible_to = is_convertible_v<_From, _To>
      && requires(add_rvalue_reference_t<_From> (&__f)()) {
	  static_cast<_To>(__f());
      };

  /// [concept.commonref], concept common_reference_with
  template<typename _Tp, typename _Up>
    concept common_reference_with
      = same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>>
      && convertible_to<_Tp, common_reference_t<_Tp, _Up>>
      && convertible_to<_Up, common_reference_t<_Tp, _Up>>;

  /// [concept.common], concept common_with
  template<typename _Tp, typename _Up>
    concept common_with
      = same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>>
      && requires {
	static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>());
	static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>());
      }
      && common_reference_with<add_lvalue_reference_t<const _Tp>,
			       add_lvalue_reference_t<const _Up>>
      && common_reference_with<add_lvalue_reference_t<common_type_t<_Tp, _Up>>,
			       common_reference_t<
				 add_lvalue_reference_t<const _Tp>,
				 add_lvalue_reference_t<const _Up>>>;

  // [concepts.arithmetic], arithmetic concepts

  template<typename _Tp>
    concept integral = is_integral_v<_Tp>;

  template<typename _Tp>
    concept signed_integral = integral<_Tp> && is_signed_v<_Tp>;

  template<typename _Tp>
    concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>;

  template<typename _Tp>
    concept floating_point = is_floating_point_v<_Tp>;

  namespace __detail
  {
    template<typename _Tp>
      using __cref = const remove_reference_t<_Tp>&;

      template<typename _Tp>
	concept __class_or_enum
	  = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>;
  } // namespace __detail

  /// [concept.assignable], concept assignable_from
  template<typename _Lhs, typename _Rhs>
    concept assignable_from
      = is_lvalue_reference_v<_Lhs>
      && common_reference_with<__detail::__cref<_Lhs>, __detail::__cref<_Rhs>>
      && requires(_Lhs __lhs, _Rhs&& __rhs) {
	{ __lhs = static_cast<_Rhs&&>(__rhs) } -> same_as<_Lhs>;
      };

  /// [concept.destructible], concept destructible
  template<typename _Tp>
    concept destructible = is_nothrow_destructible_v<_Tp>;

  /// [concept.constructible], concept constructible_from
  template<typename _Tp, typename... _Args>
    concept constructible_from
      = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;

  /// [concept.defaultinitializable], concept default_initializable
  template<typename _Tp>
    concept default_initializable = constructible_from<_Tp>
      && requires
      {
	_Tp{};
	(void) ::new _Tp;
      };

  /// [concept.moveconstructible], concept move_constructible
  template<typename _Tp>
    concept move_constructible
    = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;

  /// [concept.copyconstructible], concept copy_constructible
  template<typename _Tp>
    concept copy_constructible
      = move_constructible<_Tp>
      && constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp>
      && constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp>
      && constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>;

  // [concept.swappable], concept swappable

  namespace ranges
  {
    namespace __cust_swap
    {
      template<typename _Tp> void swap(_Tp&, _Tp&) = delete;

      template<typename _Tp, typename _Up>
	concept __adl_swap
	  = (__detail::__class_or_enum<remove_reference_t<_Tp>>
	    || __detail::__class_or_enum<remove_reference_t<_Up>>)
	  && requires(_Tp&& __t, _Up&& __u) {
	    swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
	  };

      struct _Swap
      {
      private:
	template<typename _Tp, typename _Up>
	  static constexpr bool
	  _S_noexcept()
	  {
	    if constexpr (__adl_swap<_Tp, _Up>)
	      return noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()));
	    else
	      return is_nothrow_move_constructible_v<remove_reference_t<_Tp>>
		   && is_nothrow_move_assignable_v<remove_reference_t<_Tp>>;
	  }

      public:
	template<typename _Tp, typename _Up>
	  requires __adl_swap<_Tp, _Up>
	  || (same_as<_Tp, _Up> && is_lvalue_reference_v<_Tp>
	      && move_constructible<remove_reference_t<_Tp>>
	      && assignable_from<_Tp, remove_reference_t<_Tp>>)
	  constexpr void
	  operator()(_Tp&& __t, _Up&& __u) const
	  noexcept(_S_noexcept<_Tp, _Up>())
	  {
	    if constexpr (__adl_swap<_Tp, _Up>)
	      swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
	    else
	      {
		auto __tmp = static_cast<remove_reference_t<_Tp>&&>(__t);
		__t = static_cast<remove_reference_t<_Tp>&&>(__u);
		__u = static_cast<remove_reference_t<_Tp>&&>(__tmp);
	      }
	  }

	template<typename _Tp, typename _Up, size_t _Num>
	  requires requires(const _Swap& __swap, _Tp& __e1, _Up& __e2) {
	    __swap(__e1, __e2);
	  }
	  constexpr void
	  operator()(_Tp (&__e1)[_Num], _Up (&__e2)[_Num]) const
	  noexcept(noexcept(std::declval<const _Swap&>()(*__e1, *__e2)))
	  {
	    for (size_t __n = 0; __n < _Num; ++__n)
	      (*this)(__e1[__n], __e2[__n]);
	  }
      };
    } // namespace __cust_swap

    inline namespace __cust
    {
      inline constexpr __cust_swap::_Swap swap{};
    } // inline namespace __cust
  } // namespace ranges

  template<typename _Tp>
    concept swappable
      = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); };

  template<typename _Tp, typename _Up>
    concept swappable_with = common_reference_with<_Tp, _Up>
      && requires(_Tp&& __t, _Up&& __u) {
	ranges::swap(static_cast<_Tp&&>(__t), static_cast<_Tp&&>(__t));
	ranges::swap(static_cast<_Up&&>(__u), static_cast<_Up&&>(__u));
	ranges::swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
	ranges::swap(static_cast<_Up&&>(__u), static_cast<_Tp&&>(__t));
      };

  // [concepts.object], Object concepts

  template<typename _Tp>
    concept movable = is_object_v<_Tp> && move_constructible<_Tp>
      && assignable_from<_Tp&, _Tp> && swappable<_Tp>;

  template<typename _Tp>
    concept copyable = copy_constructible<_Tp> && movable<_Tp>
      && assignable_from<_Tp&, _Tp&> && assignable_from<_Tp&, const _Tp&>
      && assignable_from<_Tp&, const _Tp>;

  template<typename _Tp>
    concept semiregular = copyable<_Tp> && default_initializable<_Tp>;

  // [concepts.compare], comparison concepts

  // [concept.booleantestable], Boolean testability
  namespace __detail
  {
    template<typename _Tp>
      concept __boolean_testable_impl = convertible_to<_Tp, bool>;

    template<typename _Tp>
      concept __boolean_testable
	= __boolean_testable_impl<_Tp>
	  && requires(_Tp&& __t)
	  { { !static_cast<_Tp&&>(__t) } -> __boolean_testable_impl; };
  } // namespace __detail

  // [concept.equalitycomparable], concept equality_comparable

  namespace __detail
  {
    template<typename _Tp, typename _Up>
      concept __weakly_eq_cmp_with
	= requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) {
	  { __t == __u } -> __boolean_testable;
	  { __t != __u } -> __boolean_testable;
	  { __u == __t } -> __boolean_testable;
	  { __u != __t } -> __boolean_testable;
	};
  } // namespace __detail

  template<typename _Tp>
    concept equality_comparable = __detail::__weakly_eq_cmp_with<_Tp, _Tp>;

  template<typename _Tp, typename _Up>
    concept equality_comparable_with
      = equality_comparable<_Tp> && equality_comparable<_Up>
      && common_reference_with<__detail::__cref<_Tp>, __detail::__cref<_Up>>
      && equality_comparable<common_reference_t<__detail::__cref<_Tp>,
						__detail::__cref<_Up>>>
      && __detail::__weakly_eq_cmp_with<_Tp, _Up>;

  namespace __detail
  {
    template<typename _Tp, typename _Up>
      concept __partially_ordered_with
	= requires(const remove_reference_t<_Tp>& __t,
		   const remove_reference_t<_Up>& __u) {
	  { __t <  __u } -> __boolean_testable;
	  { __t >  __u } -> __boolean_testable;
	  { __t <= __u } -> __boolean_testable;
	  { __t >= __u } -> __boolean_testable;
	  { __u <  __t } -> __boolean_testable;
	  { __u >  __t } -> __boolean_testable;
	  { __u <= __t } -> __boolean_testable;
	  { __u >= __t } -> __boolean_testable;
	};
  } // namespace __detail

  // [concept.totallyordered], concept totally_ordered
  template<typename _Tp>
    concept totally_ordered
      = equality_comparable<_Tp>
      && __detail::__partially_ordered_with<_Tp, _Tp>;

  template<typename _Tp, typename _Up>
    concept totally_ordered_with
      = totally_ordered<_Tp> && totally_ordered<_Up>
      && equality_comparable_with<_Tp, _Up>
      && totally_ordered<common_reference_t<__detail::__cref<_Tp>,
					    __detail::__cref<_Up>>>
      && __detail::__partially_ordered_with<_Tp, _Up>;

  template<typename _Tp>
    concept regular = semiregular<_Tp> && equality_comparable<_Tp>;

  // [concepts.callable], callable concepts

  /// [concept.invocable], concept invocable
  template<typename _Fn, typename... _Args>
    concept invocable = is_invocable_v<_Fn, _Args...>;

  /// [concept.regularinvocable], concept regular_invocable
  template<typename _Fn, typename... _Args>
    concept regular_invocable = invocable<_Fn, _Args...>;

  /// [concept.predicate], concept predicate
  template<typename _Fn, typename... _Args>
    concept predicate = regular_invocable<_Fn, _Args...>
      && __detail::__boolean_testable<invoke_result_t<_Fn, _Args...>>;

  /// [concept.relation], concept relation
  template<typename _Rel, typename _Tp, typename _Up>
    concept relation
      = predicate<_Rel, _Tp, _Tp> && predicate<_Rel, _Up, _Up>
      && predicate<_Rel, _Tp, _Up> && predicate<_Rel, _Up, _Tp>;

  /// [concept.equiv], concept equivalence_relation
  template<typename _Rel, typename _Tp, typename _Up>
    concept equivalence_relation = relation<_Rel, _Tp, _Up>;

  /// [concept.strictweakorder], concept strict_weak_order
  template<typename _Rel, typename _Tp, typename _Up>
    concept strict_weak_order = relation<_Rel, _Tp, _Up>;

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++2a

#endif /* _GLIBCXX_CONCEPTS */
