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