xref: /freebsd/contrib/llvm-project/libcxx/include/__functional/operations.h (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
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>
1606c3fb27SDimitry Andric #include <__type_traits/integral_constant.h>
1706c3fb27SDimitry Andric #include <__type_traits/operation_traits.h>
18fe6060f1SDimitry Andric #include <__utility/forward.h>
19fe6060f1SDimitry Andric 
20fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21fe6060f1SDimitry Andric #  pragma GCC system_header
22fe6060f1SDimitry Andric #endif
23fe6060f1SDimitry Andric 
24fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
25fe6060f1SDimitry Andric 
26fe6060f1SDimitry Andric // Arithmetic operations
27fe6060f1SDimitry Andric 
2806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
29fe6060f1SDimitry Andric template <class _Tp = void>
30fe6060f1SDimitry Andric #else
31fe6060f1SDimitry Andric template <class _Tp>
32fe6060f1SDimitry Andric #endif
33*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS plus : __binary_function<_Tp, _Tp, _Tp> {
34fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
35*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
36*cb14a3feSDimitry Andric     return __x + __y;
37*cb14a3feSDimitry Andric   }
38fe6060f1SDimitry Andric };
39bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
40fe6060f1SDimitry Andric 
415f757f3fSDimitry Andric // The non-transparent std::plus specialization is only equivalent to a raw plus
425f757f3fSDimitry Andric // operator when we don't perform an implicit conversion when calling it.
4306c3fb27SDimitry Andric template <class _Tp>
445f757f3fSDimitry Andric struct __desugars_to<__plus_tag, plus<_Tp>, _Tp, _Tp> : true_type {};
4506c3fb27SDimitry Andric 
4606c3fb27SDimitry Andric template <class _Tp, class _Up>
475f757f3fSDimitry Andric struct __desugars_to<__plus_tag, plus<void>, _Tp, _Up> : true_type {};
4806c3fb27SDimitry Andric 
4906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
50fe6060f1SDimitry Andric template <>
51*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS plus<void> {
52fe6060f1SDimitry Andric   template <class _T1, class _T2>
53*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
545f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u)))
55*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) {
56*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) + std::forward<_T2>(__u);
57*cb14a3feSDimitry Andric   }
58fe6060f1SDimitry Andric   typedef void is_transparent;
59fe6060f1SDimitry Andric };
60fe6060f1SDimitry Andric #endif
61fe6060f1SDimitry Andric 
6206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
63fe6060f1SDimitry Andric template <class _Tp = void>
64fe6060f1SDimitry Andric #else
65fe6060f1SDimitry Andric template <class _Tp>
66fe6060f1SDimitry Andric #endif
67*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS minus : __binary_function<_Tp, _Tp, _Tp> {
68fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
69*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
70*cb14a3feSDimitry Andric     return __x - __y;
71*cb14a3feSDimitry Andric   }
72fe6060f1SDimitry Andric };
73bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus);
74fe6060f1SDimitry Andric 
7506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
76fe6060f1SDimitry Andric template <>
77*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS minus<void> {
78fe6060f1SDimitry Andric   template <class _T1, class _T2>
79*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
805f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u)))
81*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) {
82*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) - std::forward<_T2>(__u);
83*cb14a3feSDimitry Andric   }
84fe6060f1SDimitry Andric   typedef void is_transparent;
85fe6060f1SDimitry Andric };
86fe6060f1SDimitry Andric #endif
87fe6060f1SDimitry Andric 
8806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
89fe6060f1SDimitry Andric template <class _Tp = void>
90fe6060f1SDimitry Andric #else
91fe6060f1SDimitry Andric template <class _Tp>
92fe6060f1SDimitry Andric #endif
93*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS multiplies : __binary_function<_Tp, _Tp, _Tp> {
94fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
95*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
96*cb14a3feSDimitry Andric     return __x * __y;
97*cb14a3feSDimitry Andric   }
98fe6060f1SDimitry Andric };
99bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies);
100fe6060f1SDimitry Andric 
10106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
102fe6060f1SDimitry Andric template <>
103*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS multiplies<void> {
104fe6060f1SDimitry Andric   template <class _T1, class _T2>
105*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
1065f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u)))
107*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) {
108*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) * std::forward<_T2>(__u);
109*cb14a3feSDimitry Andric   }
110fe6060f1SDimitry Andric   typedef void is_transparent;
111fe6060f1SDimitry Andric };
112fe6060f1SDimitry Andric #endif
113fe6060f1SDimitry Andric 
11406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
115fe6060f1SDimitry Andric template <class _Tp = void>
116fe6060f1SDimitry Andric #else
117fe6060f1SDimitry Andric template <class _Tp>
118fe6060f1SDimitry Andric #endif
119*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS divides : __binary_function<_Tp, _Tp, _Tp> {
120fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
121*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
122*cb14a3feSDimitry Andric     return __x / __y;
123*cb14a3feSDimitry Andric   }
124fe6060f1SDimitry Andric };
125bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides);
126fe6060f1SDimitry Andric 
12706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
128fe6060f1SDimitry Andric template <>
129*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS divides<void> {
130fe6060f1SDimitry Andric   template <class _T1, class _T2>
131*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
1325f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u)))
133*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) {
134*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) / std::forward<_T2>(__u);
135*cb14a3feSDimitry Andric   }
136fe6060f1SDimitry Andric   typedef void is_transparent;
137fe6060f1SDimitry Andric };
138fe6060f1SDimitry Andric #endif
139fe6060f1SDimitry Andric 
14006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
141fe6060f1SDimitry Andric template <class _Tp = void>
142fe6060f1SDimitry Andric #else
143fe6060f1SDimitry Andric template <class _Tp>
144fe6060f1SDimitry Andric #endif
145*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS modulus : __binary_function<_Tp, _Tp, _Tp> {
146fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
147*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
148*cb14a3feSDimitry Andric     return __x % __y;
149*cb14a3feSDimitry Andric   }
150fe6060f1SDimitry Andric };
151bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus);
152fe6060f1SDimitry Andric 
15306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
154fe6060f1SDimitry Andric template <>
155*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS modulus<void> {
156fe6060f1SDimitry Andric   template <class _T1, class _T2>
157*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
1585f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u)))
159*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) {
160*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) % std::forward<_T2>(__u);
161*cb14a3feSDimitry Andric   }
162fe6060f1SDimitry Andric   typedef void is_transparent;
163fe6060f1SDimitry Andric };
164fe6060f1SDimitry Andric #endif
165fe6060f1SDimitry Andric 
16606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
167fe6060f1SDimitry Andric template <class _Tp = void>
168fe6060f1SDimitry Andric #else
169fe6060f1SDimitry Andric template <class _Tp>
170fe6060f1SDimitry Andric #endif
171*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS negate : __unary_function<_Tp, _Tp> {
172fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
173*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; }
174fe6060f1SDimitry Andric };
175bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
176fe6060f1SDimitry Andric 
17706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
178fe6060f1SDimitry Andric template <>
179*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS negate<void> {
180fe6060f1SDimitry Andric   template <class _Tp>
181*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
182*cb14a3feSDimitry Andric       noexcept(noexcept(-std::forward<_Tp>(__x))) -> decltype(-std::forward<_Tp>(__x)) {
183*cb14a3feSDimitry Andric     return -std::forward<_Tp>(__x);
184*cb14a3feSDimitry 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
196*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_and : __binary_function<_Tp, _Tp, _Tp> {
197fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
198*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
199*cb14a3feSDimitry Andric     return __x & __y;
200*cb14a3feSDimitry Andric   }
201fe6060f1SDimitry Andric };
202bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and);
203fe6060f1SDimitry Andric 
20406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
205fe6060f1SDimitry Andric template <>
206*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_and<void> {
207fe6060f1SDimitry Andric   template <class _T1, class _T2>
208*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
2095f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) & std::forward<_T2>(__u)))
210*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) {
211*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) & std::forward<_T2>(__u);
212*cb14a3feSDimitry 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>
219*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_not : __unary_function<_Tp, _Tp> {
220*cb14a3feSDimitry 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 <>
225*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_not<void> {
226fe6060f1SDimitry Andric   template <class _Tp>
227*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
228*cb14a3feSDimitry Andric       noexcept(noexcept(~std::forward<_Tp>(__x))) -> decltype(~std::forward<_Tp>(__x)) {
229*cb14a3feSDimitry Andric     return ~std::forward<_Tp>(__x);
230*cb14a3feSDimitry Andric   }
231fe6060f1SDimitry Andric   typedef void is_transparent;
232fe6060f1SDimitry Andric };
233fe6060f1SDimitry Andric #endif
234fe6060f1SDimitry Andric 
23506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
236fe6060f1SDimitry Andric template <class _Tp = void>
237fe6060f1SDimitry Andric #else
238fe6060f1SDimitry Andric template <class _Tp>
239fe6060f1SDimitry Andric #endif
240*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_or : __binary_function<_Tp, _Tp, _Tp> {
241fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
242*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
243*cb14a3feSDimitry Andric     return __x | __y;
244*cb14a3feSDimitry Andric   }
245fe6060f1SDimitry Andric };
246bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or);
247fe6060f1SDimitry Andric 
24806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
249fe6060f1SDimitry Andric template <>
250*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_or<void> {
251fe6060f1SDimitry Andric   template <class _T1, class _T2>
252*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
2535f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u)))
254*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) {
255*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) | std::forward<_T2>(__u);
256*cb14a3feSDimitry Andric   }
257fe6060f1SDimitry Andric   typedef void is_transparent;
258fe6060f1SDimitry Andric };
259fe6060f1SDimitry Andric #endif
260fe6060f1SDimitry Andric 
26106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
262fe6060f1SDimitry Andric template <class _Tp = void>
263fe6060f1SDimitry Andric #else
264fe6060f1SDimitry Andric template <class _Tp>
265fe6060f1SDimitry Andric #endif
266*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_xor : __binary_function<_Tp, _Tp, _Tp> {
267fe6060f1SDimitry Andric   typedef _Tp __result_type; // used by valarray
268*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
269*cb14a3feSDimitry Andric     return __x ^ __y;
270*cb14a3feSDimitry Andric   }
271fe6060f1SDimitry Andric };
272bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor);
273fe6060f1SDimitry Andric 
27406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
275fe6060f1SDimitry Andric template <>
276*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS bit_xor<void> {
277fe6060f1SDimitry Andric   template <class _T1, class _T2>
278*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
2795f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)))
280*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) {
281*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) ^ std::forward<_T2>(__u);
282*cb14a3feSDimitry Andric   }
283fe6060f1SDimitry Andric   typedef void is_transparent;
284fe6060f1SDimitry Andric };
285fe6060f1SDimitry Andric #endif
286fe6060f1SDimitry Andric 
287fe6060f1SDimitry Andric // Comparison operations
288fe6060f1SDimitry Andric 
28906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
290fe6060f1SDimitry Andric template <class _Tp = void>
291fe6060f1SDimitry Andric #else
292fe6060f1SDimitry Andric template <class _Tp>
293fe6060f1SDimitry Andric #endif
294*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS equal_to : __binary_function<_Tp, _Tp, bool> {
295fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
296*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
297*cb14a3feSDimitry Andric     return __x == __y;
298*cb14a3feSDimitry Andric   }
299fe6060f1SDimitry Andric };
300bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to);
301fe6060f1SDimitry Andric 
30206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
303fe6060f1SDimitry Andric template <>
304*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS equal_to<void> {
305fe6060f1SDimitry Andric   template <class _T1, class _T2>
306*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
3075f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u)))
308*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) {
309*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) == std::forward<_T2>(__u);
310*cb14a3feSDimitry Andric   }
311fe6060f1SDimitry Andric   typedef void is_transparent;
312fe6060f1SDimitry Andric };
313fe6060f1SDimitry Andric #endif
314fe6060f1SDimitry Andric 
3155f757f3fSDimitry Andric // The non-transparent std::equal_to specialization is only equivalent to a raw equality
3165f757f3fSDimitry Andric // comparison when we don't perform an implicit conversion when calling it.
31706c3fb27SDimitry Andric template <class _Tp>
3185f757f3fSDimitry Andric struct __desugars_to<__equal_tag, equal_to<_Tp>, _Tp, _Tp> : true_type {};
31906c3fb27SDimitry Andric 
3205f757f3fSDimitry Andric // In the transparent case, we do not enforce that
3215f757f3fSDimitry Andric template <class _Tp, class _Up>
3225f757f3fSDimitry Andric struct __desugars_to<__equal_tag, equal_to<void>, _Tp, _Up> : true_type {};
32306c3fb27SDimitry Andric 
32406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
325fe6060f1SDimitry Andric template <class _Tp = void>
326fe6060f1SDimitry Andric #else
327fe6060f1SDimitry Andric template <class _Tp>
328fe6060f1SDimitry Andric #endif
329*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS not_equal_to : __binary_function<_Tp, _Tp, bool> {
330fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
331*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
332*cb14a3feSDimitry Andric     return __x != __y;
333*cb14a3feSDimitry Andric   }
334fe6060f1SDimitry Andric };
335bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to);
336fe6060f1SDimitry Andric 
33706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
338fe6060f1SDimitry Andric template <>
339*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS not_equal_to<void> {
340fe6060f1SDimitry Andric   template <class _T1, class _T2>
341*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
3425f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u)))
343*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) {
344*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) != std::forward<_T2>(__u);
345*cb14a3feSDimitry Andric   }
346fe6060f1SDimitry Andric   typedef void is_transparent;
347fe6060f1SDimitry Andric };
348fe6060f1SDimitry Andric #endif
349fe6060f1SDimitry Andric 
35006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
351fe6060f1SDimitry Andric template <class _Tp = void>
352fe6060f1SDimitry Andric #else
353fe6060f1SDimitry Andric template <class _Tp>
354fe6060f1SDimitry Andric #endif
355*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less : __binary_function<_Tp, _Tp, bool> {
356fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
357*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
358*cb14a3feSDimitry Andric     return __x < __y;
359*cb14a3feSDimitry Andric   }
360fe6060f1SDimitry Andric };
361bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less);
362fe6060f1SDimitry Andric 
36306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
364fe6060f1SDimitry Andric template <>
365*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less<void> {
366fe6060f1SDimitry Andric   template <class _T1, class _T2>
367*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
3685f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u)))
369*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) {
370*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) < std::forward<_T2>(__u);
371*cb14a3feSDimitry Andric   }
372fe6060f1SDimitry Andric   typedef void is_transparent;
373fe6060f1SDimitry Andric };
374fe6060f1SDimitry Andric #endif
375fe6060f1SDimitry Andric 
37606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
377fe6060f1SDimitry Andric template <class _Tp = void>
378fe6060f1SDimitry Andric #else
379fe6060f1SDimitry Andric template <class _Tp>
380fe6060f1SDimitry Andric #endif
381*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less_equal : __binary_function<_Tp, _Tp, bool> {
382fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
383*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
384*cb14a3feSDimitry Andric     return __x <= __y;
385*cb14a3feSDimitry Andric   }
386fe6060f1SDimitry Andric };
387bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal);
388fe6060f1SDimitry Andric 
38906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
390fe6060f1SDimitry Andric template <>
391*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS less_equal<void> {
392fe6060f1SDimitry Andric   template <class _T1, class _T2>
393*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
3945f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u)))
395*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) {
396*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) <= std::forward<_T2>(__u);
397*cb14a3feSDimitry Andric   }
398fe6060f1SDimitry Andric   typedef void is_transparent;
399fe6060f1SDimitry Andric };
400fe6060f1SDimitry Andric #endif
401fe6060f1SDimitry Andric 
40206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
403fe6060f1SDimitry Andric template <class _Tp = void>
404fe6060f1SDimitry Andric #else
405fe6060f1SDimitry Andric template <class _Tp>
406fe6060f1SDimitry Andric #endif
407*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater_equal : __binary_function<_Tp, _Tp, bool> {
408fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
409*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
410*cb14a3feSDimitry Andric     return __x >= __y;
411*cb14a3feSDimitry Andric   }
412fe6060f1SDimitry Andric };
413bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal);
414fe6060f1SDimitry Andric 
41506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
416fe6060f1SDimitry Andric template <>
417*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater_equal<void> {
418fe6060f1SDimitry Andric   template <class _T1, class _T2>
419*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
4205f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) >= std::forward<_T2>(__u)))
421*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) {
422*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) >= std::forward<_T2>(__u);
423*cb14a3feSDimitry Andric   }
424fe6060f1SDimitry Andric   typedef void is_transparent;
425fe6060f1SDimitry Andric };
426fe6060f1SDimitry Andric #endif
427fe6060f1SDimitry Andric 
42806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
429fe6060f1SDimitry Andric template <class _Tp = void>
430fe6060f1SDimitry Andric #else
431fe6060f1SDimitry Andric template <class _Tp>
432fe6060f1SDimitry Andric #endif
433*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater : __binary_function<_Tp, _Tp, bool> {
434fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
435*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
436*cb14a3feSDimitry Andric     return __x > __y;
437*cb14a3feSDimitry Andric   }
438fe6060f1SDimitry Andric };
439bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater);
440fe6060f1SDimitry Andric 
44106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
442fe6060f1SDimitry Andric template <>
443*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS greater<void> {
444fe6060f1SDimitry Andric   template <class _T1, class _T2>
445*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
4465f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u)))
447*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) {
448*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) > std::forward<_T2>(__u);
449*cb14a3feSDimitry Andric   }
450fe6060f1SDimitry Andric   typedef void is_transparent;
451fe6060f1SDimitry Andric };
452fe6060f1SDimitry Andric #endif
453fe6060f1SDimitry Andric 
454fe6060f1SDimitry Andric // Logical operations
455fe6060f1SDimitry Andric 
45606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
457fe6060f1SDimitry Andric template <class _Tp = void>
458fe6060f1SDimitry Andric #else
459fe6060f1SDimitry Andric template <class _Tp>
460fe6060f1SDimitry Andric #endif
461*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_and : __binary_function<_Tp, _Tp, bool> {
462fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
463*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
464*cb14a3feSDimitry Andric     return __x && __y;
465*cb14a3feSDimitry Andric   }
466fe6060f1SDimitry Andric };
467bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and);
468fe6060f1SDimitry Andric 
46906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
470fe6060f1SDimitry Andric template <>
471*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_and<void> {
472fe6060f1SDimitry Andric   template <class _T1, class _T2>
473*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
4745f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u)))
475*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) {
476*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) && std::forward<_T2>(__u);
477*cb14a3feSDimitry Andric   }
478fe6060f1SDimitry Andric   typedef void is_transparent;
479fe6060f1SDimitry Andric };
480fe6060f1SDimitry Andric #endif
481fe6060f1SDimitry Andric 
48206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
483fe6060f1SDimitry Andric template <class _Tp = void>
484fe6060f1SDimitry Andric #else
485fe6060f1SDimitry Andric template <class _Tp>
486fe6060f1SDimitry Andric #endif
487*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_not : __unary_function<_Tp, bool> {
488fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
489*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; }
490fe6060f1SDimitry Andric };
491bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
492fe6060f1SDimitry Andric 
49306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
494fe6060f1SDimitry Andric template <>
495*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_not<void> {
496fe6060f1SDimitry Andric   template <class _Tp>
497*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
498*cb14a3feSDimitry Andric       noexcept(noexcept(!std::forward<_Tp>(__x))) -> decltype(!std::forward<_Tp>(__x)) {
499*cb14a3feSDimitry Andric     return !std::forward<_Tp>(__x);
500*cb14a3feSDimitry Andric   }
501fe6060f1SDimitry Andric   typedef void is_transparent;
502fe6060f1SDimitry Andric };
503fe6060f1SDimitry Andric #endif
504fe6060f1SDimitry Andric 
50506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
506fe6060f1SDimitry Andric template <class _Tp = void>
507fe6060f1SDimitry Andric #else
508fe6060f1SDimitry Andric template <class _Tp>
509fe6060f1SDimitry Andric #endif
510*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_or : __binary_function<_Tp, _Tp, bool> {
511fe6060f1SDimitry Andric   typedef bool __result_type; // used by valarray
512*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
513*cb14a3feSDimitry Andric     return __x || __y;
514*cb14a3feSDimitry Andric   }
515fe6060f1SDimitry Andric };
516bdd1243dSDimitry Andric _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or);
517fe6060f1SDimitry Andric 
51806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
519fe6060f1SDimitry Andric template <>
520*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS logical_or<void> {
521fe6060f1SDimitry Andric   template <class _T1, class _T2>
522*cb14a3feSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
5235f757f3fSDimitry Andric       noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u)))
524*cb14a3feSDimitry Andric           -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) {
525*cb14a3feSDimitry Andric     return std::forward<_T1>(__t) || std::forward<_T2>(__u);
526*cb14a3feSDimitry Andric   }
527fe6060f1SDimitry Andric   typedef void is_transparent;
528fe6060f1SDimitry Andric };
529fe6060f1SDimitry Andric #endif
530fe6060f1SDimitry Andric 
531fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
532fe6060f1SDimitry Andric 
533fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H
534