You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.4KB

  1. // Concept-constrained comparison implementations -*- C++ -*-
  2. // Copyright (C) 2019-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/range_cmp.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{functional}
  23. */
  24. #ifndef _RANGE_CMP_H
  25. #define _RANGE_CMP_H 1
  26. #if __cplusplus > 201703L
  27. # include <bits/move.h>
  28. # include <concepts>
  29. namespace std _GLIBCXX_VISIBILITY(default)
  30. {
  31. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  32. struct __is_transparent; // not defined
  33. // Define std::identity here so that <iterator> and <ranges>
  34. // don't need to include <bits/stl_function.h> to get it.
  35. /// [func.identity] The identity function.
  36. struct identity
  37. {
  38. template<typename _Tp>
  39. constexpr _Tp&&
  40. operator()(_Tp&& __t) const noexcept
  41. { return std::forward<_Tp>(__t); }
  42. using is_transparent = __is_transparent;
  43. };
  44. #ifdef __cpp_lib_concepts
  45. // Define this here, included by all the headers that need to define it.
  46. #define __cpp_lib_ranges 201911L
  47. namespace ranges
  48. {
  49. namespace __detail
  50. {
  51. // BUILTIN-PTR-CMP(T, ==, U)
  52. template<typename _Tp, typename _Up>
  53. concept __eq_builtin_ptr_cmp
  54. = requires (_Tp&& __t, _Up&& __u) { { __t == __u } -> same_as<bool>; }
  55. && convertible_to<_Tp, const volatile void*>
  56. && convertible_to<_Up, const volatile void*>
  57. && (! requires(_Tp&& __t, _Up&& __u)
  58. { operator==(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
  59. &&
  60. ! requires(_Tp&& __t, _Up&& __u)
  61. { std::forward<_Tp>(__t).operator==(std::forward<_Up>(__u)); });
  62. // BUILTIN-PTR-CMP(T, <, U)
  63. template<typename _Tp, typename _Up>
  64. concept __less_builtin_ptr_cmp
  65. = requires (_Tp&& __t, _Up&& __u) { { __t < __u } -> same_as<bool>; }
  66. && convertible_to<_Tp, const volatile void*>
  67. && convertible_to<_Up, const volatile void*>
  68. && (! requires(_Tp&& __t, _Up&& __u)
  69. { operator<(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
  70. && ! requires(_Tp&& __t, _Up&& __u)
  71. { std::forward<_Tp>(__t).operator<(std::forward<_Up>(__u)); });
  72. } // namespace __detail
  73. // [range.cmp] Concept-constrained comparisons
  74. /// ranges::equal_to function object type.
  75. struct equal_to
  76. {
  77. template<typename _Tp, typename _Up>
  78. requires equality_comparable_with<_Tp, _Up>
  79. || __detail::__eq_builtin_ptr_cmp<_Tp, _Up>
  80. constexpr bool
  81. operator()(_Tp&& __t, _Up&& __u) const
  82. noexcept(noexcept(std::declval<_Tp>() == std::declval<_Up>()))
  83. { return std::forward<_Tp>(__t) == std::forward<_Up>(__u); }
  84. using is_transparent = __is_transparent;
  85. };
  86. /// ranges::not_equal_to function object type.
  87. struct not_equal_to
  88. {
  89. template<typename _Tp, typename _Up>
  90. requires equality_comparable_with<_Tp, _Up>
  91. || __detail::__eq_builtin_ptr_cmp<_Tp, _Up>
  92. constexpr bool
  93. operator()(_Tp&& __t, _Up&& __u) const
  94. noexcept(noexcept(std::declval<_Up>() == std::declval<_Tp>()))
  95. { return !equal_to{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
  96. using is_transparent = __is_transparent;
  97. };
  98. /// ranges::less function object type.
  99. struct less
  100. {
  101. template<typename _Tp, typename _Up>
  102. requires totally_ordered_with<_Tp, _Up>
  103. || __detail::__less_builtin_ptr_cmp<_Tp, _Up>
  104. constexpr bool
  105. operator()(_Tp&& __t, _Up&& __u) const
  106. noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>()))
  107. {
  108. if constexpr (__detail::__less_builtin_ptr_cmp<_Tp, _Up>)
  109. {
  110. #ifdef __cpp_lib_is_constant_evaluated
  111. if (std::is_constant_evaluated())
  112. return __t < __u;
  113. #endif
  114. auto __x = reinterpret_cast<__UINTPTR_TYPE__>(
  115. static_cast<const volatile void*>(std::forward<_Tp>(__t)));
  116. auto __y = reinterpret_cast<__UINTPTR_TYPE__>(
  117. static_cast<const volatile void*>(std::forward<_Up>(__u)));
  118. return __x < __y;
  119. }
  120. else
  121. return std::forward<_Tp>(__t) < std::forward<_Up>(__u);
  122. }
  123. using is_transparent = __is_transparent;
  124. };
  125. /// ranges::greater function object type.
  126. struct greater
  127. {
  128. template<typename _Tp, typename _Up>
  129. requires totally_ordered_with<_Tp, _Up>
  130. || __detail::__less_builtin_ptr_cmp<_Up, _Tp>
  131. constexpr bool
  132. operator()(_Tp&& __t, _Up&& __u) const
  133. noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>()))
  134. { return less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); }
  135. using is_transparent = __is_transparent;
  136. };
  137. /// ranges::greater_equal function object type.
  138. struct greater_equal
  139. {
  140. template<typename _Tp, typename _Up>
  141. requires totally_ordered_with<_Tp, _Up>
  142. || __detail::__less_builtin_ptr_cmp<_Tp, _Up>
  143. constexpr bool
  144. operator()(_Tp&& __t, _Up&& __u) const
  145. noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>()))
  146. { return !less{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
  147. using is_transparent = __is_transparent;
  148. };
  149. /// ranges::less_equal function object type.
  150. struct less_equal
  151. {
  152. template<typename _Tp, typename _Up>
  153. requires totally_ordered_with<_Tp, _Up>
  154. || __detail::__less_builtin_ptr_cmp<_Up, _Tp>
  155. constexpr bool
  156. operator()(_Tp&& __t, _Up&& __u) const
  157. noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>()))
  158. { return !less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); }
  159. using is_transparent = __is_transparent;
  160. };
  161. } // namespace ranges
  162. #endif // library concepts
  163. _GLIBCXX_END_NAMESPACE_VERSION
  164. } // namespace std
  165. #endif // C++20
  166. #endif // _RANGE_CMP_H