1 // Concept-constrained comparison implementations -*- C++ -*-
3 // Copyright (C) 2019 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/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}
31 #define _RANGE_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
62 // BUILTIN-PTR-CMP(T, ==, U)
63 template<typename _Tp
, typename _Up
>
64 concept __eq_builtin_ptr_cmp
65 = convertible_to
<_Tp
, const volatile void*>
66 && convertible_to
<_Up
, const volatile void*>
67 && (! requires(_Tp
&& __t
, _Up
&& __u
)
68 { 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
)); });
73 // BUILTIN-PTR-CMP(T, <, U)
74 template<typename _Tp
, typename _Up
>
75 concept __less_builtin_ptr_cmp
76 = convertible_to
<_Tp
, const volatile void*>
77 && convertible_to
<_Up
, const volatile void*>
78 && (! requires(_Tp
&& __t
, _Up
&& __u
)
79 { operator<(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
80 && ! requires(_Tp
&& __t
, _Up
&& __u
)
81 { std::forward
<_Tp
>(__t
).operator<(std::forward
<_Up
>(__u
)); });
82 } // namespace __detail
84 // [range.cmp] Concept-constrained comparisons
86 /// ranges::equal_to function object type.
89 template<typename _Tp
, typename _Up
>
90 requires equality_comparable_with
<_Tp
, _Up
>
91 || __detail::__eq_builtin_ptr_cmp
<_Tp
, _Up
>
93 operator()(_Tp
&& __t
, _Up
&& __u
) const
94 noexcept(noexcept(std::declval
<_Tp
>() == std::declval
<_Up
>()))
95 { return std::forward
<_Tp
>(__t
) == std::forward
<_Up
>(__u
); }
97 using is_transparent
= __is_transparent
;
100 /// ranges::not_equal_to function object type.
103 template<typename _Tp
, typename _Up
>
104 requires equality_comparable_with
<_Tp
, _Up
>
105 || __detail::__eq_builtin_ptr_cmp
<_Tp
, _Up
>
107 operator()(_Tp
&& __t
, _Up
&& __u
) const
108 noexcept(noexcept(std::declval
<_Up
>() == std::declval
<_Tp
>()))
109 { return !equal_to
{}(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
111 using is_transparent
= __is_transparent
;
114 /// ranges::less function object type.
117 template<typename _Tp
, typename _Up
>
118 requires totally_ordered_with
<_Tp
, _Up
>
119 || __detail::__less_builtin_ptr_cmp
<_Tp
, _Up
>
121 operator()(_Tp
&& __t
, _Up
&& __u
) const
122 noexcept(noexcept(std::declval
<_Tp
>() < std::declval
<_Up
>()))
124 if constexpr (__detail::__less_builtin_ptr_cmp
<_Tp
, _Up
>)
126 #ifdef __cpp_lib_is_constant_evaluated
127 if (std::is_constant_evaluated())
130 auto __x
= reinterpret_cast<__UINTPTR_TYPE__
>(
131 static_cast<const volatile void*>(std::forward
<_Tp
>(__t
)));
132 auto __y
= reinterpret_cast<__UINTPTR_TYPE__
>(
133 static_cast<const volatile void*>(std::forward
<_Up
>(__u
)));
137 return std::forward
<_Tp
>(__t
) < std::forward
<_Up
>(__u
);
140 using is_transparent
= __is_transparent
;
143 /// ranges::greater function object type.
146 template<typename _Tp
, typename _Up
>
147 requires totally_ordered_with
<_Tp
, _Up
>
148 || __detail::__less_builtin_ptr_cmp
<_Up
, _Tp
>
150 operator()(_Tp
&& __t
, _Up
&& __u
) const
151 noexcept(noexcept(std::declval
<_Up
>() < std::declval
<_Tp
>()))
152 { return less
{}(std::forward
<_Up
>(__u
), std::forward
<_Tp
>(__t
)); }
154 using is_transparent
= __is_transparent
;
157 /// ranges::greater_equal function object type.
160 template<typename _Tp
, typename _Up
>
161 requires totally_ordered_with
<_Tp
, _Up
>
162 || __detail::__less_builtin_ptr_cmp
<_Tp
, _Up
>
164 operator()(_Tp
&& __t
, _Up
&& __u
) const
165 noexcept(noexcept(std::declval
<_Tp
>() < std::declval
<_Up
>()))
166 { return !less
{}(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
168 using is_transparent
= __is_transparent
;
171 /// ranges::less_equal function object type.
174 template<typename _Tp
, typename _Up
>
175 requires totally_ordered_with
<_Tp
, _Up
>
176 || __detail::__less_builtin_ptr_cmp
<_Up
, _Tp
>
178 operator()(_Tp
&& __t
, _Up
&& __u
) const
179 noexcept(noexcept(std::declval
<_Up
>() < std::declval
<_Tp
>()))
180 { return !less
{}(std::forward
<_Up
>(__u
), std::forward
<_Tp
>(__t
)); }
182 using is_transparent
= __is_transparent
;
185 } // namespace ranges
186 #endif // library concepts
187 _GLIBCXX_END_NAMESPACE_VERSION
190 #endif // _RANGE_CMP_H