24 #ifndef PPL_checked_int_inlines_hh
25 #define PPL_checked_int_inlines_hh 1
33 #if !PPL_HAVE_DECL_STRTOLL
35 strtoll(
const char* nptr,
char** endptr,
int base);
38 #if !PPL_HAVE_DECL_STRTOULL
40 strtoull(
const char* nptr,
char** endptr,
int base);
47 #ifndef PPL_HAVE_INT_FAST16_T
51 #ifndef PPL_HAVE_INT_FAST32_T
55 #ifndef PPL_HAVE_INT_FAST64_T
59 #ifndef PPL_HAVE_UINT_FAST16_T
63 #ifndef PPL_HAVE_UINT_FAST32_T
67 #ifndef PPL_HAVE_UINT_FAST64_T
71 template <
typename Policy,
typename Type>
85 : ((Policy::has_infinity ? 1 : 0) + (Policy::has_nan ? 1 : 0))));
88 - ((C_Integer<Type>::min >= 0)
89 ? (2 * (Policy::has_infinity ? 1 : 0) + (Policy::has_nan ? 1 : 0))
90 : (Policy::has_infinity ? 1 : 0)));
93 template <
typename Policy,
typename To>
101 if (Policy::has_infinity) {
109 template <
typename Policy,
typename To>
117 if (Policy::has_infinity) {
125 template <
typename Policy,
typename To>
135 template <
typename Policy,
typename To>
145 template <
typename Policy,
typename To>
150 if (Policy::has_infinity) {
164 template <
typename Policy,
typename To>
169 if (Policy::has_infinity) {
195 template <typename Policy, typename
Type>
206 if (Policy::has_infinity) {
238 template <typename Policy, typename
Type>
256 template <typename Policy, typename
Type>
259 return Policy::has_infinity
275 template <typename Policy, typename
Type>
278 return Policy::has_infinity
294 template <typename Policy, typename
Type>
297 return !is_nan<Policy>(v);
312 template <typename Policy, typename
Type>
318 if (Policy::has_nan) {
324 if (Policy::has_infinity) {
334 if (Policy::has_infinity) {
361 template <typename To_Policy, typename From_Policy, typename
To, typename
From>
364 if (
sizeof(To) <
sizeof(
From)
365 || (
sizeof(To) ==
sizeof(
From)
368 if (
CHECK_P(To_Policy::check_overflow,
371 return set_neg_overflow_int<To_Policy>(to, dir);
373 if (
CHECK_P(To_Policy::check_overflow,
376 return set_pos_overflow_int<To_Policy>(to, dir);
379 to =
static_cast<To
>(from);
383 template <
typename To_Policy,
typename From_Policy,
typename To,
typename From>
386 if (
sizeof(
To) <=
sizeof(
From)) {
387 if (
CHECK_P(To_Policy::check_overflow,
389 return set_pos_overflow_int<To_Policy>(to, dir);
392 to =
static_cast<To>(from);
396 template <
typename To_Policy,
typename From_Policy,
typename To,
typename From>
399 if (
CHECK_P(To_Policy::check_overflow, from < 0)) {
400 return set_neg_overflow_int<To_Policy>(to, dir);
402 if (
sizeof(
To) <
sizeof(
From)) {
403 if (
CHECK_P(To_Policy::check_overflow,
405 return set_pos_overflow_int<To_Policy>(to, dir);
408 to =
static_cast<To>(from);
412 template <
typename To_Policy,
typename From_Policy,
typename To,
typename From>
415 if (
sizeof(
To) <
sizeof(
From)
416 || (
sizeof(
To) ==
sizeof(
From)
418 if (
CHECK_P(To_Policy::check_overflow,
421 return set_pos_overflow_int<To_Policy>(to, dir);
424 to =
static_cast<To>(from);
429 #define PPL_ASSIGN2_SIGNED_SIGNED(Smaller, Larger) \
430 PPL_SPECIALIZE_ASSIGN(assign_signed_int_signed_int, Smaller, Larger) \
431 PPL_SPECIALIZE_ASSIGN(assign_signed_int_signed_int, Larger, Smaller)
433 #define PPL_ASSIGN2_UNSIGNED_UNSIGNED(Smaller, Larger) \
434 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_unsigned_int, Smaller, Larger) \
435 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_unsigned_int, Larger, Smaller)
437 #define PPL_ASSIGN2_UNSIGNED_SIGNED(Smaller, Larger) \
438 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_signed_int, Smaller, Larger) \
439 PPL_SPECIALIZE_ASSIGN(assign_signed_int_unsigned_int, Larger, Smaller)
441 #define PPL_ASSIGN2_SIGNED_UNSIGNED(Smaller, Larger) \
442 PPL_SPECIALIZE_ASSIGN(assign_signed_int_unsigned_int, Smaller, Larger) \
443 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_signed_int, Larger, Smaller)
445 #define PPL_ASSIGN_SIGNED(Type) \
446 PPL_SPECIALIZE_ASSIGN(assign_signed_int_signed_int, Type, Type)
447 #define PPL_ASSIGN_UNSIGNED(Type) \
448 PPL_SPECIALIZE_ASSIGN(assign_unsigned_int_unsigned_int, Type, Type)
450 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
458 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
467 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
483 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
499 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
515 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
540 template <
typename To_Policy,
typename From_Policy,
typename To,
typename From>
543 if (is_nan<From_Policy>(from)) {
546 else if (is_minf<From_Policy>(from)) {
549 else if (is_pinf<From_Policy>(from)) {
556 if (
CHECK_P(To_Policy::check_overflow,
558 return set_neg_overflow_int<To_Policy>(to, dir);
560 if (
CHECK_P(To_Policy::check_overflow,
562 return set_pos_overflow_int<To_Policy>(to, dir);
565 if (
CHECK_P(To_Policy::check_overflow,
567 return set_neg_overflow_int<To_Policy>(to, dir);
569 if (
CHECK_P(To_Policy::check_overflow,
571 return set_pos_overflow_int<To_Policy>(to, dir);
578 From i_from = rint(from);
580 if (from == i_from) {
584 return round_lt_int<To_Policy>(to, dir);
587 return round_gt_int<To_Policy>(to, dir);
590 return round_lt_int<To_Policy>(to, dir);
592 PPL_ASSERT(from > i_from);
593 return round_gt_int<To_Policy>(to, dir);
632 #undef PPL_ASSIGN_SIGNED
633 #undef PPL_ASSIGN_UNSIGNED
634 #undef PPL_ASSIGN2_SIGNED_SIGNED
635 #undef PPL_ASSIGN2_UNSIGNED_UNSIGNED
636 #undef PPL_ASSIGN2_UNSIGNED_SIGNED
637 #undef PPL_ASSIGN2_SIGNED_UNSIGNED
639 template <
typename To_Policy,
typename From_Policy,
typename To>
642 if (
sizeof(
To) <=
sizeof(
signed long)) {
643 if (!To_Policy::check_overflow) {
647 if (from.fits_slong_p()) {
648 signed long v = from.get_si();
650 return set_neg_overflow_int<To_Policy>(to, dir);
653 return set_pos_overflow_int<To_Policy>(to, dir);
660 mpz_srcptr m = from.get_mpz_t();
661 size_t sz = mpz_size(m);
662 if (sz <=
sizeof(
To) /
sizeof(mp_limb_t)) {
668 mpz_export(&v, 0, -1,
sizeof(
To), 0, 0, m);
670 if (::
sgn(from) < 0) {
671 return neg<To_Policy, To_Policy>(to, v, dir);
678 return (::
sgn(from) < 0)
679 ? set_neg_overflow_int<To_Policy>(to, dir)
680 : set_pos_overflow_int<To_Policy>(to, dir);
683 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
692 template <typename To_Policy, typename From_Policy, typename
To>
695 if (
CHECK_P(To_Policy::check_overflow, ::
sgn(from) < 0)) {
696 return set_neg_overflow_int<To_Policy>(to, dir);
698 if (
sizeof(
To) <=
sizeof(
unsigned long)) {
699 if (!To_Policy::check_overflow) {
700 to =
static_cast<To>(from.get_ui());
703 if (from.fits_ulong_p()) {
704 const unsigned long v = from.get_ui();
706 return set_pos_overflow_int<To_Policy>(to, dir);
708 to =
static_cast<To>(v);
713 const mpz_srcptr m = from.get_mpz_t();
714 const size_t sz = mpz_size(m);
715 if (sz <=
sizeof(
To) /
sizeof(mp_limb_t)) {
720 mpz_export(&to, 0, -1,
sizeof(
To), 0, 0, m);
725 return set_pos_overflow_int<To_Policy>(to, dir);
728 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
737 template <typename To_Policy, typename From_Policy, typename
To>
740 mpz_srcptr n = from.get_num().get_mpz_t();
741 mpz_srcptr d = from.get_den().get_mpz_t();
743 mpz_ptr q_z = q.get_mpz_t();
745 mpz_tdiv_q(q_z, n, d);
746 Result r = assign<To_Policy, void>(to, q, dir);
755 mpz_tdiv_qr(q_z, rem, n, d);
758 Result r = assign<To_Policy, void>(to, q, dir);
764 return round_lt_int<To_Policy>(to, dir);
766 return round_gt_int<To_Policy>(to, dir);
785 #error "Only two's complement is supported"
788 #if UCHAR_MAX == 0xff
791 #error "Unexpected max for unsigned char"
794 #if USHRT_MAX == 0xffff
797 #error "Unexpected max for unsigned short"
800 #if UINT_MAX == 0xffffffff
803 #error "Unexpected max for unsigned int"
806 #if ULONG_MAX == 0xffffffffUL
808 #elif ULONG_MAX == 0xffffffffffffffffULL
811 #error "Unexpected max for unsigned long"
814 #if ULLONG_MAX == 0xffffffffffffffffULL
815 #define LONG_LONG_BITS 64
817 #error "Unexpected max for unsigned long long"
821 template <
typename T>
962 template <
typename To_Policy,
typename From_Policy,
typename Type>
967 return assign<To_Policy, To_Policy>(to, l, dir);
970 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
976 return assign<To_Policy, To_Policy>(to, l, dir);
979 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
985 return assign<To_Policy, To_Policy>(to, l, dir);
988 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
994 return assign<To_Policy, To_Policy>(to, l, dir);
997 template <
typename To_Policy,
typename From_Policy,
typename Type>
1001 return neg_int_larger<To_Policy, From_Policy>(to, from, dir);
1003 if (
CHECK_P(To_Policy::check_overflow,
1005 return set_pos_overflow_int<To_Policy>(to, dir);
1011 template <
typename To_Policy,
typename From_Policy,
typename Type>
1015 return neg_int_larger<To_Policy, From_Policy>(to, from, dir);
1017 if (
CHECK_P(To_Policy::check_overflow, from != 0)) {
1018 return set_neg_overflow_int<To_Policy>(to, dir);
1024 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1029 return add_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1031 if (To_Policy::check_overflow) {
1034 return set_pos_overflow_int<To_Policy>(to, dir);
1038 return set_neg_overflow_int<To_Policy>(to, dir);
1045 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1050 return add_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1052 if (
CHECK_P(To_Policy::check_overflow,
1054 return set_pos_overflow_int<To_Policy>(to, dir);
1060 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1065 return sub_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1067 if (To_Policy::check_overflow) {
1070 return set_neg_overflow_int<To_Policy>(to, dir);
1074 return set_pos_overflow_int<To_Policy>(to, dir);
1081 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1086 return sub_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1088 if (
CHECK_P(To_Policy::check_overflow,
1090 return set_neg_overflow_int<To_Policy>(to, dir);
1096 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1101 return mul_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1103 if (!To_Policy::check_overflow) {
1112 return neg_signed_int<To_Policy, From1_Policy>(to, x, dir);
1117 return set_pos_overflow_int<To_Policy>(to, dir);
1122 return set_neg_overflow_int<To_Policy>(to, dir);
1129 return set_pos_overflow_int<To_Policy>(to, dir);
1134 return set_neg_overflow_int<To_Policy>(to, dir);
1142 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1147 return mul_int_larger<To_Policy, From1_Policy, From2_Policy>(to, x, y, dir);
1149 if (!To_Policy::check_overflow) {
1158 return set_pos_overflow_int<To_Policy>(to, dir);
1164 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1168 if (
CHECK_P(To_Policy::check_div_zero, y == 0)) {
1169 return assign_nan<To_Policy>(to,
V_DIV_ZERO);
1171 if (To_Policy::check_overflow && y == -1) {
1172 return neg_signed_int<To_Policy, From1_Policy>(to, x, dir);
1183 return round_lt_int_no_overflow<To_Policy>(to, dir);
1186 return round_gt_int_no_overflow<To_Policy>(to, dir);
1193 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1197 if (
CHECK_P(To_Policy::check_div_zero, y == 0)) {
1198 return assign_nan<To_Policy>(to,
V_DIV_ZERO);
1208 return round_gt_int<To_Policy>(to, dir);
1211 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1215 if (
CHECK_P(To_Policy::check_div_zero, y == 0)) {
1216 return assign_nan<To_Policy>(to,
V_DIV_ZERO);
1218 if (To_Policy::check_overflow && y == -1) {
1219 return neg_signed_int<To_Policy, From1_Policy>(to, x, dir);
1225 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1229 if (
CHECK_P(To_Policy::check_div_zero, y == 0)) {
1230 return assign_nan<To_Policy>(to,
V_DIV_ZERO);
1236 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1240 if (
CHECK_P(To_Policy::check_div_zero, y == 0)) {
1241 return assign_nan<To_Policy>(to,
V_MOD_ZERO);
1243 to = (y == -1) ? 0 : (x % y);
1247 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1251 if (
CHECK_P(To_Policy::check_div_zero, y == 0)) {
1252 return assign_nan<To_Policy>(to,
V_MOD_ZERO);
1258 template <
typename To_Policy,
typename From_Policy,
typename Type>
1270 return round_gt_int_no_overflow<To_Policy>(to, dir);
1276 if (x & ((
Type(1) << exp) - 1)) {
1277 return round_gt_int_no_overflow<To_Policy>(to, dir);
1284 template <
typename To_Policy,
typename From_Policy,
typename Type>
1294 return round_lt_int_no_overflow<To_Policy>(to, dir);
1299 to = ~
Type(~-(ux >> exp));
1303 if (ux & ((UType(1) << exp) -1)) {
1304 return round_lt_int_no_overflow<To_Policy>(to, dir);
1317 return round_gt_int_no_overflow<To_Policy>(to, dir);
1323 if (x & ((
Type(1) << exp) - 1)) {
1324 return round_gt_int_no_overflow<To_Policy>(to, dir);
1332 template <
typename To_Policy,
typename From_Policy,
typename Type>
1336 if (!To_Policy::check_overflow) {
1337 to = x + (
Type(1) << exp);
1341 return set_pos_overflow_int<To_Policy>(to, dir);
1344 return add_unsigned_int<To_Policy, From_Policy, void>(to, x, n, dir);
1347 template <
typename To_Policy,
typename From_Policy,
typename Type>
1351 if (!To_Policy::check_overflow) {
1352 to = x + (
Type(1) << exp);
1356 return set_pos_overflow_int<To_Policy>(to, dir);
1359 Type n = -2 * (
Type(1) << (exp - 1));
1360 return sub_signed_int<To_Policy, From_Policy, void>(to, x, n, dir);
1364 return add_signed_int<To_Policy, From_Policy, void>(to, x, n, dir);
1368 template <
typename To_Policy,
typename From_Policy,
typename Type>
1372 if (!To_Policy::check_overflow) {
1373 to = x - (
Type(1) << exp);
1377 return set_neg_overflow_int<To_Policy>(to, dir);
1380 return sub_unsigned_int<To_Policy, From_Policy, void>(to, x, n, dir);
1383 template <
typename To_Policy,
typename From_Policy,
typename Type>
1387 if (!To_Policy::check_overflow) {
1388 to = x - (
Type(1) << exp);
1392 return set_neg_overflow_int<To_Policy>(to, dir);
1395 Type n = -2 * (
Type(1) << (exp - 1));
1396 return add_signed_int<To_Policy, From_Policy, void>(to, x, n, dir);
1400 return sub_signed_int<To_Policy, From_Policy, void>(to, x, n, dir);
1404 template <
typename To_Policy,
typename From_Policy,
typename Type>
1408 if (!To_Policy::check_overflow) {
1417 return set_pos_overflow_int<To_Policy>(to, dir);
1420 return set_pos_overflow_int<To_Policy>(to, dir);
1426 template <
typename To_Policy,
typename From_Policy,
typename Type>
1431 if (!To_Policy::check_overflow) {
1432 to = x * (
Type(1) << exp);
1436 return set_neg_overflow_int<To_Policy>(to, dir);
1441 if ((ux & mask) != mask) {
1442 return set_neg_overflow_int<To_Policy>(to, dir);
1447 return set_neg_overflow_int<To_Policy>(to, dir);
1452 if (!To_Policy::check_overflow) {
1461 return set_pos_overflow_int<To_Policy>(to, dir);
1464 return set_pos_overflow_int<To_Policy>(to, dir);
1471 template <
typename To_Policy,
typename From_Policy,
typename Type>
1480 if (v >= (
Type(1) << (exp - 1))) {
1481 return set_neg_overflow_int<To_Policy>(to, dir);
1490 template <
typename To_Policy,
typename From_Policy,
typename Type>
1499 to = (x & (m - 1)) - (x & m);
1504 template <
typename To_Policy,
typename From_Policy,
typename Type>
1512 to = x & ((
Type(1) << exp) - 1);
1517 template <
typename To_Policy,
typename From_Policy,
typename Type>
1523 return set_pos_overflow_int<To_Policy>(to, dir);
1528 to = x & ((
Type(1) << exp) - 1);
1533 template <
typename Type>
1549 template <
typename To_Policy,
typename From_Policy,
typename Type>
1560 return round_gt_int<To_Policy>(to, dir);
1563 template <
typename To_Policy,
typename From_Policy,
typename Type>
1566 if (
CHECK_P(To_Policy::check_sqrt_neg, from < 0)) {
1567 return assign_nan<To_Policy>(to,
V_SQRT_NEG);
1569 return sqrt_unsigned_int<To_Policy, From_Policy>(to, from, dir);
1572 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1577 Result r = mul<To_Policy, From1_Policy, From2_Policy>(z, x, y, dir);
1580 return add<To_Policy, To_Policy, To_Policy>(to, to, z, dir);
1583 return set_neg_overflow_int<To_Policy>(to, dir);
1588 return set_pos_overflow_int<To_Policy>(to, dir);
1597 template <
typename To_Policy,
typename From1_Policy,
typename From2_Policy,
1602 Result r = mul<To_Policy, From1_Policy, From2_Policy>(z, x, y, dir);
1605 return sub<To_Policy, To_Policy, To_Policy>(to, to, z, dir);
1608 return set_pos_overflow_int<To_Policy>(to, dir);
1613 return set_neg_overflow_int<To_Policy>(to, dir);
1622 template <
typename Policy,
typename Type>
1630 template <
typename Policy,
typename Type>
1637 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1645 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1654 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1662 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1671 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1679 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1688 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1696 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1705 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1713 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1722 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1730 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1739 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1747 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1756 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1764 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1773 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1781 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1790 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1798 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1807 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1815 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1824 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1832 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1841 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1849 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1858 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1866 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1875 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1883 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1892 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1900 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1909 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1917 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1926 #if PPL_CXX_PLAIN_CHAR_IS_SIGNED
1934 #if !PPL_CXX_PLAIN_CHAR_IS_SIGNED
1953 PPL_SPECIALIZE_GCD(gcd_exact,
unsigned long long,
unsigned long long,
unsigned long long)
1956 char,
char,
char,
char,
char)
1958 signed char,
signed char,
signed char,
1959 signed char,
signed char)
1961 signed short,
signed short,
signed short,
1962 signed short,
signed short)
1964 signed int,
signed int,
signed int,
1965 signed int,
signed int)
1967 signed long,
signed long,
signed long,
1968 signed long,
signed long)
1970 signed long long,
signed long long,
signed long long,
1971 signed long long,
signed long long)
1973 unsigned char,
unsigned char,
unsigned char,
1974 unsigned char,
unsigned char)
1976 unsigned short,
unsigned short,
unsigned short,
1977 unsigned short,
unsigned short)
1979 unsigned int,
unsigned int,
unsigned int,
1980 unsigned int,
unsigned int)
1982 unsigned long,
unsigned long,
unsigned long,
1983 unsigned long,
unsigned long)
1985 unsigned long long,
unsigned long long,
1986 unsigned long long,
unsigned long long,
1994 PPL_SPECIALIZE_LCM(lcm_gcd_exact,
signed long long,
signed long long,
signed long long)
1999 PPL_SPECIALIZE_LCM(lcm_gcd_exact,
unsigned long long,
unsigned long long,
unsigned long long)
2077 #endif // !defined(PPL_checked_int_inlines_hh)
A positive integer overflow occurred (rounding down).
int_fast64_t type_for_sub
int result_overflow(Result r)
Result smod_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result assign_unsigned_int_unsigned_int(To &to, const From from, Rounding_Dir dir)
int_fast16_t type_for_neg
#define PPL_SPECIALIZE_NEG(func, To, From)
Result sub_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
bool is_int_int(const Type v)
#define PPL_ASSIGN2_SIGNED_SIGNED(Smaller, Larger)
int_fast32_t type_for_neg
The computed result is exact.
Taking the square root of a negative number.
int_fast16_t type_for_neg
Result add_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
#define PPL_SPECIALIZE_ADD_MUL(func, To, From1, From2)
#define PPL_SPECIALIZE_IS_MINF(func, Type)
Result output_int(std::ostream &os, Type &from, const Numeric_Format &, Rounding_Dir)
int_fast32_t type_for_mul
int_fast32_t type_for_neg
Result output_char(std::ostream &os, Type &from, const Numeric_Format &, Rounding_Dir)
uint_fast16_t type_for_mul
uint_fast64_t type_for_mul
Unknown result due to intermediate positive overflow.
#define PPL_ASSIGN2_UNSIGNED_UNSIGNED(Smaller, Larger)
static const Type plus_infinity
static const Type minus_infinity
Rounding_Dir
Rounding directions for arithmetic computations.
int_fast64_t type_for_neg
#define PPL_SPECIALIZE_SQRT(func, To, From)
A positive integer overflow occurred (rounding up).
Result add_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
int_fast64_t type_for_mul
uint_fast64_t type_for_mul
int_fast64_t type_for_mul
int_fast64_t type_for_mul
uint_fast16_t type_for_add
void isqrt_rem(Type &q, Type &r, const Type from)
Computing a remainder modulo zero.
#define PPL_SPECIALIZE_CLASSIFY(func, Type)
#define PPL_SPECIALIZE_ADD(func, To, From1, From2)
Result assign_unsigned_int_mpz(To &to, const mpz_class &from, Rounding_Dir dir)
Result add_mul_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_ASSIGN_UNSIGNED(Type)
int_fast64_t type_for_neg
Result
Possible outcomes of a checked arithmetic computation.
#define const_bool_nodef(name, value)
Declares a per-class constant of type bool, called name and with value value.
From bool Type Type Rounding_Dir To
#define PPL_SPECIALIZE_REM(func, To, From1, From2)
Negative infinity result class.
Not a number result class.
Result set_pos_overflow_int(To &to, Rounding_Dir dir)
Result add_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result round_gt_int_no_overflow(To &to, Rounding_Dir dir)
Result round_gt_int(To &to, Rounding_Dir dir)
uint_fast64_t type_for_add
signed signed signed signed signed char signed signed signed signed signed int signed long long
Result gcdext_exact(To1 &to, To2 &s, To3 &t, const From1 &x, const From2 &y, Rounding_Dir dir)
Result assign_int_mpq(To &to, const mpq_class &from, Rounding_Dir dir)
Result umod_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir)
#define PPL_SPECIALIZE_ABS(func, To, From)
int_fast16_t type_for_mul
Result mul_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
Result input_generic(Type &to, std::istream &is, Rounding_Dir dir)
#define PPL_SPECIALIZE_UMOD_2EXP(func, To, From)
PPL_SPECIALIZE_GCDEXT(gcdext_exact, char, char, char, char, char) PPL_SPECIALIZE_GCDEXT(gcdext_exact
The computed result is inexact and rounded down.
#define PPL_SPECIALIZE_TRUNC(func, To, From)
#define PPL_SPECIALIZE_CMP(func, Type1, Type2)
#define PPL_SPECIALIZE_CEIL(func, To, From)
#define PPL_SPECIALIZE_DIV(func, To, From1, From2)
Result classify_int(const Type v, bool nan, bool inf, bool sign)
int_fast64_t type_for_sub
int_fast64_t type_for_neg
Enable_If<(Safe_Int_Comparison< T1, T2 >::value||Safe_Conversion< T1, T2 >::value||Safe_Conversion< T2, T1 >::value), bool >::type lt(const T1 &x, const T2 &y)
int_fast32_t type_for_sub
uint_fast64_t type_for_mul
#define PPL_SPECIALIZE_IDIV(func, To, From1, From2)
#define PPL_SPECIALIZE_MUL_2EXP(func, To, From)
Result div_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
Positive infinity result class.
Result assign_signed_int_unsigned_int(To &to, const From from, Rounding_Dir dir)
int_fast64_t type_for_add
Result mul_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Unknown result due to intermediate negative overflow.
The computed result is not representable.
int_fast64_t type_for_sub
Result idiv_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_SPECIALIZE_SUB(func, To, From1, From2)
#define PPL_SPECIALIZE_ASSIGN_SPECIAL(func, Type)
int_fast16_t type_for_neg
Negative infinity result.
From bool Type Type Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir Rounding_Dir unsigned int
Result neg_int_larger(Type &to, const Type x, Rounding_Dir dir)
#define sizeof_to_bits(size)
Result add_int_larger(Type &to, const Type x, const Type y, Rounding_Dir dir)
bool is_pinf_int(const Type v)
int_fast64_t type_for_sub
int_fast64_t type_for_add
Result round_lt_int(To &to, Rounding_Dir dir)
Result gcd_exact(To &to, const From1 &x, const From2 &y, Rounding_Dir dir)
bool round_up(Rounding_Dir dir)
#define PPL_SPECIALIZE_ADD_2EXP(func, To, From)
int_fast16_t type_for_add
#define PPL_SPECIALIZE_GCD(func, To, From1, From2)
Result rem_signed_int(Type &to, const Type x, const Type y, Rounding_Dir)
Result sqrt_signed_int(Type &to, const Type from, Rounding_Dir dir)
uint_fast64_t type_for_add
#define PPL_SPECIALIZE_SUB_MUL(func, To, From1, From2)
int_fast16_t type_for_sub
Result umod_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result idiv_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir)
The computed result may be inexact and rounded up.
#define PPL_DIRTY_TEMP(T, id)
#define PPL_SPECIALIZE_IS_INT(func, Type)
Result assign_special_int(Type &v, Result_Class c, Rounding_Dir dir)
#define PPL_SPECIALIZE_FLOOR(func, To, From)
Result div_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result mul_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
Result sub_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
static const Type not_a_number
unsigned long long strtoull(const char *nptr, char **endptr, int base)
Result neg_signed_int(Type &to, const Type from, Rounding_Dir dir)
uint_fast64_t type_for_add
Result mul_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
Result add_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
The entire library is confined to this namespace.
#define PPL_SPECIALIZE_DIV_2EXP(func, To, From)
int_fast16_t type_for_add
Enable_If< Is_Same< To_Policy, From_Policy >::value, void >::type copy_generic(Type &to, const Type &from)
bool round_direct(Rounding_Dir dir)
int_fast16_t type_for_mul
Result_Relation sgn_generic(const Type &x)
int_fast64_t type_for_neg
Result sqrt_unsigned_int(Type &to, const Type from, Rounding_Dir dir)
int_fast16_t type_for_sub
The computed result may be inexact and rounded down.
Result assign_signed_int_signed_int(To &to, const From from, Rounding_Dir dir)
Result div_2exp_unsigned_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
From bool Type Type Rounding_Dir From
#define PPL_GT_SILENT(a, b)
Result smod_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir)
Result assign_unsigned_int_signed_int(To &to, const From from, Rounding_Dir dir)
#define PPL_SPECIALIZE_IS_NAN(func, Type)
uint_fast32_t type_for_add
Result round_lt_int_no_overflow(To &to, Rounding_Dir dir)
#define PPL_ASSIGN2_UNSIGNED_SIGNED(Smaller, Larger)
int_fast16_t type_for_sub
int sgn(Boundary_Type type, const T &x, const Info &info)
Result mul_int_larger(Type &to, const Type x, const Type y, Rounding_Dir dir)
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)
signed long long strtoll(const char *nptr, char **endptr, int base)
#define PPL_SPECIALIZE_ASSIGN(func, To, From)
Positive infinity result.
int_fast64_t type_for_neg
#define PPL_SPECIALIZE_SUB_2EXP(func, To, From)
int_fast64_t type_for_neg
#define PPL_SPECIALIZE_COPY(func, Type)
A negative integer overflow occurred (rounding down).
#define PPL_ASSIGN2_SIGNED_UNSIGNED(Smaller, Larger)
#define PPL_SPECIALIZE_LCM(func, To, From1, From2)
int_fast32_t type_for_sub
#define CHECK_P(cond, check)
bool is_minf_int(const Type v)
Result div_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
Result sub_int_larger(Type &to, const Type x, const Type y, Rounding_Dir dir)
int_fast64_t type_for_sub
int_fast32_t type_for_add
#define PPL_SPECIALIZE_OUTPUT(func, Type)
int_fast64_t type_for_sub
The computed result is inexact and rounded up.
int_fast64_t type_for_add
The computed result may be inexact.
Result assign_int_float(To &to, const From from, Rounding_Dir dir)
Result set_neg_overflow_int(To &to, Rounding_Dir dir)
Result sub_signed_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
uint_fast32_t type_for_mul
#define PPL_SPECIALIZE_INPUT(func, Type)
bool round_down(Rounding_Dir dir)
Result assign_signed_int_mpz(To &to, const mpz_class &from, Rounding_Dir dir)
Result rem_unsigned_int(Type &to, const Type x, const Type y, Rounding_Dir)
#define PPL_SPECIALIZE_SMOD_2EXP(func, To, From)
#define PPL_LT_SILENT(a, b)
Performs the test a < b avoiding the warning about the comparison being always false due to limited r...
bool round_not_requested(Rounding_Dir dir)
Result_Relation cmp_generic(const Type1 &x, const Type2 &y)
#define PPL_ASSIGN_SIGNED(Type)
A negative integer overflow occurred (rounding up).
Result sub_2exp_signed_int(Type &to, const Type x, unsigned int exp, Rounding_Dir dir)
#define PPL_SPECIALIZE_MUL(func, To, From1, From2)
Result neg_unsigned_int(Type &to, const Type from, Rounding_Dir dir)
Result sub_mul_int(Type &to, const Type x, const Type y, Rounding_Dir dir)
#define PPL_SPECIALIZE_IS_PINF(func, Type)
#define PPL_SPECIALIZE_SGN(func, From)
Enable_If<(Safe_Int_Comparison< T1, T2 >::value||Safe_Conversion< T1, T2 >::value||Safe_Conversion< T2, T1 >::value), bool >::type le(const T1 &x, const T2 &y)
bool is_nan_int(const Type v)