source: mainline/uspace/lib/cpp/include/__bits/functional/arithmetic_operations.hpp@ 8fd0675f

Last change on this file since 8fd0675f was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 13.9 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef LIBCPP_BITS_FUNCTIONAL_ARITHMETIC_OPERATIONS
8#define LIBCPP_BITS_FUNCTIONAL_ARITHMETIC_OPERATIONS
9
10#include <__bits/utility/forward_move.hpp>
11#include <type_traits>
12
13namespace std
14{
15 /**
16 * 20.9.5, arithmetic operations:
17 */
18
19 template<class T = void>
20 struct plus
21 {
22 constexpr T operator()(const T& lhs, const T& rhs) const
23 {
24 return lhs + rhs;
25 }
26
27 using first_argument_type = T;
28 using second_argument_type = T;
29 using result_type = T;
30 };
31
32 template<class T = void>
33 struct minus
34 {
35 constexpr T operator()(const T& lhs, const T& rhs) const
36 {
37 return lhs - rhs;
38 }
39
40 using first_argument_type = T;
41 using second_argument_type = T;
42 using result_type = T;
43 };
44
45 template<class T = void>
46 struct multiplies
47 {
48 constexpr T operator()(const T& lhs, const T& rhs) const
49 {
50 return lhs * rhs;
51 }
52
53 using first_argument_type = T;
54 using second_argument_type = T;
55 using result_type = T;
56 };
57
58 template<class T = void>
59 struct divides
60 {
61 constexpr T operator()(const T& lhs, const T& rhs) const
62 {
63 return lhs / rhs;
64 }
65
66 using first_argument_type = T;
67 using second_argument_type = T;
68 using result_type = T;
69 };
70
71 template<class T = void>
72 struct modulus
73 {
74 constexpr T operator()(const T& lhs, const T& rhs) const
75 {
76 return lhs % rhs;
77 }
78
79 using first_argument_type = T;
80 using second_argument_type = T;
81 using result_type = T;
82 };
83
84 template<class T = void>
85 struct negate
86 {
87 constexpr T operator()(const T& x) const
88 {
89 return -x;
90 }
91
92 using argument_type = T;
93 using result_type = T;
94 };
95
96 namespace aux
97 {
98 /**
99 * Used by some functions like std::set::find to determine
100 * whether a functor is transparent.
101 */
102 struct transparent_t;
103
104 template<class T, class = void>
105 struct is_transparent: false_type
106 { /* DUMMY BODY */ };
107
108 template<class T>
109 struct is_transparent<T, void_t<typename T::is_transparent>>
110 : true_type
111 { /* DUMMY BODY */ };
112
113 template<class T>
114 inline constexpr bool is_transparent_v = is_transparent<T>::value;
115 }
116
117 template<>
118 struct plus<void>
119 {
120 template<class T, class U>
121 constexpr auto operator()(T&& lhs, U&& rhs) const
122 -> decltype(forward<T>(lhs) + forward<U>(rhs))
123 {
124 return forward<T>(lhs) + forward<T>(rhs);
125 }
126
127 using is_transparent = aux::transparent_t;
128 };
129
130 template<>
131 struct minus<void>
132 {
133 template<class T, class U>
134 constexpr auto operator()(T&& lhs, U&& rhs) const
135 -> decltype(forward<T>(lhs) - forward<U>(rhs))
136 {
137 return forward<T>(lhs) - forward<T>(rhs);
138 }
139
140 using is_transparent = aux::transparent_t;
141 };
142
143 template<>
144 struct multiplies<void>
145 {
146 template<class T, class U>
147 constexpr auto operator()(T&& lhs, U&& rhs) const
148 -> decltype(forward<T>(lhs) * forward<U>(rhs))
149 {
150 return forward<T>(lhs) * forward<T>(rhs);
151 }
152
153 using is_transparent = aux::transparent_t;
154 };
155
156 template<>
157 struct divides<void>
158 {
159 template<class T, class U>
160 constexpr auto operator()(T&& lhs, U&& rhs) const
161 -> decltype(forward<T>(lhs) / forward<U>(rhs))
162 {
163 return forward<T>(lhs) / forward<T>(rhs);
164 }
165
166 using is_transparent = aux::transparent_t;
167 };
168
169 template<>
170 struct modulus<void>
171 {
172 template<class T, class U>
173 constexpr auto operator()(T&& lhs, U&& rhs) const
174 -> decltype(forward<T>(lhs) % forward<U>(rhs))
175 {
176 return forward<T>(lhs) % forward<T>(rhs);
177 }
178
179 using is_transparent = aux::transparent_t;
180 };
181
182 template<>
183 struct negate<void>
184 {
185 template<class T>
186 constexpr auto operator()(T&& x) const
187 -> decltype(-forward<T>(x))
188 {
189 return -forward<T>(x);
190 }
191
192 using is_transparent = aux::transparent_t;
193 };
194
195 /**
196 * 20.9.6, comparisons:
197 */
198
199 template<class T = void>
200 struct equal_to
201 {
202 constexpr bool operator()(const T& lhs, const T& rhs) const
203 {
204 return lhs == rhs;
205 }
206
207 using first_argument_type = T;
208 using second_argument_type = T;
209 using result_type = bool;
210 };
211
212 template<class T = void>
213 struct not_equal_to
214 {
215 constexpr bool operator()(const T& lhs, const T& rhs) const
216 {
217 return lhs != rhs;
218 }
219
220 using first_argument_type = T;
221 using second_argument_type = T;
222 using result_type = bool;
223 };
224
225 template<class T = void>
226 struct greater
227 {
228 constexpr bool operator()(const T& lhs, const T& rhs) const
229 {
230 return lhs > rhs;
231 }
232
233 using first_argument_type = T;
234 using second_argument_type = T;
235 using result_type = bool;
236 };
237
238 template<class T = void>
239 struct less
240 {
241 constexpr bool operator()(const T& lhs, const T& rhs) const
242 {
243 return lhs < rhs;
244 }
245
246 using first_argument_type = T;
247 using second_argument_type = T;
248 using result_type = bool;
249 };
250
251 template<class T = void>
252 struct greater_equal
253 {
254 constexpr bool operator()(const T& lhs, const T& rhs) const
255 {
256 return lhs >= rhs;
257 }
258
259 using first_argument_type = T;
260 using second_argument_type = T;
261 using result_type = bool;
262 };
263
264 template<class T = void>
265 struct less_equal
266 {
267 constexpr bool operator()(const T& lhs, const T& rhs) const
268 {
269 return lhs <= rhs;
270 }
271
272 using first_argument_type = T;
273 using second_argument_type = T;
274 using result_type = bool;
275 };
276
277 template<>
278 struct equal_to<void>
279 {
280 template<class T, class U>
281 constexpr auto operator()(T&& lhs, U&& rhs) const
282 -> decltype(forward<T>(lhs) == forward<U>(rhs))
283 {
284 return forward<T>(lhs) == forward<U>(rhs);
285 }
286
287 using is_transparent = aux::transparent_t;
288 };
289
290 template<>
291 struct not_equal_to<void>
292 {
293 template<class T, class U>
294 constexpr auto operator()(T&& lhs, U&& rhs) const
295 -> decltype(forward<T>(lhs) != forward<U>(rhs))
296 {
297 return forward<T>(lhs) != forward<U>(rhs);
298 }
299
300 using is_transparent = aux::transparent_t;
301 };
302
303 template<>
304 struct greater<void>
305 {
306 template<class T, class U>
307 constexpr auto operator()(T&& lhs, U&& rhs) const
308 -> decltype(forward<T>(lhs) > forward<U>(rhs))
309 {
310 return forward<T>(lhs) > forward<U>(rhs);
311 }
312
313 using is_transparent = aux::transparent_t;
314 };
315
316 template<>
317 struct less<void>
318 {
319 template<class T, class U>
320 constexpr auto operator()(T&& lhs, U&& rhs) const
321 -> decltype(forward<T>(lhs) < forward<U>(rhs))
322 {
323 return forward<T>(lhs) < forward<U>(rhs);
324 }
325
326 using is_transparent = aux::transparent_t;
327 };
328
329 template<>
330 struct greater_equal<void>
331 {
332 template<class T, class U>
333 constexpr auto operator()(T&& lhs, U&& rhs) const
334 -> decltype(forward<T>(lhs) >= forward<U>(rhs))
335 {
336 return forward<T>(lhs) >= forward<U>(rhs);
337 }
338
339 using is_transparent = aux::transparent_t;
340 };
341
342 template<>
343 struct less_equal<void>
344 {
345 template<class T, class U>
346 constexpr auto operator()(T&& lhs, U&& rhs) const
347 -> decltype(forward<T>(lhs) <= forward<U>(rhs))
348 {
349 return forward<T>(lhs) <= forward<U>(rhs);
350 }
351
352 using is_transparent = aux::transparent_t;
353 };
354
355 /**
356 * 20.9.7, logical operations:
357 */
358
359 template<class T = void>
360 struct logical_and
361 {
362 constexpr bool operator()(const T& lhs, const T& rhs) const
363 {
364 return lhs && rhs;
365 }
366
367 using first_argument_type = T;
368 using second_argument_type = T;
369 using result_type = bool;
370 };
371
372 template<class T = void>
373 struct logical_or
374 {
375 constexpr bool operator()(const T& lhs, const T& rhs) const
376 {
377 return lhs || rhs;
378 }
379
380 using first_argument_type = T;
381 using second_argument_type = T;
382 using result_type = bool;
383 };
384
385 template<class T = void>
386 struct logical_not
387 {
388 constexpr bool operator()(const T& x) const
389 {
390 return !x;
391 }
392
393 using argument_type = T;
394 using result_type = bool;
395 };
396
397 template<>
398 struct logical_and<void>
399 {
400 template<class T, class U>
401 constexpr auto operator()(T&& lhs, U&& rhs) const
402 -> decltype(forward<T>(lhs) && forward<U>(rhs))
403 {
404 return forward<T>(lhs) && forward<U>(rhs);
405 }
406
407 using is_transparent = aux::transparent_t;
408 };
409
410 template<>
411 struct logical_or<void>
412 {
413 template<class T, class U>
414 constexpr auto operator()(T&& lhs, U&& rhs) const
415 -> decltype(forward<T>(lhs) || forward<U>(rhs))
416 {
417 return forward<T>(lhs) || forward<U>(rhs);
418 }
419
420 using is_transparent = aux::transparent_t;
421 };
422
423 template<>
424 struct logical_not<void>
425 {
426 template<class T>
427 constexpr auto operator()(T&& x) const
428 -> decltype(!forward<T>(x))
429 {
430 return !forward<T>(x);
431 }
432
433 using is_transparent = aux::transparent_t;
434 };
435
436 /**
437 * 20.9.8, bitwise operations:
438 */
439
440 template<class T = void>
441 struct bit_and
442 {
443 constexpr T operator()(const T& lhs, const T& rhs) const
444 {
445 return lhs & rhs;
446 }
447
448 using first_argument_type = T;
449 using second_argument_type = T;
450 using result_type = T;
451 };
452
453 template<class T = void>
454 struct bit_or
455 {
456 constexpr T operator()(const T& lhs, const T& rhs) const
457 {
458 return lhs | rhs;
459 }
460
461 using first_argument_type = T;
462 using second_argument_type = T;
463 using result_type = T;
464 };
465
466 template<class T = void>
467 struct bit_xor
468 {
469 constexpr T operator()(const T& lhs, const T& rhs) const
470 {
471 return lhs ^ rhs;
472 }
473
474 using first_argument_type = T;
475 using second_argument_type = T;
476 using result_type = T;
477 };
478
479 template<class T = void>
480 struct bit_not
481 {
482 constexpr bool operator()(const T& x) const
483 {
484 return ~x;
485 }
486
487 using argument_type = T;
488 using result_type = T;
489 };
490
491 template<>
492 struct bit_and<void>
493 {
494 template<class T, class U>
495 constexpr auto operator()(T&& lhs, U&& rhs) const
496 -> decltype(forward<T>(lhs) & forward<U>(rhs))
497 {
498 return forward<T>(lhs) & forward<U>(rhs);
499 }
500
501 using is_transparent = aux::transparent_t;
502 };
503
504 template<>
505 struct bit_or<void>
506 {
507 template<class T, class U>
508 constexpr auto operator()(T&& lhs, U&& rhs) const
509 -> decltype(forward<T>(lhs) | forward<U>(rhs))
510 {
511 return forward<T>(lhs) | forward<U>(rhs);
512 }
513
514 using is_transparent = aux::transparent_t;
515 };
516
517 template<>
518 struct bit_xor<void>
519 {
520 template<class T, class U>
521 constexpr auto operator()(T&& lhs, U&& rhs) const
522 -> decltype(forward<T>(lhs) ^ forward<U>(rhs))
523 {
524 return forward<T>(lhs) ^ forward<U>(rhs);
525 }
526
527 using is_transparent = aux::transparent_t;
528 };
529
530 template<>
531 struct bit_not<void>
532 {
533 template<class T>
534 constexpr auto operator()(T&& x) const
535 -> decltype(~forward<T>(x))
536 {
537 return ~forward<T>(x);
538 }
539
540 using is_transparent = aux::transparent_t;
541 };
542
543 /**
544 * 20.9.9, negators:
545 */
546
547 template<class Predicate>
548 class unary_negate
549 {
550 public:
551 using result_type = bool;
552 using argument_type = typename Predicate::argument_type;
553
554 constexpr explicit unary_negate(const Predicate& pred)
555 : pred_{pred}
556 { /* DUMMY BODY */ }
557
558 constexpr result_type operator()(const argument_type& arg)
559 {
560 return !pred_(arg);
561 }
562
563 private:
564 Predicate pred_;
565 };
566
567 template<class Predicate>
568 constexpr unary_negate<Predicate> not1(const Predicate& pred)
569 {
570 return unary_negate<Predicate>{pred};
571 }
572
573 template<class Predicate>
574 class binary_negate
575 {
576 public:
577 using result_type = bool;
578 using first_argument_type = typename Predicate::first_argument_type;
579 using second_argument_type = typename Predicate::second_argument_type;
580
581 constexpr explicit binary_negate(const Predicate& pred)
582 : pred_{pred}
583 { /* DUMMY BODY */ }
584
585 constexpr result_type operator()(const first_argument_type& arg1,
586 const second_argument_type& arg2)
587 {
588 return !pred_(arg1, arg2);
589 }
590
591 private:
592 Predicate pred_;
593 };
594
595 template<class Predicate>
596 constexpr binary_negate<Predicate> not2(const Predicate& pred);
597}
598
599#endif
Note: See TracBrowser for help on using the repository browser.