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