1 // Concept-constrained comparison implementations -*- C++ -*-
3 // Copyright (C) 2019-2021 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file bits/ranges_cmp.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{functional}
31 #define _RANGES_CMP_H 1
33 #if __cplusplus > 201703L
34 # include <bits/move.h>
37 namespace std
_GLIBCXX_VISIBILITY(default)
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
41 struct __is_transparent
; // not defined
43 // Define std::identity here so that <iterator> and <ranges>
44 // don't need to include <bits/stl_function.h> to get it.
46 /// [func.identity] The identity function.
49 template<typename _Tp
>
51 operator()(_Tp
&& __t
) const noexcept
52 { return std::forward
<_Tp
>(__t
); }
54 using is_transparent
= __is_transparent
;
57 #ifdef __cpp_lib_concepts
58 // Define this here, included by all the headers that need to define it.
59 #define __cpp_lib_ranges 201911L
65 // BUILTIN-PTR-CMP(T, ==, U)
66 template<typename _Tp
, typename _Up
>
67 concept __eq_builtin_ptr_cmp
68 = requires (_Tp
&& __t
, _Up
&& __u
) { { __t
== __u
} -> same_as
<bool>; }
69 && convertible_to
<_Tp
, const volatile void*>
70 && convertible_to
<_Up
, const volatile void*>
71 && (! requires(_Tp
&& __t
, _Up
&& __u
)
72 { operator==(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
74 ! requires(_Tp
&& __t
, _Up
&& __u
)
75 { std::forward
<_Tp
>(__t
).operator==(std::forward
<_Up
>(__u
)); });
77 // BUILTIN-PTR-CMP(T, <, U)
78 template<typename _Tp
, typename _Up
>
79 concept __less_builtin_ptr_cmp
80 = requires (_Tp
&& __t
, _Up
&& __u
) { { __t
< __u
} -> same_as
<bool>; }
81 && convertible_to
<_Tp
, const volatile void*>
82 && convertible_to
<_Up
, const volatile void*>
83 && (! requires(_Tp
&& __t
, _Up
&& __u
)
84 { operator<(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
85 && ! requires(_Tp
&& __t
, _Up
&& __u
)
86 { std::forward
<_Tp
>(__t
).operator<(std::forward
<_Up
>(__u
)); });
87 } // namespace __detail
89 // [range.cmp] Concept-constrained comparisons
91 /// ranges::equal_to function object type.
94 template<typename _Tp
, typename _Up
>
95 requires equality_comparable_with
<_Tp
, _Up
>
96 || __detail::__eq_builtin_ptr_cmp
<_Tp
, _Up
>
98 operator()(_Tp
&& __t
, _Up
&& __u
) const
99 noexcept(noexcept(std::declval
<_Tp
>() == std::declval
<_Up
>()))
100 { return std::forward
<_Tp
>(__t
) == std::forward
<_Up
>(__u
); }
102 using is_transparent
= __is_transparent
;
105 /// ranges::not_equal_to function object type.
108 template<typename _Tp
, typename _Up
>
109 requires equality_comparable_with
<_Tp
, _Up
>
110 || __detail::__eq_builtin_ptr_cmp
<_Tp
, _Up
>
112 operator()(_Tp
&& __t
, _Up
&& __u
) const
113 noexcept(noexcept(std::declval
<_Up
>() == std::declval
<_Tp
>()))
114 { return !equal_to
{}(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
116 using is_transparent
= __is_transparent
;
119 /// ranges::less function object type.
122 template<typename _Tp
, typename _Up
>
123 requires totally_ordered_with
<_Tp
, _Up
>
124 || __detail::__less_builtin_ptr_cmp
<_Tp
, _Up
>
126 operator()(_Tp
&& __t
, _Up
&& __u
) const
127 noexcept(noexcept(std::declval
<_Tp
>() < std::declval
<_Up
>()))
129 if constexpr (__detail::__less_builtin_ptr_cmp
<_Tp
, _Up
>)
131 #ifdef __cpp_lib_is_constant_evaluated
132 if (std::is_constant_evaluated())
135 auto __x
= reinterpret_cast<__UINTPTR_TYPE__
>(
136 static_cast<const volatile void*>(std::forward
<_Tp
>(__t
)));
137 auto __y
= reinterpret_cast<__UINTPTR_TYPE__
>(
138 static_cast<const volatile void*>(std::forward
<_Up
>(__u
)));
142 return std::forward
<_Tp
>(__t
) < std::forward
<_Up
>(__u
);
145 using is_transparent
= __is_transparent
;
148 /// ranges::greater function object type.
151 template<typename _Tp
, typename _Up
>
152 requires totally_ordered_with
<_Tp
, _Up
>
153 || __detail::__less_builtin_ptr_cmp
<_Up
, _Tp
>
155 operator()(_Tp
&& __t
, _Up
&& __u
) const
156 noexcept(noexcept(std::declval
<_Up
>() < std::declval
<_Tp
>()))
157 { return less
{}(std::forward
<_Up
>(__u
), std::forward
<_Tp
>(__t
)); }
159 using is_transparent
= __is_transparent
;
162 /// ranges::greater_equal function object type.
165 template<typename _Tp
, typename _Up
>
166 requires totally_ordered_with
<_Tp
, _Up
>
167 || __detail::__less_builtin_ptr_cmp
<_Tp
, _Up
>
169 operator()(_Tp
&& __t
, _Up
&& __u
) const
170 noexcept(noexcept(std::declval
<_Tp
>() < std::declval
<_Up
>()))
171 { return !less
{}(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
173 using is_transparent
= __is_transparent
;
176 /// ranges::less_equal function object type.
179 template<typename _Tp
, typename _Up
>
180 requires totally_ordered_with
<_Tp
, _Up
>
181 || __detail::__less_builtin_ptr_cmp
<_Up
, _Tp
>
183 operator()(_Tp
&& __t
, _Up
&& __u
) const
184 noexcept(noexcept(std::declval
<_Up
>() < std::declval
<_Tp
>()))
185 { return !less
{}(std::forward
<_Up
>(__u
), std::forward
<_Tp
>(__t
)); }
187 using is_transparent
= __is_transparent
;
190 } // namespace ranges
191 #endif // library concepts
192 _GLIBCXX_END_NAMESPACE_VERSION
195 #endif // _RANGES_CMP_H