inline typename enable_if<import::is_arithmetic<Tp>, Tp>::type check_positive_add(Tp x, Tp y) { // The additional bracket is to avoid conflict with MSVC min/max macros if (((std::numeric_limits<Tp>::max)() - x) < y) { std::stringstream out; out << x << " + " << y << " caused overflow"; throw arithmetic_error(out.str()); } return x + y; }
inline typename enable_if_c <std::numeric_limits<Tp>::is_integer && std::numeric_limits<Tp>::is_signed, Tp>::type check_abs(Tp x) { if (x == (std::numeric_limits<Tp>::min)()) { std::stringstream out; out << "absolute of " << x << " caused overflow"; throw arithmetic_error(out.str()); } return std::abs(x); }
inline typename enable_if<import::is_arithmetic<Tp>, Tp>::type check_positive_mul(Tp x, Tp y) { Tp zero = Tp(); // get 0 if (x != zero) { if (((std::numeric_limits<Tp>::max)() / x) < y) { std::stringstream out; out << x << " * " << y << " caused overflow"; throw arithmetic_error(out.str()); } return x * y; } return zero; }
inline typename enable_if<import::is_arithmetic<Tp>, Tp>::type check_square(Tp x) { Tp zero = Tp(); // get 0 if (x != zero) { Tp abs = check_abs(x); if (((std::numeric_limits<Tp>::max)() / abs) < abs) { std::stringstream out; out << "square(" << x << ") caused overflow"; throw arithmetic_error(out.str()); } return x * x; } return zero; }