24 #ifndef PPL_checked_inlines_hh
25 #define PPL_checked_inlines_hh 1
30 #include "assertions.hh"
38 #define PPL_LT_SILENT(a, b) ((a) < (b))
39 #define PPL_GT_SILENT(a, b) ((a) > (b))
45 template <
typename T1,
typename T2>
52 #define PPL_SAFE_CONVERSION(To, From) \
53 template <> struct Safe_Conversion<PPL_U(To), PPL_U(From)> \
56 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
60 #if PPL_SIZEOF_CHAR < PPL_SIZEOF_SHORT
61 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
67 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
72 #if PPL_SIZEOF_CHAR < PPL_SIZEOF_INT
73 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
78 #if PPL_SIZEOF_SHORT < PPL_SIZEOF_INT
82 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
88 #if PPL_SIZEOF_CHAR < PPL_SIZEOF_LONG
89 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
94 #if PPL_SIZEOF_SHORT < PPL_SIZEOF_LONG
97 #if PPL_SIZEOF_INT < PPL_SIZEOF_LONG
101 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
108 #if PPL_SIZEOF_CHAR < PPL_SIZEOF_LONG_LONG
109 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
114 #if PPL_SIZEOF_SHORT < PPL_SIZEOF_LONG_LONG
117 #if PPL_SIZEOF_INT < PPL_SIZEOF_LONG_LONG
120 #if PPL_SIZEOF_LONG < PPL_SIZEOF_LONG_LONG
124 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
129 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
135 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
142 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
151 #if PPL_SIZEOF_CHAR <= PPL_SIZEOF_FLOAT - 2
156 #if PPL_SIZEOF_SHORT <= PPL_SIZEOF_FLOAT - 2
160 #if PPL_SIZEOF_INT <= PPL_SIZEOF_FLOAT - 2
164 #if PPL_SIZEOF_LONG <= PPL_SIZEOF_FLOAT - 2
168 #if PPL_SIZEOF_LONG_LONG <= PPL_SIZEOF_FLOAT - 2
173 #if PPL_SIZEOF_CHAR <= PPL_SIZEOF_DOUBLE - 4
178 #if PPL_SIZEOF_SHORT <= PPL_SIZEOF_DOUBLE - 4
182 #if PPL_SIZEOF_INT <= PPL_SIZEOF_DOUBLE - 4
186 #if PPL_SIZEOF_LONG <= PPL_SIZEOF_DOUBLE - 4
190 #if PPL_SIZEOF_LONG_LONG <= PPL_SIZEOF_DOUBLE - 4
196 #if PPL_SIZEOF_CHAR <= PPL_SIZEOF_LONG_DOUBLE - 4
201 #if PPL_SIZEOF_SHORT <= PPL_SIZEOF_LONG_DOUBLE - 4
205 #if PPL_SIZEOF_INT <= PPL_SIZEOF_LONG_DOUBLE - 4
209 #if PPL_SIZEOF_LONG <= PPL_SIZEOF_LONG_DOUBLE - 4
213 #if PPL_SIZEOF_LONG_LONG <= PPL_SIZEOF_LONG_DOUBLE - 4
247 #undef PPL_SAFE_CONVERSION
249 template <
typename Policy,
typename Type>
250 struct PPL_FUNCTION_CLASS(construct)<Policy, Policy,
Type,
Type> {
257 template <
typename To_Policy,
typename From_Policy,
typename To,
typename From>
258 struct PPL_FUNCTION_CLASS(construct) {
261 return assign<To_Policy, From_Policy>(to, from, dir);
265 template <
typename To_Policy,
typename To>
266 struct PPL_FUNCTION_CLASS(construct_special) {
269 return assign_special<To_Policy>(to, r, dir);
273 template <
typename To_Policy,
typename From_Policy,
typename To,
typename From>
280 template <
typename To_Policy,
typename From_Policy,
typename Type>
286 template <
typename To_Policy,
typename From_Policy,
typename To,
typename From>
290 return neg<To_Policy, From_Policy>(to, from, dir);
293 return assign<To_Policy, From_Policy>(to, from, dir);
297 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
298 typename To,
typename From>
308 rem<To_Policy, From1_Policy, From2_Policy>(remainder, w_x, w_y,
316 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
320 gcd_exact_no_abs<To_Policy, From1_Policy, From2_Policy>(to, x, y);
321 return abs<To_Policy, To_Policy>(to, to, dir);
324 template <
typename To1_Policy,
typename To2_Policy,
typename To3_Policy,
325 typename From1_Policy,
typename From2_Policy,
326 typename To1,
typename To2,
typename To3,
349 return abs<To1_Policy, From1_Policy>(to, x, dir);
355 bool negative_x = x < 0;
356 bool negative_y = y < 0;
359 r = abs<To1_Policy, From1_Policy>(to, x, dir);
365 r = abs<To1_Policy, From2_Policy>(a_y, y, dir);
374 #define PPL_MATCH_GMP_GCDEXT 1
375 #ifdef PPL_MATCH_GMP_GCDEXT
384 To1 v3 =
static_cast<To1
>(a_y);
389 To2 t1 = s -
static_cast<To2
>(q)*v1;
390 To3 t2 = t -
static_cast<To3
>(q)*v2;
403 #ifdef PPL_MATCH_GMP_GCDEXT
407 r = neg<To2_Policy, To2_Policy>(s, s, dir);
413 return neg<To3_Policy, To3_Policy>(t, t, dir);
416 #undef PPL_MATCH_GMP_GCDEXT
419 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
423 if (x == 0 || y == 0) {
430 r = abs<From1_Policy, From1_Policy>(a_x, x, dir);
434 r = abs<From2_Policy, From2_Policy>(a_y, y, dir);
439 gcd_exact_no_abs<To_Policy, From1_Policy, From2_Policy>(gcd, a_x, a_y);
444 return mul<To_Policy, To_Policy, From2_Policy>(to, to, a_y, dir);
447 template <
typename Policy,
typename Type>
459 template <
typename T1,
typename T2,
typename Enable =
void>
463 template <
typename T1,
typename T2>
465 :
public Bool<(C_Integer<T1>::is_signed
466 ? (C_Integer<T2>::is_signed
467 || sizeof(T2) < sizeof(T1)
468 || sizeof(T2) < sizeof(int))
469 : (!C_Integer<T2>::is_signed
470 || sizeof(T1) < sizeof(T2)
471 || sizeof(T1) < sizeof(int)))> {
475 template <typename T1, typename T2>
476 inline typename Enable_If<(Safe_Int_Comparison<T1, T2>::value
477 || Safe_Conversion<T1, T2>::value
478 || Safe_Conversion<T2, T1>::value), bool>::type
479 lt(const T1& x, const T2& y) {
482 template <typename T1, typename T2>
483 inline typename Enable_If<(Safe_Int_Comparison<T1, T2>::value
484 || Safe_Conversion<T1, T2>::value
485 || Safe_Conversion<T2, T1>::value), bool>::type
486 le(const T1& x, const T2& y) {
489 template <typename T1, typename T2>
490 inline typename Enable_If<(Safe_Int_Comparison<T1, T2>::value
491 || Safe_Conversion<T1, T2>::value
492 || Safe_Conversion<T2, T1>::value), bool>::type
493 eq(const T1& x, const T2& y) {
497 template <typename S, typename U>
498 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
499 && C_Integer<U>::value
500 && C_Integer<S>::is_signed), bool>::type
501 lt(const S& x, const U& y) {
502 return x < 0 || static_cast<typename C_Integer<S>::other_type>(x) < y;
505 template <typename U, typename S>
506 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
507 && C_Integer<U>::value
508 && C_Integer<S>::is_signed), bool>::type
509 lt(const U& x, const S& y) {
510 return y >= 0 && x < static_cast<typename C_Integer<S>::other_type>(y);
513 template <typename S, typename U>
514 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
515 && C_Integer<U>::value
516 && C_Integer<S>::is_signed), bool>::type
517 le(const S& x, const U& y) {
518 return x < 0 || static_cast<typename C_Integer<S>::other_type>(x) <= y;
521 template <typename U, typename S>
522 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
523 && C_Integer<U>::value
524 && C_Integer<S>::is_signed), bool>::type
525 le(const U& x, const S& y) {
526 return y >= 0 && x <= static_cast<typename C_Integer<S>::other_type>(y);
529 template <typename S, typename U>
530 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
531 && C_Integer<U>::value
532 && C_Integer<S>::is_signed), bool>::type
533 eq(const S& x, const U& y) {
534 return x >= 0 && static_cast<typename C_Integer<S>::other_type>(x) == y;
537 template <typename U, typename S>
538 inline typename Enable_If<(!Safe_Int_Comparison<S, U>::value
539 && C_Integer<U>::value
540 && C_Integer<S>::is_signed), bool>::type
541 eq(const U& x, const S& y) {
542 return y >= 0 && x == static_cast<typename C_Integer<S>::other_type>(y);
545 template <typename T1, typename T2>
546 inline typename Enable_If<(!Safe_Conversion<T1, T2>::value
547 && !Safe_Conversion<T2, T1>::value
548 && (!C_Integer<T1>::value || !C_Integer<T2>::value)), bool>::type
549 eq(const T1& x, const T2& y) {
550 PPL_DIRTY_TEMP(T1, tmp);
551 Result r = assign_r(tmp, y, ROUND_CHECK);
556 PPL_ASSERT(r != V_LE && r != V_GE && r != V_LGE);
557 return r == V_EQ && x == tmp;
560 template <typename T1, typename T2>
561 inline typename Enable_If<(!Safe_Conversion<T1, T2>::value
562 && !Safe_Conversion<T2, T1>::value
563 && (!C_Integer<T1>::value || !C_Integer<T2>::value)), bool>::type
564 lt(const T1& x, const T2& y) {
565 PPL_DIRTY_TEMP(T1, tmp);
566 Result r = assign_r(tmp, y, ROUND_UP);
567 if (!result_representable(r)) {
570 switch (result_relation(r)) {
580 template <typename T1, typename T2>
582 Enable_If<(!Safe_Conversion<T1, T2>::value
583 && !Safe_Conversion<T2, T1>::value
584 && (!C_Integer<T1>::value || !C_Integer<T2>::value)), bool>::type
585 le(const T1& x, const T2& y) {
586 PPL_DIRTY_TEMP(T1, tmp);
587 Result r = assign_r(tmp, y, (ROUND_UP | ROUND_STRICT_RELATION));
592 PPL_ASSERT(r != V_LE && r != V_GE && r != V_LGE);
593 if (!result_representable(r)) {
596 switch (result_relation(r)) {
612 template <typename Policy1, typename Policy2,
613 typename Type1, typename Type2>
615 lt_p(const Type1& x, const Type2& y) {
619 template <typename Policy1, typename Policy2,
620 typename Type1, typename Type2>
622 le_p(const Type1& x, const Type2& y) {
626 template <typename Policy1, typename Policy2,
627 typename Type1, typename Type2>
629 eq_p(const Type1& x, const Type2& y) {
633 template <typename Policy1, typename Policy2,
634 typename Type1, typename Type2>
635 inline Result_Relation
636 cmp_generic(const Type1& x, const Type2& y) {
646 template <typename Policy, typename Type>
648 assign_nan(Type& to, Result r) {
649 assign_special<Policy>(to, VC_NAN, ROUND_IGNORE);
653 template <typename Policy, typename Type>
655 input_generic(Type& to, std::istream& is, Rounding_Dir dir) {
656 PPL_DIRTY_TEMP(mpq_class, q);
657 Result r = input_mpq(q, is);
658 Result_Class c = result_class(r);
660 case VC_MINUS_INFINITY:
661 case VC_PLUS_INFINITY:
662 return assign_special<Policy>(to, c, dir);
664 return assign_nan<Policy>(to, r);
668 PPL_ASSERT(r == V_EQ);
669 return assign<Policy, void>(to, q, dir);
The computed result is exact.
PPL_SAFE_CONVERSION(signed short, signed char)
Rounding_Dir
Rounding directions for arithmetic computations.
Result
Possible outcomes of a checked arithmetic computation.
From bool Type Type Rounding_Dir To
Result gcdext_exact(To1 &to, To2 &s, To3 &t, const From1 &x, const From2 &y, Rounding_Dir dir)
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
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 gcd_exact(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
void gcd_exact_no_abs(To &to, const From &x, const From &y)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir From1
Result assign_exact(To &to, const From &from, Rounding_Dir)
The entire library is confined to this namespace.
Greater than. This need to be accompanied by a value.
Enable_If< Is_Same< To_Policy, From_Policy >::value, void >::type copy_generic(Type &to, const Type &from)
Result_Relation sgn_generic(const Type &x)
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir From2
From bool Type Type Rounding_Dir From
Result lcm_gcd_exact(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
Result abs_generic(To &to, const From &from, Rounding_Dir dir)
A class that provides a type member called type equivalent to T if and only if b is true...
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
A class holding a constant called value that evaluates to b.