24 #ifndef PPL_checked_ext_defs_hh
25 #define PPL_checked_ext_defs_hh 1
42 template <
typename Policy,
typename Type>
46 && (Policy::has_infinity || Policy::has_nan);
49 template <
typename Policy,
typename Type>
52 if (!ext_to_handle<Policy>(x)) {
55 if (is_nan<Policy>(x)) {
58 else if (is_minf<Policy>(x)) {
61 else if (is_pinf<Policy>(x)) {
66 return sgn<Policy>(x);
70 template <
typename To_Policy,
typename From_Policy,
71 typename To,
typename From>
74 if (!ext_to_handle<From_Policy>(x)) {
77 if (is_nan<From_Policy>(x)) {
80 else if (is_minf<From_Policy>(x)) {
83 else if (is_pinf<From_Policy>(x)) {
88 return construct<To_Policy, From_Policy>(to, x, dir);
92 template <
typename To_Policy,
typename From_Policy,
93 typename To,
typename From>
96 if (!ext_to_handle<From_Policy>(x)) {
99 if (is_nan<From_Policy>(x)) {
102 else if (is_minf<From_Policy>(x)) {
105 else if (is_pinf<From_Policy>(x)) {
110 return assign<To_Policy, From_Policy>(to, x, dir);
114 template <
typename To_Policy,
typename From_Policy,
115 typename To,
typename From>
118 if (!ext_to_handle<From_Policy>(x)) {
121 if (is_nan<From_Policy>(x)) {
124 else if (is_minf<From_Policy>(x)) {
127 else if (is_pinf<From_Policy>(x)) {
132 return neg<To_Policy, From_Policy>(to, x, dir);
136 template <
typename To_Policy,
typename From_Policy,
137 typename To,
typename From>
140 if (!ext_to_handle<From_Policy>(x)) {
143 if (is_nan<From_Policy>(x)) {
146 else if (is_minf<From_Policy>(x)) {
149 else if (is_pinf<From_Policy>(x)) {
154 return floor<To_Policy, From_Policy>(to, x, dir);
158 template <
typename To_Policy,
typename From_Policy,
159 typename To,
typename From>
162 if (!ext_to_handle<From_Policy>(x)) {
165 if (is_nan<From_Policy>(x)) {
168 else if (is_minf<From_Policy>(x)) {
171 else if (is_pinf<From_Policy>(x)) {
176 return ceil<To_Policy, From_Policy>(to, x, dir);
180 template <
typename To_Policy,
typename From_Policy,
181 typename To,
typename From>
184 if (!ext_to_handle<From_Policy>(x)) {
187 if (is_nan<From_Policy>(x)) {
190 else if (is_minf<From_Policy>(x)) {
193 else if (is_pinf<From_Policy>(x)) {
198 return trunc<To_Policy, From_Policy>(to, x, dir);
202 template <
typename To_Policy,
typename From_Policy,
203 typename To,
typename From>
206 if (!ext_to_handle<From_Policy>(x)) {
209 if (is_nan<From_Policy>(x)) {
212 else if (is_minf<From_Policy>(x) || is_pinf<From_Policy>(x)) {
217 return abs<To_Policy, From_Policy>(to, x, dir);
221 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
225 if (!ext_to_handle<From1_Policy>(x) && !ext_to_handle<From2_Policy>(y)) {
228 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
231 else if (is_minf<From1_Policy>(x)) {
232 if (
CHECK_P(To_Policy::check_inf_add_inf, is_pinf<From2_Policy>(y))) {
239 else if (is_pinf<From1_Policy>(x)) {
240 if (
CHECK_P(To_Policy::check_inf_add_inf, is_minf<From2_Policy>(y))) {
249 if (is_minf<From2_Policy>(y)) {
253 else if (is_pinf<From2_Policy>(y)) {
259 return add<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
264 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
268 if (!ext_to_handle<From1_Policy>(x) && !ext_to_handle<From2_Policy>(y)) {
271 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
274 else if (is_minf<From1_Policy>(x)) {
275 if (
CHECK_P(To_Policy::check_inf_sub_inf, is_minf<From2_Policy>(y))) {
282 else if (is_pinf<From1_Policy>(x)) {
283 if (
CHECK_P(To_Policy::check_inf_sub_inf, is_pinf<From2_Policy>(y))) {
292 if (is_pinf<From2_Policy>(y)) {
296 else if (is_minf<From2_Policy>(y)) {
302 return sub<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
307 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
311 if (!ext_to_handle<From1_Policy>(x) && !ext_to_handle<From2_Policy>(y)) {
314 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
317 if (is_minf<From1_Policy>(x)) {
318 switch (sgn_ext<From2_Policy>(y)) {
327 else if (is_pinf<From1_Policy>(x)) {
328 switch (sgn_ext<From2_Policy>(y)) {
338 if (is_minf<From2_Policy>(y)) {
339 switch (sgn<From1_Policy>(x)) {
348 else if (is_pinf<From2_Policy>(y)) {
349 switch (sgn<From1_Policy>(x)) {
358 PPL_ASSERT(To_Policy::check_inf_mul_zero);
364 return mul<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
370 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
374 if (!ext_to_handle<To_Policy>(to)
375 && !ext_to_handle<From1_Policy>(x) && !ext_to_handle<From2_Policy>(y)) {
378 if (is_nan<To_Policy>(to)
379 || is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
382 if (is_minf<From1_Policy>(x)) {
383 switch (sgn_ext<From2_Policy>(y)) {
392 else if (is_pinf<From1_Policy>(x)) {
393 switch (sgn_ext<From2_Policy>(y)) {
403 if (is_minf<From2_Policy>(y)) {
404 switch (sgn<From1_Policy>(x)) {
413 else if (is_pinf<From2_Policy>(y)) {
414 switch (sgn<From1_Policy>(x)) {
417 if (
CHECK_P(To_Policy::check_inf_add_inf, is_pinf<To_Policy>(to))) {
425 if (
CHECK_P(To_Policy::check_inf_add_inf, is_minf<To_Policy>(to))) {
434 PPL_ASSERT(To_Policy::check_inf_mul_zero);
439 if (is_minf<To_Policy>(to)) {
443 if (is_pinf<To_Policy>(to)) {
448 return add_mul<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
453 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
457 if (!ext_to_handle<To_Policy>(to)
458 && !ext_to_handle<From1_Policy>(x) && !ext_to_handle<From2_Policy>(y)) {
461 if (is_nan<To_Policy>(to)
462 || is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
465 if (is_minf<From1_Policy>(x)) {
466 switch (sgn_ext<From2_Policy>(y)) {
475 else if (is_pinf<From1_Policy>(x)) {
476 switch (sgn_ext<From2_Policy>(y)) {
486 if (is_minf<From2_Policy>(y)) {
487 switch (sgn<From1_Policy>(x)) {
496 else if (is_pinf<From2_Policy>(y)) {
497 switch (sgn<From1_Policy>(x)) {
500 if (
CHECK_P(To_Policy::check_inf_sub_inf, is_minf<To_Policy>(to))) {
508 if (
CHECK_P(To_Policy::check_inf_sub_inf, is_pinf<To_Policy>(to))) {
517 PPL_ASSERT(To_Policy::check_inf_mul_zero);
522 if (is_minf<To_Policy>(to)) {
526 if (is_pinf<To_Policy>(to)) {
531 return sub_mul<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
536 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
540 if (!ext_to_handle<From1_Policy>(x) && !ext_to_handle<From2_Policy>(y)) {
543 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
546 if (is_minf<From1_Policy>(x)) {
547 if (
CHECK_P(To_Policy::check_inf_div_inf, is_minf<From2_Policy>(y)
548 || is_pinf<From2_Policy>(y))) {
552 switch (sgn<From2_Policy>(y)) {
562 else if (is_pinf<From1_Policy>(x)) {
563 if (
CHECK_P(To_Policy::check_inf_div_inf, is_minf<From2_Policy>(y)
564 || is_pinf<From2_Policy>(y))) {
569 switch (sgn<From2_Policy>(y)) {
578 PPL_ASSERT(To_Policy::check_div_zero);
584 if (is_minf<From2_Policy>(y) || is_pinf<From2_Policy>(y)) {
590 return div<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
596 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
600 if (!ext_to_handle<From1_Policy>(x) && !ext_to_handle<From2_Policy>(y)) {
603 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
606 if (is_minf<From1_Policy>(x)) {
607 if (
CHECK_P(To_Policy::check_inf_div_inf, is_minf<From2_Policy>(y)
608 || is_pinf<From2_Policy>(y))) {
612 switch (sgn<From2_Policy>(y)) {
622 else if (is_pinf<From1_Policy>(x)) {
623 if (
CHECK_P(To_Policy::check_inf_div_inf, is_minf<From2_Policy>(y)
624 || is_pinf<From2_Policy>(y))) {
629 switch (sgn<From2_Policy>(y)) {
638 PPL_ASSERT(To_Policy::check_div_zero);
644 if (is_minf<From2_Policy>(y) || is_pinf<From2_Policy>(y)) {
650 return idiv<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
656 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
660 if (!ext_to_handle<From1_Policy>(x) && !ext_to_handle<From2_Policy>(y)) {
663 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
666 else if (
CHECK_P(To_Policy::check_inf_mod, is_minf<From1_Policy>(x)
667 || is_pinf<From1_Policy>(x))) {
668 return assign_nan<To_Policy>(to,
V_INF_MOD);
671 if (is_minf<From1_Policy>(y) || is_pinf<From2_Policy>(y)) {
677 return rem<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
682 template <
typename To_Policy,
typename From_Policy,
683 typename To,
typename From>
686 if (!ext_to_handle<From_Policy>(x)) {
689 if (is_nan<From_Policy>(x)) {
692 else if (is_minf<From_Policy>(x)) {
695 else if (is_pinf<From_Policy>(x)) {
700 return add_2exp<To_Policy, From_Policy>(to, x, exp, dir);
704 template <
typename To_Policy,
typename From_Policy,
705 typename To,
typename From>
708 if (!ext_to_handle<From_Policy>(x)) {
711 if (is_nan<From_Policy>(x)) {
714 else if (is_minf<From_Policy>(x)) {
717 else if (is_pinf<From_Policy>(x)) {
722 return sub_2exp<To_Policy, From_Policy>(to, x, exp, dir);
726 template <
typename To_Policy,
typename From_Policy,
727 typename To,
typename From>
730 if (!ext_to_handle<From_Policy>(x)) {
733 if (is_nan<From_Policy>(x)) {
736 else if (is_minf<From_Policy>(x)) {
739 else if (is_pinf<From_Policy>(x)) {
744 return mul_2exp<To_Policy, From_Policy>(to, x, exp, dir);
748 template <
typename To_Policy,
typename From_Policy,
749 typename To,
typename From>
752 if (!ext_to_handle<From_Policy>(x)) {
755 if (is_nan<From_Policy>(x)) {
758 else if (is_minf<From_Policy>(x)) {
761 else if (is_pinf<From_Policy>(x)) {
766 return div_2exp<To_Policy, From_Policy>(to, x, exp, dir);
770 template <
typename To_Policy,
typename From_Policy,
771 typename To,
typename From>
774 if (!ext_to_handle<From_Policy>(x)) {
777 if (is_nan<From_Policy>(x)) {
780 else if (
CHECK_P(To_Policy::check_inf_mod, is_minf<From_Policy>(x)
781 || is_pinf<From_Policy>(x))) {
782 return assign_nan<To_Policy>(to,
V_INF_MOD);
786 return smod_2exp<To_Policy, From_Policy>(to, x, exp, dir);
790 template <
typename To_Policy,
typename From_Policy,
791 typename To,
typename From>
794 if (!ext_to_handle<From_Policy>(x)) {
797 if (is_nan<From_Policy>(x)) {
800 else if (
CHECK_P(To_Policy::check_inf_mod, is_minf<From_Policy>(x)
801 || is_pinf<From_Policy>(x))) {
802 return assign_nan<To_Policy>(to,
V_INF_MOD);
806 return umod_2exp<To_Policy, From_Policy>(to, x, exp, dir);
810 template <
typename To_Policy,
typename From_Policy,
811 typename To,
typename From>
814 if (!ext_to_handle<From_Policy>(x)) {
817 if (is_nan<From_Policy>(x)) {
820 else if (is_minf<From_Policy>(x)) {
823 else if (is_pinf<From_Policy>(x)) {
828 return sqrt<To_Policy, From_Policy>(to, x, dir);
832 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
836 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
839 else if (is_minf<From1_Policy>(x) || is_pinf<From1_Policy>(x)) {
840 return abs_ext<To_Policy, From2_Policy>(to, y, dir);
842 else if (is_minf<From2_Policy>(y) || is_pinf<From2_Policy>(y)) {
843 return abs_ext<To_Policy, From1_Policy>(to, x, dir);
846 return gcd<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
850 template <
typename To1_Policy,
typename To2_Policy,
typename To3_Policy,
851 typename From1_Policy,
typename From2_Policy,
852 typename To1,
typename To2,
typename To3,
857 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
860 else if (is_minf<From1_Policy>(x) || is_pinf<From1_Policy>(x)) {
863 return abs_ext<To1_Policy, From2_Policy>(to, y, dir);
865 else if (is_minf<From2_Policy>(y) || is_pinf<From2_Policy>(y)) {
868 return abs_ext<To1_Policy, From1_Policy>(to, x, dir);
871 return gcdext<To1_Policy, To2_Policy, To3_Policy, From1_Policy, From2_Policy>(to, s, t, x, y, dir);
875 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
879 if (is_nan<From1_Policy>(x) || is_nan<From2_Policy>(y)) {
882 else if (is_minf<From1_Policy>(x) || is_pinf<From1_Policy>(x)
883 || is_minf<From2_Policy>(y) || is_pinf<From2_Policy>(y)) {
887 return lcm<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
891 template <
typename Policy1,
typename Policy2,
892 typename Type1,
typename Type2>
895 if (!ext_to_handle<Policy1>(x) && !ext_to_handle<Policy2>(y)) {
898 if (is_nan<Policy1>(x) || is_nan<Policy2>(y)) {
901 else if (is_minf<Policy1>(x)) {
904 else if (is_pinf<Policy1>(x)) {
908 if (is_minf<Policy2>(y)) {
911 if (is_pinf<Policy2>(y)) {
915 return cmp<Policy1, Policy2>(x, y);
919 template <
typename Policy1,
typename Policy2,
920 typename Type1,
typename Type2>
923 if (!ext_to_handle<Policy1>(x) && !ext_to_handle<Policy2>(y)) {
926 if (is_nan<Policy1>(x) || is_nan<Policy2>(y)) {
929 if (is_pinf<Policy1>(x) || is_minf<Policy2>(y)) {
932 if (is_minf<Policy1>(x) || is_pinf<Policy2>(y)) {
936 return lt_p<Policy1, Policy2>(x, y);
939 template <
typename Policy1,
typename Policy2,
940 typename Type1,
typename Type2>
943 return lt_ext<Policy1, Policy2>(y, x);
946 template <
typename Policy1,
typename Policy2,
947 typename Type1,
typename Type2>
950 if (!ext_to_handle<Policy1>(x) && !ext_to_handle<Policy2>(y)) {
953 if (is_nan<Policy1>(x) || is_nan<Policy2>(y)) {
956 if (is_minf<Policy1>(x) || is_pinf<Policy2>(y)) {
959 if (is_pinf<Policy1>(x) || is_minf<Policy2>(y)) {
963 return le_p<Policy1, Policy2>(x, y);
966 template <
typename Policy1,
typename Policy2,
967 typename Type1,
typename Type2>
970 return le_ext<Policy1, Policy2>(y, x);
973 template <
typename Policy1,
typename Policy2,
974 typename Type1,
typename Type2>
977 if (!ext_to_handle<Policy1>(x) && !ext_to_handle<Policy2>(y)) {
980 if (is_nan<Policy1>(x) || is_nan<Policy2>(y)) {
983 if (is_minf<Policy1>(x)) {
984 return is_minf<Policy2>(y);
986 if (is_pinf<Policy1>(x)) {
987 return is_pinf<Policy2>(y);
989 else if (is_minf<Policy2>(y) || is_pinf<Policy2>(y)) {
993 return eq_p<Policy1, Policy2>(x, y);
996 template <
typename Policy1,
typename Policy2,
997 typename Type1,
typename Type2>
1000 return !eq_ext<Policy1, Policy2>(x, y);
1003 template <
typename Policy,
typename Type>
1007 if (!ext_to_handle<Policy>(x)) {
1010 if (is_nan<Policy>(x)) {
1014 if (is_minf<Policy>(x)) {
1018 if (is_pinf<Policy>(x)) {
1023 return output<Policy>(os, x, format, dir);
1026 template <
typename To_Policy,
typename To>
1029 return input<To_Policy>(to, is, dir);
1036 #endif // !defined(PPL_checked_ext_defs_hh)
Result gcd_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
The computed result is exact.
Taking the square root of a negative number.
Result sub_mul_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Result lcm_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Result sqrt_ext(To &to, const From &x, Rounding_Dir dir)
Result sub_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Result mul_2exp_ext(To &to, const From &x, unsigned int exp, Rounding_Dir dir)
Rounding_Dir
Rounding directions for arithmetic computations.
Result construct_ext(To &to, const From &x, Rounding_Dir dir)
Result add_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Result
Possible outcomes of a checked arithmetic computation.
From bool Type Type Rounding_Dir To
Result output_ext(std::ostream &os, const Type &x, const Numeric_Format &format, Rounding_Dir dir)
Result trunc_ext(To &to, const From &x, Rounding_Dir dir)
Result add_mul_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Negative infinity result class.
Not a number result class.
signed signed signed signed signed char signed signed signed signed signed int signed long long
Result sgn_ext(const Type &x)
Result neg_ext(To &to, const From &x, Rounding_Dir dir)
Result idiv_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Taking the modulus of an infinity.
bool ext_to_handle(const Type &x)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir Rounding_Dir To2
bool handle_ext_natively(const T &)
Positive infinity result class.
Result div_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Result mul_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
A class holding a constant called value that evaluates to true.
Equal. This need to be accompanied by a value.
Less than. This need to be accompanied by a value.
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir Rounding_Dir To1
Result add_2exp_ext(To &to, const From &x, unsigned int exp, Rounding_Dir dir)
bool ne_ext(const Type1 &x, const Type2 &y)
bool eq_ext(const Type1 &x, const Type2 &y)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir From1
Result ceil_ext(To &to, const From &x, Rounding_Dir dir)
Result sub_2exp_ext(To &to, const From &x, unsigned int exp, Rounding_Dir dir)
The entire library is confined to this namespace.
Adding two infinities having opposite signs.
Greater than. This need to be accompanied by a value.
Result gcdext_ext(To1 &to, To2 &s, To3 &t, const From1 &x, const From2 &y, Rounding_Dir dir)
Result abs_ext(To &to, const From &x, Rounding_Dir dir)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir From2
bool lt_ext(const Type1 &x, const Type2 &y)
Subtracting two infinities having the same sign.
From bool Type Type Rounding_Dir From
Result cmp_ext(const Type1 &x, const Type2 &y)
No values satisfies the relation.
Result input_ext(Type &x, std::istream &is, Rounding_Dir dir)
Result assign_ext(To &to, const From &from, Rounding_Dir dir)
Result smod_2exp_ext(To &to, const From &x, unsigned int exp, Rounding_Dir dir)
bool le_ext(const Type1 &x, const Type2 &y)
#define CHECK_P(cond, check)
bool gt_ext(const Type1 &x, const Type2 &y)
Multiplying an infinity by zero.
A class holding a constant called value that evaluates to false.
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir unsigned Rounding_Dir Rounding_Dir To3
Result rem_ext(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
bool ge_ext(const Type1 &x, const Type2 &y)
Result div_2exp_ext(To &to, const From &x, unsigned int exp, Rounding_Dir dir)
Result umod_2exp_ext(To &to, const From &x, unsigned int exp, Rounding_Dir dir)
Result floor_ext(To &to, const From &x, Rounding_Dir dir)