1 // Concept-constrained comparison implementations -*- C++ -*-
3 // Copyright (C) 2019-2024 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
>
52 operator()(_Tp
&& __t
) const noexcept
53 { return std::forward
<_Tp
>(__t
); }
55 using is_transparent
= __is_transparent
;
58 #ifdef __glibcxx_ranges // C++ >= 20
63 // BUILTIN-PTR-CMP(T, <, U)
64 // This determines whether t < u results in a call to a built-in operator<
65 // comparing pointers. It doesn't work for function pointers (PR 93628).
66 template<typename _Tp
, typename _Up
>
67 concept __less_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
)); }
73 && ! requires(_Tp
&& __t
, _Up
&& __u
)
74 { std::forward
<_Tp
>(__t
).operator<(std::forward
<_Up
>(__u
)); });
75 } // namespace __detail
77 // [range.cmp] Concept-constrained comparisons
79 // _GLIBCXX_RESOLVE_LIB_DEFECTS
80 // 3530 BUILTIN-PTR-MEOW should not opt the type out of syntactic checks
82 /// ranges::equal_to function object type.
85 template<typename _Tp
, typename _Up
>
86 requires equality_comparable_with
<_Tp
, _Up
>
88 operator()(_Tp
&& __t
, _Up
&& __u
) const
89 noexcept(noexcept(std::declval
<_Tp
>() == std::declval
<_Up
>()))
90 { return std::forward
<_Tp
>(__t
) == std::forward
<_Up
>(__u
); }
92 using is_transparent
= __is_transparent
;
95 /// ranges::not_equal_to function object type.
98 template<typename _Tp
, typename _Up
>
99 requires equality_comparable_with
<_Tp
, _Up
>
101 operator()(_Tp
&& __t
, _Up
&& __u
) const
102 noexcept(noexcept(std::declval
<_Up
>() == std::declval
<_Tp
>()))
103 { return !equal_to
{}(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
105 using is_transparent
= __is_transparent
;
108 /// ranges::less function object type.
111 template<typename _Tp
, typename _Up
>
112 requires totally_ordered_with
<_Tp
, _Up
>
114 operator()(_Tp
&& __t
, _Up
&& __u
) const
115 noexcept(noexcept(std::declval
<_Tp
>() < std::declval
<_Up
>()))
117 if constexpr (__detail::__less_builtin_ptr_cmp
<_Tp
, _Up
>)
119 if (std::__is_constant_evaluated())
122 auto __x
= reinterpret_cast<__UINTPTR_TYPE__
>(
123 static_cast<const volatile void*>(std::forward
<_Tp
>(__t
)));
124 auto __y
= reinterpret_cast<__UINTPTR_TYPE__
>(
125 static_cast<const volatile void*>(std::forward
<_Up
>(__u
)));
129 return std::forward
<_Tp
>(__t
) < std::forward
<_Up
>(__u
);
132 using is_transparent
= __is_transparent
;
135 /// ranges::greater function object type.
138 template<typename _Tp
, typename _Up
>
139 requires totally_ordered_with
<_Tp
, _Up
>
141 operator()(_Tp
&& __t
, _Up
&& __u
) const
142 noexcept(noexcept(std::declval
<_Up
>() < std::declval
<_Tp
>()))
143 { return less
{}(std::forward
<_Up
>(__u
), std::forward
<_Tp
>(__t
)); }
145 using is_transparent
= __is_transparent
;
148 /// ranges::greater_equal function object type.
151 template<typename _Tp
, typename _Up
>
152 requires totally_ordered_with
<_Tp
, _Up
>
154 operator()(_Tp
&& __t
, _Up
&& __u
) const
155 noexcept(noexcept(std::declval
<_Tp
>() < std::declval
<_Up
>()))
156 { return !less
{}(std::forward
<_Tp
>(__t
), std::forward
<_Up
>(__u
)); }
158 using is_transparent
= __is_transparent
;
161 /// ranges::less_equal function object type.
164 template<typename _Tp
, typename _Up
>
165 requires totally_ordered_with
<_Tp
, _Up
>
167 operator()(_Tp
&& __t
, _Up
&& __u
) const
168 noexcept(noexcept(std::declval
<_Up
>() < std::declval
<_Tp
>()))
169 { return !less
{}(std::forward
<_Up
>(__u
), std::forward
<_Tp
>(__t
)); }
171 using is_transparent
= __is_transparent
;
174 } // namespace ranges
175 #endif // __glibcxx_ranges
176 _GLIBCXX_END_NAMESPACE_VERSION
179 #endif // _RANGES_CMP_H