xref: /llvm-project/libcxx/include/__functional/operations.h (revision 0fb76bae6b2abfe5e0a34557f365a586be989364)
1050b064fSChristopher Di Bella // -*- C++ -*-
2050b064fSChristopher Di Bella //===----------------------------------------------------------------------===//
3050b064fSChristopher Di Bella //
4050b064fSChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5050b064fSChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
6050b064fSChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7050b064fSChristopher Di Bella //
8050b064fSChristopher Di Bella //===----------------------------------------------------------------------===//
9050b064fSChristopher Di Bella 
10050b064fSChristopher Di Bella #ifndef _LIBCPP___FUNCTIONAL_OPERATIONS_H
11050b064fSChristopher Di Bella #define _LIBCPP___FUNCTIONAL_OPERATIONS_H
12050b064fSChristopher Di Bella 
13050b064fSChristopher Di Bella #include <__config>
14050b064fSChristopher Di Bella #include <__functional/binary_function.h>
15050b064fSChristopher Di Bella #include <__functional/unary_function.h>
16f5960c16SNikolas Klauser #include <__type_traits/desugars_to.h>
17d07fdf97SNikolas Klauser #include <__type_traits/is_integral.h>
18050b064fSChristopher Di Bella #include <__utility/forward.h>
19050b064fSChristopher Di Bella 
20050b064fSChristopher Di Bella #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21050b064fSChristopher Di Bella #  pragma GCC system_header
22050b064fSChristopher Di Bella #endif
23050b064fSChristopher Di Bella 
24050b064fSChristopher Di Bella _LIBCPP_BEGIN_NAMESPACE_STD
25050b064fSChristopher Di Bella 
26050b064fSChristopher Di Bella // Arithmetic operations
27050b064fSChristopher Di Bella 
284f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
29050b064fSChristopher Di Bella template <class _Tp = void>
30050b064fSChristopher Di Bella #else
31050b064fSChristopher Di Bella template <class _Tp>
32050b064fSChristopher Di Bella #endif
339783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS plus : __binary_function<_Tp, _Tp, _Tp> {
34050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
359783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
369783f28cSLouis Dionne     return __x + __y;
379783f28cSLouis Dionne   }
38050b064fSChristopher Di Bella };
39c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus);
40050b064fSChristopher Di Bella 
41aea7929bSAnton Rydahl // The non-transparent std::plus specialization is only equivalent to a raw plus
42aea7929bSAnton Rydahl // operator when we don't perform an implicit conversion when calling it.
43ee6ec2c5SNikolas Klauser template <class _Tp>
44f5960c16SNikolas Klauser inline const bool __desugars_to_v<__plus_tag, plus<_Tp>, _Tp, _Tp> = true;
45ee6ec2c5SNikolas Klauser 
46ee6ec2c5SNikolas Klauser template <class _Tp, class _Up>
47f5960c16SNikolas Klauser inline const bool __desugars_to_v<__plus_tag, plus<void>, _Tp, _Up> = true;
48ee6ec2c5SNikolas Klauser 
494f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
50050b064fSChristopher Di Bella template <>
519783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS plus<void> {
52050b064fSChristopher Di Bella   template <class _T1, class _T2>
539783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
54e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) //
559783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) {
569783f28cSLouis Dionne     return std::forward<_T1>(__t) + std::forward<_T2>(__u);
579783f28cSLouis Dionne   }
58050b064fSChristopher Di Bella   typedef void is_transparent;
59050b064fSChristopher Di Bella };
60050b064fSChristopher Di Bella #endif
61050b064fSChristopher Di Bella 
624f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
63050b064fSChristopher Di Bella template <class _Tp = void>
64050b064fSChristopher Di Bella #else
65050b064fSChristopher Di Bella template <class _Tp>
66050b064fSChristopher Di Bella #endif
679783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS minus : __binary_function<_Tp, _Tp, _Tp> {
68050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
699783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
709783f28cSLouis Dionne     return __x - __y;
719783f28cSLouis Dionne   }
72050b064fSChristopher Di Bella };
73c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus);
74050b064fSChristopher Di Bella 
754f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
76050b064fSChristopher Di Bella template <>
779783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS minus<void> {
78050b064fSChristopher Di Bella   template <class _T1, class _T2>
799783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
80e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) //
819783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) {
829783f28cSLouis Dionne     return std::forward<_T1>(__t) - std::forward<_T2>(__u);
839783f28cSLouis Dionne   }
84050b064fSChristopher Di Bella   typedef void is_transparent;
85050b064fSChristopher Di Bella };
86050b064fSChristopher Di Bella #endif
87050b064fSChristopher Di Bella 
884f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
89050b064fSChristopher Di Bella template <class _Tp = void>
90050b064fSChristopher Di Bella #else
91050b064fSChristopher Di Bella template <class _Tp>
92050b064fSChristopher Di Bella #endif
939783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS multiplies : __binary_function<_Tp, _Tp, _Tp> {
94050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
959783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
969783f28cSLouis Dionne     return __x * __y;
979783f28cSLouis Dionne   }
98050b064fSChristopher Di Bella };
99c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies);
100050b064fSChristopher Di Bella 
1014f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
102050b064fSChristopher Di Bella template <>
1039783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS multiplies<void> {
104050b064fSChristopher Di Bella   template <class _T1, class _T2>
1059783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
106e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) //
1079783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) {
1089783f28cSLouis Dionne     return std::forward<_T1>(__t) * std::forward<_T2>(__u);
1099783f28cSLouis Dionne   }
110050b064fSChristopher Di Bella   typedef void is_transparent;
111050b064fSChristopher Di Bella };
112050b064fSChristopher Di Bella #endif
113050b064fSChristopher Di Bella 
1144f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
115050b064fSChristopher Di Bella template <class _Tp = void>
116050b064fSChristopher Di Bella #else
117050b064fSChristopher Di Bella template <class _Tp>
118050b064fSChristopher Di Bella #endif
1199783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS divides : __binary_function<_Tp, _Tp, _Tp> {
120050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
1219783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
1229783f28cSLouis Dionne     return __x / __y;
1239783f28cSLouis Dionne   }
124050b064fSChristopher Di Bella };
125c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides);
126050b064fSChristopher Di Bella 
1274f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
128050b064fSChristopher Di Bella template <>
1299783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS divides<void> {
130050b064fSChristopher Di Bella   template <class _T1, class _T2>
1319783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
132e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) //
1339783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) {
1349783f28cSLouis Dionne     return std::forward<_T1>(__t) / std::forward<_T2>(__u);
1359783f28cSLouis Dionne   }
136050b064fSChristopher Di Bella   typedef void is_transparent;
137050b064fSChristopher Di Bella };
138050b064fSChristopher Di Bella #endif
139050b064fSChristopher Di Bella 
1404f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
141050b064fSChristopher Di Bella template <class _Tp = void>
142050b064fSChristopher Di Bella #else
143050b064fSChristopher Di Bella template <class _Tp>
144050b064fSChristopher Di Bella #endif
1459783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS modulus : __binary_function<_Tp, _Tp, _Tp> {
146050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
1479783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
1489783f28cSLouis Dionne     return __x % __y;
1499783f28cSLouis Dionne   }
150050b064fSChristopher Di Bella };
151c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus);
152050b064fSChristopher Di Bella 
1534f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
154050b064fSChristopher Di Bella template <>
1559783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS modulus<void> {
156050b064fSChristopher Di Bella   template <class _T1, class _T2>
1579783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
158e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) //
1599783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) {
1609783f28cSLouis Dionne     return std::forward<_T1>(__t) % std::forward<_T2>(__u);
1619783f28cSLouis Dionne   }
162050b064fSChristopher Di Bella   typedef void is_transparent;
163050b064fSChristopher Di Bella };
164050b064fSChristopher Di Bella #endif
165050b064fSChristopher Di Bella 
1664f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
167050b064fSChristopher Di Bella template <class _Tp = void>
168050b064fSChristopher Di Bella #else
169050b064fSChristopher Di Bella template <class _Tp>
170050b064fSChristopher Di Bella #endif
1719783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS negate : __unary_function<_Tp, _Tp> {
172050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
1739783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; }
174050b064fSChristopher Di Bella };
175c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate);
176050b064fSChristopher Di Bella 
1774f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
178050b064fSChristopher Di Bella template <>
1799783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS negate<void> {
180050b064fSChristopher Di Bella   template <class _Tp>
1819783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
182e2c2ffbeSLouis Dionne       noexcept(noexcept(-std::forward<_Tp>(__x))) //
183e2c2ffbeSLouis Dionne       -> decltype(-std::forward<_Tp>(__x)) {
1849783f28cSLouis Dionne     return -std::forward<_Tp>(__x);
1859783f28cSLouis Dionne   }
186050b064fSChristopher Di Bella   typedef void is_transparent;
187050b064fSChristopher Di Bella };
188050b064fSChristopher Di Bella #endif
189050b064fSChristopher Di Bella 
190050b064fSChristopher Di Bella // Bitwise operations
191050b064fSChristopher Di Bella 
1924f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
193050b064fSChristopher Di Bella template <class _Tp = void>
194050b064fSChristopher Di Bella #else
195050b064fSChristopher Di Bella template <class _Tp>
196050b064fSChristopher Di Bella #endif
1979783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS bit_and : __binary_function<_Tp, _Tp, _Tp> {
198050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
1999783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
2009783f28cSLouis Dionne     return __x & __y;
2019783f28cSLouis Dionne   }
202050b064fSChristopher Di Bella };
203c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and);
204050b064fSChristopher Di Bella 
2054f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
206050b064fSChristopher Di Bella template <>
2079783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS bit_and<void> {
208050b064fSChristopher Di Bella   template <class _T1, class _T2>
2099783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
210e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) &
211e2c2ffbeSLouis Dionne                         std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) {
2129783f28cSLouis Dionne     return std::forward<_T1>(__t) & std::forward<_T2>(__u);
2139783f28cSLouis Dionne   }
214050b064fSChristopher Di Bella   typedef void is_transparent;
215050b064fSChristopher Di Bella };
216050b064fSChristopher Di Bella #endif
217050b064fSChristopher Di Bella 
2184f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
219050b064fSChristopher Di Bella template <class _Tp = void>
2209783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS bit_not : __unary_function<_Tp, _Tp> {
2219783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return ~__x; }
222050b064fSChristopher Di Bella };
223c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not);
224050b064fSChristopher Di Bella 
225050b064fSChristopher Di Bella template <>
2269783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS bit_not<void> {
227050b064fSChristopher Di Bella   template <class _Tp>
2289783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
229e2c2ffbeSLouis Dionne       noexcept(noexcept(~std::forward<_Tp>(__x))) //
230e2c2ffbeSLouis Dionne       -> decltype(~std::forward<_Tp>(__x)) {
2319783f28cSLouis Dionne     return ~std::forward<_Tp>(__x);
2329783f28cSLouis Dionne   }
233050b064fSChristopher Di Bella   typedef void is_transparent;
234050b064fSChristopher Di Bella };
235050b064fSChristopher Di Bella #endif
236050b064fSChristopher Di Bella 
2374f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
238050b064fSChristopher Di Bella template <class _Tp = void>
239050b064fSChristopher Di Bella #else
240050b064fSChristopher Di Bella template <class _Tp>
241050b064fSChristopher Di Bella #endif
2429783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS bit_or : __binary_function<_Tp, _Tp, _Tp> {
243050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
2449783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
2459783f28cSLouis Dionne     return __x | __y;
2469783f28cSLouis Dionne   }
247050b064fSChristopher Di Bella };
248c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or);
249050b064fSChristopher Di Bella 
2504f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
251050b064fSChristopher Di Bella template <>
2529783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS bit_or<void> {
253050b064fSChristopher Di Bella   template <class _T1, class _T2>
2549783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
255e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) //
2569783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) {
2579783f28cSLouis Dionne     return std::forward<_T1>(__t) | std::forward<_T2>(__u);
2589783f28cSLouis Dionne   }
259050b064fSChristopher Di Bella   typedef void is_transparent;
260050b064fSChristopher Di Bella };
261050b064fSChristopher Di Bella #endif
262050b064fSChristopher Di Bella 
2634f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
264050b064fSChristopher Di Bella template <class _Tp = void>
265050b064fSChristopher Di Bella #else
266050b064fSChristopher Di Bella template <class _Tp>
267050b064fSChristopher Di Bella #endif
2689783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS bit_xor : __binary_function<_Tp, _Tp, _Tp> {
269050b064fSChristopher Di Bella   typedef _Tp __result_type; // used by valarray
2709783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const {
2719783f28cSLouis Dionne     return __x ^ __y;
2729783f28cSLouis Dionne   }
273050b064fSChristopher Di Bella };
274c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor);
275050b064fSChristopher Di Bella 
2764f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
277050b064fSChristopher Di Bella template <>
2789783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS bit_xor<void> {
279050b064fSChristopher Di Bella   template <class _T1, class _T2>
2809783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
281e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) //
2829783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) {
2839783f28cSLouis Dionne     return std::forward<_T1>(__t) ^ std::forward<_T2>(__u);
2849783f28cSLouis Dionne   }
285050b064fSChristopher Di Bella   typedef void is_transparent;
286050b064fSChristopher Di Bella };
287050b064fSChristopher Di Bella #endif
288050b064fSChristopher Di Bella 
289050b064fSChristopher Di Bella // Comparison operations
290050b064fSChristopher Di Bella 
2914f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
292050b064fSChristopher Di Bella template <class _Tp = void>
293050b064fSChristopher Di Bella #else
294050b064fSChristopher Di Bella template <class _Tp>
295050b064fSChristopher Di Bella #endif
2969783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS equal_to : __binary_function<_Tp, _Tp, bool> {
297050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
2989783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
2999783f28cSLouis Dionne     return __x == __y;
3009783f28cSLouis Dionne   }
301050b064fSChristopher Di Bella };
302c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to);
303050b064fSChristopher Di Bella 
3044f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
305050b064fSChristopher Di Bella template <>
3069783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS equal_to<void> {
307050b064fSChristopher Di Bella   template <class _T1, class _T2>
3089783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
309e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) //
3109783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) {
3119783f28cSLouis Dionne     return std::forward<_T1>(__t) == std::forward<_T2>(__u);
3129783f28cSLouis Dionne   }
313050b064fSChristopher Di Bella   typedef void is_transparent;
314050b064fSChristopher Di Bella };
315050b064fSChristopher Di Bella #endif
316050b064fSChristopher Di Bella 
317aea7929bSAnton Rydahl // The non-transparent std::equal_to specialization is only equivalent to a raw equality
318aea7929bSAnton Rydahl // comparison when we don't perform an implicit conversion when calling it.
319b4ecfd3cSNikolas Klauser template <class _Tp>
320f5960c16SNikolas Klauser inline const bool __desugars_to_v<__equal_tag, equal_to<_Tp>, _Tp, _Tp> = true;
321b4ecfd3cSNikolas Klauser 
322aea7929bSAnton Rydahl // In the transparent case, we do not enforce that
323aea7929bSAnton Rydahl template <class _Tp, class _Up>
324f5960c16SNikolas Klauser inline const bool __desugars_to_v<__equal_tag, equal_to<void>, _Tp, _Up> = true;
325b4ecfd3cSNikolas Klauser 
3264f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
327050b064fSChristopher Di Bella template <class _Tp = void>
328050b064fSChristopher Di Bella #else
329050b064fSChristopher Di Bella template <class _Tp>
330050b064fSChristopher Di Bella #endif
3319783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS not_equal_to : __binary_function<_Tp, _Tp, bool> {
332050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
3339783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
3349783f28cSLouis Dionne     return __x != __y;
3359783f28cSLouis Dionne   }
336050b064fSChristopher Di Bella };
337c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to);
338050b064fSChristopher Di Bella 
3394f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
340050b064fSChristopher Di Bella template <>
3419783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS not_equal_to<void> {
342050b064fSChristopher Di Bella   template <class _T1, class _T2>
3439783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
344e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) //
3459783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) {
3469783f28cSLouis Dionne     return std::forward<_T1>(__t) != std::forward<_T2>(__u);
3479783f28cSLouis Dionne   }
348050b064fSChristopher Di Bella   typedef void is_transparent;
349050b064fSChristopher Di Bella };
350050b064fSChristopher Di Bella #endif
351050b064fSChristopher Di Bella 
3524f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
353050b064fSChristopher Di Bella template <class _Tp = void>
354050b064fSChristopher Di Bella #else
355050b064fSChristopher Di Bella template <class _Tp>
356050b064fSChristopher Di Bella #endif
3579783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS less : __binary_function<_Tp, _Tp, bool> {
358050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
3599783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
3609783f28cSLouis Dionne     return __x < __y;
3619783f28cSLouis Dionne   }
362050b064fSChristopher Di Bella };
363c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less);
364050b064fSChristopher Di Bella 
365935e6991SNikolas Klauser template <class _Tp>
366*0fb76baeSNikolas Klauser inline const bool __desugars_to_v<__less_tag, less<_Tp>, _Tp, _Tp> = true;
367*0fb76baeSNikolas Klauser 
368*0fb76baeSNikolas Klauser template <class _Tp>
369d07fdf97SNikolas Klauser inline const bool __desugars_to_v<__totally_ordered_less_tag, less<_Tp>, _Tp, _Tp> = is_integral<_Tp>::value;
370935e6991SNikolas Klauser 
3714f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
372050b064fSChristopher Di Bella template <>
3739783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS less<void> {
374050b064fSChristopher Di Bella   template <class _T1, class _T2>
3759783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
376e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) //
3779783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) {
3789783f28cSLouis Dionne     return std::forward<_T1>(__t) < std::forward<_T2>(__u);
3799783f28cSLouis Dionne   }
380050b064fSChristopher Di Bella   typedef void is_transparent;
381050b064fSChristopher Di Bella };
382935e6991SNikolas Klauser 
383*0fb76baeSNikolas Klauser template <class _Tp, class _Up>
384*0fb76baeSNikolas Klauser inline const bool __desugars_to_v<__less_tag, less<>, _Tp, _Up> = true;
385*0fb76baeSNikolas Klauser 
386935e6991SNikolas Klauser template <class _Tp>
387d07fdf97SNikolas Klauser inline const bool __desugars_to_v<__totally_ordered_less_tag, less<>, _Tp, _Tp> = is_integral<_Tp>::value;
388050b064fSChristopher Di Bella #endif
389050b064fSChristopher Di Bella 
3904f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
391050b064fSChristopher Di Bella template <class _Tp = void>
392050b064fSChristopher Di Bella #else
393050b064fSChristopher Di Bella template <class _Tp>
394050b064fSChristopher Di Bella #endif
3959783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS less_equal : __binary_function<_Tp, _Tp, bool> {
396050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
3979783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
3989783f28cSLouis Dionne     return __x <= __y;
3999783f28cSLouis Dionne   }
400050b064fSChristopher Di Bella };
401c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal);
402050b064fSChristopher Di Bella 
4034f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
404050b064fSChristopher Di Bella template <>
4059783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS less_equal<void> {
406050b064fSChristopher Di Bella   template <class _T1, class _T2>
4079783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
408e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) //
4099783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) {
4109783f28cSLouis Dionne     return std::forward<_T1>(__t) <= std::forward<_T2>(__u);
4119783f28cSLouis Dionne   }
412050b064fSChristopher Di Bella   typedef void is_transparent;
413050b064fSChristopher Di Bella };
414050b064fSChristopher Di Bella #endif
415050b064fSChristopher Di Bella 
4164f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
417050b064fSChristopher Di Bella template <class _Tp = void>
418050b064fSChristopher Di Bella #else
419050b064fSChristopher Di Bella template <class _Tp>
420050b064fSChristopher Di Bella #endif
4219783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS greater_equal : __binary_function<_Tp, _Tp, bool> {
422050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
4239783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
4249783f28cSLouis Dionne     return __x >= __y;
4259783f28cSLouis Dionne   }
426050b064fSChristopher Di Bella };
427c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal);
428050b064fSChristopher Di Bella 
4294f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
430050b064fSChristopher Di Bella template <>
4319783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS greater_equal<void> {
432050b064fSChristopher Di Bella   template <class _T1, class _T2>
4339783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
434e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) >=
435e2c2ffbeSLouis Dionne                         std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) {
4369783f28cSLouis Dionne     return std::forward<_T1>(__t) >= std::forward<_T2>(__u);
4379783f28cSLouis Dionne   }
438050b064fSChristopher Di Bella   typedef void is_transparent;
439050b064fSChristopher Di Bella };
440050b064fSChristopher Di Bella #endif
441050b064fSChristopher Di Bella 
4424f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
443050b064fSChristopher Di Bella template <class _Tp = void>
444050b064fSChristopher Di Bella #else
445050b064fSChristopher Di Bella template <class _Tp>
446050b064fSChristopher Di Bella #endif
4479783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS greater : __binary_function<_Tp, _Tp, bool> {
448050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
4499783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
4509783f28cSLouis Dionne     return __x > __y;
4519783f28cSLouis Dionne   }
452050b064fSChristopher Di Bella };
453c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater);
454050b064fSChristopher Di Bella 
455*0fb76baeSNikolas Klauser template <class _Tp>
456*0fb76baeSNikolas Klauser inline const bool __desugars_to_v<__greater_tag, greater<_Tp>, _Tp, _Tp> = true;
457*0fb76baeSNikolas Klauser 
4584f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
459050b064fSChristopher Di Bella template <>
4609783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS greater<void> {
461050b064fSChristopher Di Bella   template <class _T1, class _T2>
4629783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
463e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) //
4649783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) {
4659783f28cSLouis Dionne     return std::forward<_T1>(__t) > std::forward<_T2>(__u);
4669783f28cSLouis Dionne   }
467050b064fSChristopher Di Bella   typedef void is_transparent;
468050b064fSChristopher Di Bella };
469*0fb76baeSNikolas Klauser 
470*0fb76baeSNikolas Klauser template <class _Tp, class _Up>
471*0fb76baeSNikolas Klauser inline const bool __desugars_to_v<__greater_tag, greater<>, _Tp, _Up> = true;
472050b064fSChristopher Di Bella #endif
473050b064fSChristopher Di Bella 
474050b064fSChristopher Di Bella // Logical operations
475050b064fSChristopher Di Bella 
4764f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
477050b064fSChristopher Di Bella template <class _Tp = void>
478050b064fSChristopher Di Bella #else
479050b064fSChristopher Di Bella template <class _Tp>
480050b064fSChristopher Di Bella #endif
4819783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS logical_and : __binary_function<_Tp, _Tp, bool> {
482050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
4839783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
4849783f28cSLouis Dionne     return __x && __y;
4859783f28cSLouis Dionne   }
486050b064fSChristopher Di Bella };
487c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and);
488050b064fSChristopher Di Bella 
4894f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
490050b064fSChristopher Di Bella template <>
4919783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS logical_and<void> {
492050b064fSChristopher Di Bella   template <class _T1, class _T2>
4939783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
494e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) //
4959783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) {
4969783f28cSLouis Dionne     return std::forward<_T1>(__t) && std::forward<_T2>(__u);
4979783f28cSLouis Dionne   }
498050b064fSChristopher Di Bella   typedef void is_transparent;
499050b064fSChristopher Di Bella };
500050b064fSChristopher Di Bella #endif
501050b064fSChristopher Di Bella 
5024f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
503050b064fSChristopher Di Bella template <class _Tp = void>
504050b064fSChristopher Di Bella #else
505050b064fSChristopher Di Bella template <class _Tp>
506050b064fSChristopher Di Bella #endif
5079783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS logical_not : __unary_function<_Tp, bool> {
508050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
5099783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; }
510050b064fSChristopher Di Bella };
511c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not);
512050b064fSChristopher Di Bella 
5134f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
514050b064fSChristopher Di Bella template <>
5159783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS logical_not<void> {
516050b064fSChristopher Di Bella   template <class _Tp>
5179783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const
518e2c2ffbeSLouis Dionne       noexcept(noexcept(!std::forward<_Tp>(__x))) //
519e2c2ffbeSLouis Dionne       -> decltype(!std::forward<_Tp>(__x)) {
5209783f28cSLouis Dionne     return !std::forward<_Tp>(__x);
5219783f28cSLouis Dionne   }
522050b064fSChristopher Di Bella   typedef void is_transparent;
523050b064fSChristopher Di Bella };
524050b064fSChristopher Di Bella #endif
525050b064fSChristopher Di Bella 
5264f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
527050b064fSChristopher Di Bella template <class _Tp = void>
528050b064fSChristopher Di Bella #else
529050b064fSChristopher Di Bella template <class _Tp>
530050b064fSChristopher Di Bella #endif
5319783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS logical_or : __binary_function<_Tp, _Tp, bool> {
532050b064fSChristopher Di Bella   typedef bool __result_type; // used by valarray
5339783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const {
5349783f28cSLouis Dionne     return __x || __y;
5359783f28cSLouis Dionne   }
536050b064fSChristopher Di Bella };
537c2df7076SLouis Dionne _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or);
538050b064fSChristopher Di Bella 
5394f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14
540050b064fSChristopher Di Bella template <>
5419783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS logical_or<void> {
542050b064fSChristopher Di Bella   template <class _T1, class _T2>
5439783f28cSLouis Dionne   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
544e2c2ffbeSLouis Dionne       noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) //
5459783f28cSLouis Dionne       -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) {
5469783f28cSLouis Dionne     return std::forward<_T1>(__t) || std::forward<_T2>(__u);
5479783f28cSLouis Dionne   }
548050b064fSChristopher Di Bella   typedef void is_transparent;
549050b064fSChristopher Di Bella };
550050b064fSChristopher Di Bella #endif
551050b064fSChristopher Di Bella 
552050b064fSChristopher Di Bella _LIBCPP_END_NAMESPACE_STD
553050b064fSChristopher Di Bella 
554050b064fSChristopher Di Bella #endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H
555