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