source: mainline/uspace/lib/cpp/include/__bits/functional/arithmetic_operations.hpp@ 7bbf91e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7bbf91e was 7bbf91e, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: changed internal to bits to avoid include space pollusion, fixed old std::hel:: bugs in files that weren't touched since

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