xref: /freebsd-src/contrib/llvm-project/libcxx/include/__functional/operations.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1fe6060f1SDimitry Andric // -*- C++ -*-
2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
3fe6060f1SDimitry Andric //
4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7fe6060f1SDimitry Andric //
8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
9fe6060f1SDimitry Andric 
10fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_OPERATIONS_H
11fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_OPERATIONS_H
12fe6060f1SDimitry Andric 
13fe6060f1SDimitry Andric #include <__config>
14fe6060f1SDimitry Andric #include <__functional/binary_function.h>
15fe6060f1SDimitry Andric #include <__functional/unary_function.h>
16*0fca6ea1SDimitry Andric #include <__type_traits/desugars_to.h>
17fe6060f1SDimitry Andric #include <__utility/forward.h>
18fe6060f1SDimitry Andric 
19fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20fe6060f1SDimitry Andric #  pragma GCC system_header
21fe6060f1SDimitry Andric #endif
22fe6060f1SDimitry Andric 
23fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
24fe6060f1SDimitry Andric 
25fe6060f1SDimitry Andric // Arithmetic operations
26fe6060f1SDimitry Andric 
2706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
28fe6060f1SDimitry Andric template <class _Tp = void>
29fe6060f1SDimitry Andric #else
30fe6060f1SDimitry Andric template <class _Tp>
31fe6060f1SDimitry Andric #endif
32cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS plus : __binary_function<_Tp, _Tp, _Tp> {
33fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
34cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
35cb14a3feSDimitry Andric     return __x + __y;
36cb14a3feSDimitry Andric   }
37fe6060f1SDimitry Andric };
38bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
39fe6060f1SDimitry Andric 
405f757f3fSDimitry Andric // The non-transparent std::plus specialization is only equivalent to a raw plus
415f757f3fSDimitry Andric // operator when we don't perform an implicit conversion when calling it.
4206c3fb27SDimitry Andric template <class _Tp>
43*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__plus_tag, plus<_Tp>, _Tp, _Tp> = true;
4406c3fb27SDimitry Andric 
4506c3fb27SDimitry Andric template <class _Tp, class _Up>
46*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__plus_tag, plus<void>, _Tp, _Up> = true;
4706c3fb27SDimitry Andric 
4806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
49fe6060f1SDimitry Andric template <>
50cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS plus<void> {
51fe6060f1SDimitry Andric   template <class _T1, class _T2>
52cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
53*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) //
54cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) {
55cb14a3feSDimitry Andric     return std::forward<_T1>(__t) + std::forward<_T2>(__u);
56cb14a3feSDimitry Andric   }
57fe6060f1SDimitry Andric   typedef void is_transparent;
58fe6060f1SDimitry Andric };
59fe6060f1SDimitry Andric #endif
60fe6060f1SDimitry Andric 
6106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
62fe6060f1SDimitry Andric template <class _Tp = void>
63fe6060f1SDimitry Andric #else
64fe6060f1SDimitry Andric template <class _Tp>
65fe6060f1SDimitry Andric #endif
66cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS minus : __binary_function<_Tp, _Tp, _Tp> {
67fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
68cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
69cb14a3feSDimitry Andric     return __x - __y;
70cb14a3feSDimitry Andric   }
71fe6060f1SDimitry Andric };
72bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus);
73fe6060f1SDimitry Andric 
7406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
75fe6060f1SDimitry Andric template <>
76cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS minus<void> {
77fe6060f1SDimitry Andric   template <class _T1, class _T2>
78cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
79*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) //
80cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) {
81cb14a3feSDimitry Andric     return std::forward<_T1>(__t) - std::forward<_T2>(__u);
82cb14a3feSDimitry Andric   }
83fe6060f1SDimitry Andric   typedef void is_transparent;
84fe6060f1SDimitry Andric };
85fe6060f1SDimitry Andric #endif
86fe6060f1SDimitry Andric 
8706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
88fe6060f1SDimitry Andric template <class _Tp = void>
89fe6060f1SDimitry Andric #else
90fe6060f1SDimitry Andric template <class _Tp>
91fe6060f1SDimitry Andric #endif
92cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS multiplies : __binary_function<_Tp, _Tp, _Tp> {
93fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
94cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
95cb14a3feSDimitry Andric     return __x * __y;
96cb14a3feSDimitry Andric   }
97fe6060f1SDimitry Andric };
98bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies);
99fe6060f1SDimitry Andric 
10006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
101fe6060f1SDimitry Andric template <>
102cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS multiplies<void> {
103fe6060f1SDimitry Andric   template <class _T1, class _T2>
104cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
105*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) //
106cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) {
107cb14a3feSDimitry Andric     return std::forward<_T1>(__t) * std::forward<_T2>(__u);
108cb14a3feSDimitry Andric   }
109fe6060f1SDimitry Andric   typedef void is_transparent;
110fe6060f1SDimitry Andric };
111fe6060f1SDimitry Andric #endif
112fe6060f1SDimitry Andric 
11306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
114fe6060f1SDimitry Andric template <class _Tp = void>
115fe6060f1SDimitry Andric #else
116fe6060f1SDimitry Andric template <class _Tp>
117fe6060f1SDimitry Andric #endif
118cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS divides : __binary_function<_Tp, _Tp, _Tp> {
119fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
120cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
121cb14a3feSDimitry Andric     return __x / __y;
122cb14a3feSDimitry Andric   }
123fe6060f1SDimitry Andric };
124bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides);
125fe6060f1SDimitry Andric 
12606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
127fe6060f1SDimitry Andric template <>
128cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS divides<void> {
129fe6060f1SDimitry Andric   template <class _T1, class _T2>
130cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
131*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) //
132cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) {
133cb14a3feSDimitry Andric     return std::forward<_T1>(__t) / std::forward<_T2>(__u);
134cb14a3feSDimitry Andric   }
135fe6060f1SDimitry Andric   typedef void is_transparent;
136fe6060f1SDimitry Andric };
137fe6060f1SDimitry Andric #endif
138fe6060f1SDimitry Andric 
13906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
140fe6060f1SDimitry Andric template <class _Tp = void>
141fe6060f1SDimitry Andric #else
142fe6060f1SDimitry Andric template <class _Tp>
143fe6060f1SDimitry Andric #endif
144cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS modulus : __binary_function<_Tp, _Tp, _Tp> {
145fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
146cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
147cb14a3feSDimitry Andric     return __x % __y;
148cb14a3feSDimitry Andric   }
149fe6060f1SDimitry Andric };
150bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus);
151fe6060f1SDimitry Andric 
15206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
153fe6060f1SDimitry Andric template <>
154cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS modulus<void> {
155fe6060f1SDimitry Andric   template <class _T1, class _T2>
156cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
157*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) //
158cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) {
159cb14a3feSDimitry Andric     return std::forward<_T1>(__t) % std::forward<_T2>(__u);
160cb14a3feSDimitry Andric   }
161fe6060f1SDimitry Andric   typedef void is_transparent;
162fe6060f1SDimitry Andric };
163fe6060f1SDimitry Andric #endif
164fe6060f1SDimitry Andric 
16506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
166fe6060f1SDimitry Andric template <class _Tp = void>
167fe6060f1SDimitry Andric #else
168fe6060f1SDimitry Andric template <class _Tp>
169fe6060f1SDimitry Andric #endif
170cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS negate : __unary_function<_Tp, _Tp> {
171fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
172cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; }
173fe6060f1SDimitry Andric };
174bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
175fe6060f1SDimitry Andric 
17606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
177fe6060f1SDimitry Andric template <>
178cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS negate<void> {
179fe6060f1SDimitry Andric   template <class _Tp>
180cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
181*0fca6ea1SDimitry Andric       noexcept(noexcept(-std::forward<_Tp>(__x))) //
182*0fca6ea1SDimitry Andric       -> decltype(-std::forward<_Tp>(__x)) {
183cb14a3feSDimitry Andric     return -std::forward<_Tp>(__x);
184cb14a3feSDimitry Andric   }
185fe6060f1SDimitry Andric   typedef void is_transparent;
186fe6060f1SDimitry Andric };
187fe6060f1SDimitry Andric #endif
188fe6060f1SDimitry Andric 
189fe6060f1SDimitry Andric // Bitwise operations
190fe6060f1SDimitry Andric 
19106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
192fe6060f1SDimitry Andric template <class _Tp = void>
193fe6060f1SDimitry Andric #else
194fe6060f1SDimitry Andric template <class _Tp>
195fe6060f1SDimitry Andric #endif
196cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_and : __binary_function<_Tp, _Tp, _Tp> {
197fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
198cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
199cb14a3feSDimitry Andric     return __x & __y;
200cb14a3feSDimitry Andric   }
201fe6060f1SDimitry Andric };
202bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and);
203fe6060f1SDimitry Andric 
20406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
205fe6060f1SDimitry Andric template <>
206cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_and<void> {
207fe6060f1SDimitry Andric   template <class _T1, class _T2>
208cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
209*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) &
210*0fca6ea1SDimitry Andric                         std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) {
211cb14a3feSDimitry Andric     return std::forward<_T1>(__t) & std::forward<_T2>(__u);
212cb14a3feSDimitry Andric   }
213fe6060f1SDimitry Andric   typedef void is_transparent;
214fe6060f1SDimitry Andric };
215fe6060f1SDimitry Andric #endif
216fe6060f1SDimitry Andric 
21706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
218fe6060f1SDimitry Andric template <class _Tp = void>
219cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_not : __unary_function<_Tp, _Tp> {
220cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return ~__x; }
221fe6060f1SDimitry Andric };
222bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not);
223fe6060f1SDimitry Andric 
224fe6060f1SDimitry Andric template <>
225cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_not<void> {
226fe6060f1SDimitry Andric   template <class _Tp>
227cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
228*0fca6ea1SDimitry Andric       noexcept(noexcept(~std::forward<_Tp>(__x))) //
229*0fca6ea1SDimitry Andric       -> decltype(~std::forward<_Tp>(__x)) {
230cb14a3feSDimitry Andric     return ~std::forward<_Tp>(__x);
231cb14a3feSDimitry Andric   }
232fe6060f1SDimitry Andric   typedef void is_transparent;
233fe6060f1SDimitry Andric };
234fe6060f1SDimitry Andric #endif
235fe6060f1SDimitry Andric 
23606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
237fe6060f1SDimitry Andric template <class _Tp = void>
238fe6060f1SDimitry Andric #else
239fe6060f1SDimitry Andric template <class _Tp>
240fe6060f1SDimitry Andric #endif
241cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_or : __binary_function<_Tp, _Tp, _Tp> {
242fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
243cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
244cb14a3feSDimitry Andric     return __x | __y;
245cb14a3feSDimitry Andric   }
246fe6060f1SDimitry Andric };
247bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or);
248fe6060f1SDimitry Andric 
24906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
250fe6060f1SDimitry Andric template <>
251cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_or<void> {
252fe6060f1SDimitry Andric   template <class _T1, class _T2>
253cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
254*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) //
255cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) {
256cb14a3feSDimitry Andric     return std::forward<_T1>(__t) | std::forward<_T2>(__u);
257cb14a3feSDimitry Andric   }
258fe6060f1SDimitry Andric   typedef void is_transparent;
259fe6060f1SDimitry Andric };
260fe6060f1SDimitry Andric #endif
261fe6060f1SDimitry Andric 
26206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
263fe6060f1SDimitry Andric template <class _Tp = void>
264fe6060f1SDimitry Andric #else
265fe6060f1SDimitry Andric template <class _Tp>
266fe6060f1SDimitry Andric #endif
267cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_xor : __binary_function<_Tp, _Tp, _Tp> {
268fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
269cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
270cb14a3feSDimitry Andric     return __x ^ __y;
271cb14a3feSDimitry Andric   }
272fe6060f1SDimitry Andric };
273bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor);
274fe6060f1SDimitry Andric 
27506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
276fe6060f1SDimitry Andric template <>
277cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_xor<void> {
278fe6060f1SDimitry Andric   template <class _T1, class _T2>
279cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
280*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) //
281cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) {
282cb14a3feSDimitry Andric     return std::forward<_T1>(__t) ^ std::forward<_T2>(__u);
283cb14a3feSDimitry Andric   }
284fe6060f1SDimitry Andric   typedef void is_transparent;
285fe6060f1SDimitry Andric };
286fe6060f1SDimitry Andric #endif
287fe6060f1SDimitry Andric 
288fe6060f1SDimitry Andric // Comparison operations
289fe6060f1SDimitry Andric 
29006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
291fe6060f1SDimitry Andric template <class _Tp = void>
292fe6060f1SDimitry Andric #else
293fe6060f1SDimitry Andric template <class _Tp>
294fe6060f1SDimitry Andric #endif
295cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS equal_to : __binary_function<_Tp, _Tp, bool> {
296fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
297cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
298cb14a3feSDimitry Andric     return __x == __y;
299cb14a3feSDimitry Andric   }
300fe6060f1SDimitry Andric };
301bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to);
302fe6060f1SDimitry Andric 
30306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
304fe6060f1SDimitry Andric template <>
305cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS equal_to<void> {
306fe6060f1SDimitry Andric   template <class _T1, class _T2>
307cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
308*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) //
309cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) {
310cb14a3feSDimitry Andric     return std::forward<_T1>(__t) == std::forward<_T2>(__u);
311cb14a3feSDimitry Andric   }
312fe6060f1SDimitry Andric   typedef void is_transparent;
313fe6060f1SDimitry Andric };
314fe6060f1SDimitry Andric #endif
315fe6060f1SDimitry Andric 
3165f757f3fSDimitry Andric // The non-transparent std::equal_to specialization is only equivalent to a raw equality
3175f757f3fSDimitry Andric // comparison when we don't perform an implicit conversion when calling it.
31806c3fb27SDimitry Andric template <class _Tp>
319*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__equal_tag, equal_to<_Tp>, _Tp, _Tp> = true;
32006c3fb27SDimitry Andric 
3215f757f3fSDimitry Andric // In the transparent case, we do not enforce that
3225f757f3fSDimitry Andric template <class _Tp, class _Up>
323*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__equal_tag, equal_to<void>, _Tp, _Up> = true;
32406c3fb27SDimitry Andric 
32506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
326fe6060f1SDimitry Andric template <class _Tp = void>
327fe6060f1SDimitry Andric #else
328fe6060f1SDimitry Andric template <class _Tp>
329fe6060f1SDimitry Andric #endif
330cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS not_equal_to : __binary_function<_Tp, _Tp, bool> {
331fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
332cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
333cb14a3feSDimitry Andric     return __x != __y;
334cb14a3feSDimitry Andric   }
335fe6060f1SDimitry Andric };
336bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to);
337fe6060f1SDimitry Andric 
33806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
339fe6060f1SDimitry Andric template <>
340cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS not_equal_to<void> {
341fe6060f1SDimitry Andric   template <class _T1, class _T2>
342cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
343*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) //
344cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) {
345cb14a3feSDimitry Andric     return std::forward<_T1>(__t) != std::forward<_T2>(__u);
346cb14a3feSDimitry Andric   }
347fe6060f1SDimitry Andric   typedef void is_transparent;
348fe6060f1SDimitry Andric };
349fe6060f1SDimitry Andric #endif
350fe6060f1SDimitry Andric 
35106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
352fe6060f1SDimitry Andric template <class _Tp = void>
353fe6060f1SDimitry Andric #else
354fe6060f1SDimitry Andric template <class _Tp>
355fe6060f1SDimitry Andric #endif
356cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less : __binary_function<_Tp, _Tp, bool> {
357fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
358cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
359cb14a3feSDimitry Andric     return __x < __y;
360cb14a3feSDimitry Andric   }
361fe6060f1SDimitry Andric };
362bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less);
363fe6060f1SDimitry Andric 
364*0fca6ea1SDimitry Andric template <class _Tp>
365*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__less_tag, less<_Tp>, _Tp, _Tp> = true;
366*0fca6ea1SDimitry Andric 
36706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
368fe6060f1SDimitry Andric template <>
369cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less<void> {
370fe6060f1SDimitry Andric   template <class _T1, class _T2>
371cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
372*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) //
373cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) {
374cb14a3feSDimitry Andric     return std::forward<_T1>(__t) < std::forward<_T2>(__u);
375cb14a3feSDimitry Andric   }
376fe6060f1SDimitry Andric   typedef void is_transparent;
377fe6060f1SDimitry Andric };
378*0fca6ea1SDimitry Andric 
379*0fca6ea1SDimitry Andric template <class _Tp>
380*0fca6ea1SDimitry Andric inline const bool __desugars_to_v<__less_tag, less<>, _Tp, _Tp> = true;
381fe6060f1SDimitry Andric #endif
382fe6060f1SDimitry Andric 
38306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
384fe6060f1SDimitry Andric template <class _Tp = void>
385fe6060f1SDimitry Andric #else
386fe6060f1SDimitry Andric template <class _Tp>
387fe6060f1SDimitry Andric #endif
388cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less_equal : __binary_function<_Tp, _Tp, bool> {
389fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
390cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
391cb14a3feSDimitry Andric     return __x <= __y;
392cb14a3feSDimitry Andric   }
393fe6060f1SDimitry Andric };
394bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal);
395fe6060f1SDimitry Andric 
39606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
397fe6060f1SDimitry Andric template <>
398cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less_equal<void> {
399fe6060f1SDimitry Andric   template <class _T1, class _T2>
400cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
401*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) //
402cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) {
403cb14a3feSDimitry Andric     return std::forward<_T1>(__t) <= std::forward<_T2>(__u);
404cb14a3feSDimitry Andric   }
405fe6060f1SDimitry Andric   typedef void is_transparent;
406fe6060f1SDimitry Andric };
407fe6060f1SDimitry Andric #endif
408fe6060f1SDimitry Andric 
40906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
410fe6060f1SDimitry Andric template <class _Tp = void>
411fe6060f1SDimitry Andric #else
412fe6060f1SDimitry Andric template <class _Tp>
413fe6060f1SDimitry Andric #endif
414cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater_equal : __binary_function<_Tp, _Tp, bool> {
415fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
416cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
417cb14a3feSDimitry Andric     return __x >= __y;
418cb14a3feSDimitry Andric   }
419fe6060f1SDimitry Andric };
420bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal);
421fe6060f1SDimitry Andric 
42206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
423fe6060f1SDimitry Andric template <>
424cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater_equal<void> {
425fe6060f1SDimitry Andric   template <class _T1, class _T2>
426cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
427*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) >=
428*0fca6ea1SDimitry Andric                         std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) {
429cb14a3feSDimitry Andric     return std::forward<_T1>(__t) >= std::forward<_T2>(__u);
430cb14a3feSDimitry Andric   }
431fe6060f1SDimitry Andric   typedef void is_transparent;
432fe6060f1SDimitry Andric };
433fe6060f1SDimitry Andric #endif
434fe6060f1SDimitry Andric 
43506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
436fe6060f1SDimitry Andric template <class _Tp = void>
437fe6060f1SDimitry Andric #else
438fe6060f1SDimitry Andric template <class _Tp>
439fe6060f1SDimitry Andric #endif
440cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater : __binary_function<_Tp, _Tp, bool> {
441fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
442cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
443cb14a3feSDimitry Andric     return __x > __y;
444cb14a3feSDimitry Andric   }
445fe6060f1SDimitry Andric };
446bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater);
447fe6060f1SDimitry Andric 
44806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
449fe6060f1SDimitry Andric template <>
450cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater<void> {
451fe6060f1SDimitry Andric   template <class _T1, class _T2>
452cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
453*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) //
454cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) {
455cb14a3feSDimitry Andric     return std::forward<_T1>(__t) > std::forward<_T2>(__u);
456cb14a3feSDimitry Andric   }
457fe6060f1SDimitry Andric   typedef void is_transparent;
458fe6060f1SDimitry Andric };
459fe6060f1SDimitry Andric #endif
460fe6060f1SDimitry Andric 
461fe6060f1SDimitry Andric // Logical operations
462fe6060f1SDimitry Andric 
46306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
464fe6060f1SDimitry Andric template <class _Tp = void>
465fe6060f1SDimitry Andric #else
466fe6060f1SDimitry Andric template <class _Tp>
467fe6060f1SDimitry Andric #endif
468cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_and : __binary_function<_Tp, _Tp, bool> {
469fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
470cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
471cb14a3feSDimitry Andric     return __x && __y;
472cb14a3feSDimitry Andric   }
473fe6060f1SDimitry Andric };
474bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and);
475fe6060f1SDimitry Andric 
47606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
477fe6060f1SDimitry Andric template <>
478cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_and<void> {
479fe6060f1SDimitry Andric   template <class _T1, class _T2>
480cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
481*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) //
482cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) {
483cb14a3feSDimitry Andric     return std::forward<_T1>(__t) && std::forward<_T2>(__u);
484cb14a3feSDimitry Andric   }
485fe6060f1SDimitry Andric   typedef void is_transparent;
486fe6060f1SDimitry Andric };
487fe6060f1SDimitry Andric #endif
488fe6060f1SDimitry Andric 
48906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
490fe6060f1SDimitry Andric template <class _Tp = void>
491fe6060f1SDimitry Andric #else
492fe6060f1SDimitry Andric template <class _Tp>
493fe6060f1SDimitry Andric #endif
494cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_not : __unary_function<_Tp, bool> {
495fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
496cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; }
497fe6060f1SDimitry Andric };
498bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
499fe6060f1SDimitry Andric 
50006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
501fe6060f1SDimitry Andric template <>
502cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_not<void> {
503fe6060f1SDimitry Andric   template <class _Tp>
504cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
505*0fca6ea1SDimitry Andric       noexcept(noexcept(!std::forward<_Tp>(__x))) //
506*0fca6ea1SDimitry Andric       -> decltype(!std::forward<_Tp>(__x)) {
507cb14a3feSDimitry Andric     return !std::forward<_Tp>(__x);
508cb14a3feSDimitry Andric   }
509fe6060f1SDimitry Andric   typedef void is_transparent;
510fe6060f1SDimitry Andric };
511fe6060f1SDimitry Andric #endif
512fe6060f1SDimitry Andric 
51306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
514fe6060f1SDimitry Andric template <class _Tp = void>
515fe6060f1SDimitry Andric #else
516fe6060f1SDimitry Andric template <class _Tp>
517fe6060f1SDimitry Andric #endif
518cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_or : __binary_function<_Tp, _Tp, bool> {
519fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
520cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
521cb14a3feSDimitry Andric     return __x || __y;
522cb14a3feSDimitry Andric   }
523fe6060f1SDimitry Andric };
524bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or);
525fe6060f1SDimitry Andric 
52606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
527fe6060f1SDimitry Andric template <>
528cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_or<void> {
529fe6060f1SDimitry Andric   template <class _T1, class _T2>
530cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
531*0fca6ea1SDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) //
532cb14a3feSDimitry Andric       -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) {
533cb14a3feSDimitry Andric     return std::forward<_T1>(__t) || std::forward<_T2>(__u);
534cb14a3feSDimitry Andric   }
535fe6060f1SDimitry Andric   typedef void is_transparent;
536fe6060f1SDimitry Andric };
537fe6060f1SDimitry Andric #endif
538fe6060f1SDimitry Andric 
539fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
540fe6060f1SDimitry Andric 
541fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H
542