ranges_cmp.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Concept-constrained comparison implementations -*- C++ -*-
  2. // Copyright (C) 2019-2022 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/ranges_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 _RANGES_CMP_H
  25. #define _RANGES_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. [[nodiscard]]
  40. constexpr _Tp&&
  41. operator()(_Tp&& __t) const noexcept
  42. { return std::forward<_Tp>(__t); }
  43. using is_transparent = __is_transparent;
  44. };
  45. #ifdef __cpp_lib_concepts
  46. // Define this here, included by all the headers that need to define it.
  47. #define __cpp_lib_ranges 202110L
  48. namespace ranges
  49. {
  50. namespace __detail
  51. {
  52. // BUILTIN-PTR-CMP(T, <, U)
  53. // This determines whether t < u results in a call to a built-in operator<
  54. // comparing pointers. It doesn't work for function pointers (PR 93628).
  55. template<typename _Tp, typename _Up>
  56. concept __less_builtin_ptr_cmp
  57. = requires (_Tp&& __t, _Up&& __u) { { __t < __u } -> same_as<bool>; }
  58. && convertible_to<_Tp, const volatile void*>
  59. && convertible_to<_Up, const volatile void*>
  60. && (! requires(_Tp&& __t, _Up&& __u)
  61. { operator<(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
  62. && ! requires(_Tp&& __t, _Up&& __u)
  63. { std::forward<_Tp>(__t).operator<(std::forward<_Up>(__u)); });
  64. } // namespace __detail
  65. // [range.cmp] Concept-constrained comparisons
  66. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  67. // 3530 BUILTIN-PTR-MEOW should not opt the type out of syntactic checks
  68. /// ranges::equal_to function object type.
  69. struct equal_to
  70. {
  71. template<typename _Tp, typename _Up>
  72. requires equality_comparable_with<_Tp, _Up>
  73. constexpr bool
  74. operator()(_Tp&& __t, _Up&& __u) const
  75. noexcept(noexcept(std::declval<_Tp>() == std::declval<_Up>()))
  76. { return std::forward<_Tp>(__t) == std::forward<_Up>(__u); }
  77. using is_transparent = __is_transparent;
  78. };
  79. /// ranges::not_equal_to function object type.
  80. struct not_equal_to
  81. {
  82. template<typename _Tp, typename _Up>
  83. requires equality_comparable_with<_Tp, _Up>
  84. constexpr bool
  85. operator()(_Tp&& __t, _Up&& __u) const
  86. noexcept(noexcept(std::declval<_Up>() == std::declval<_Tp>()))
  87. { return !equal_to{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
  88. using is_transparent = __is_transparent;
  89. };
  90. /// ranges::less function object type.
  91. struct less
  92. {
  93. template<typename _Tp, typename _Up>
  94. requires totally_ordered_with<_Tp, _Up>
  95. constexpr bool
  96. operator()(_Tp&& __t, _Up&& __u) const
  97. noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>()))
  98. {
  99. if constexpr (__detail::__less_builtin_ptr_cmp<_Tp, _Up>)
  100. {
  101. if (std::__is_constant_evaluated())
  102. return __t < __u;
  103. auto __x = reinterpret_cast<__UINTPTR_TYPE__>(
  104. static_cast<const volatile void*>(std::forward<_Tp>(__t)));
  105. auto __y = reinterpret_cast<__UINTPTR_TYPE__>(
  106. static_cast<const volatile void*>(std::forward<_Up>(__u)));
  107. return __x < __y;
  108. }
  109. else
  110. return std::forward<_Tp>(__t) < std::forward<_Up>(__u);
  111. }
  112. using is_transparent = __is_transparent;
  113. };
  114. /// ranges::greater function object type.
  115. struct greater
  116. {
  117. template<typename _Tp, typename _Up>
  118. requires totally_ordered_with<_Tp, _Up>
  119. constexpr bool
  120. operator()(_Tp&& __t, _Up&& __u) const
  121. noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>()))
  122. { return less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); }
  123. using is_transparent = __is_transparent;
  124. };
  125. /// ranges::greater_equal function object type.
  126. struct greater_equal
  127. {
  128. template<typename _Tp, typename _Up>
  129. requires totally_ordered_with<_Tp, _Up>
  130. constexpr bool
  131. operator()(_Tp&& __t, _Up&& __u) const
  132. noexcept(noexcept(std::declval<_Tp>() < std::declval<_Up>()))
  133. { return !less{}(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
  134. using is_transparent = __is_transparent;
  135. };
  136. /// ranges::less_equal function object type.
  137. struct less_equal
  138. {
  139. template<typename _Tp, typename _Up>
  140. requires totally_ordered_with<_Tp, _Up>
  141. constexpr bool
  142. operator()(_Tp&& __t, _Up&& __u) const
  143. noexcept(noexcept(std::declval<_Up>() < std::declval<_Tp>()))
  144. { return !less{}(std::forward<_Up>(__u), std::forward<_Tp>(__t)); }
  145. using is_transparent = __is_transparent;
  146. };
  147. } // namespace ranges
  148. #endif // library concepts
  149. _GLIBCXX_END_NAMESPACE_VERSION
  150. } // namespace std
  151. #endif // C++20
  152. #endif // _RANGES_CMP_H