diff --git a/src/safe_op.hpp b/src/safe_op.hpp index ed3f30f4..1ac8b9a8 100644 --- a/src/safe_op.hpp +++ b/src/safe_op.hpp @@ -114,10 +114,11 @@ namespace Safe struct fallback_add_overflow; /*! - * @brief Overload of fallback_add_overflow for signed integers + * @brief Overload of fallback_add_overflow for signed integer types + * larger then int or with the same size as int */ template - struct fallback_add_overflow::VALUE>::type> + struct fallback_add_overflow::VALUE && sizeof(T) >= sizeof(int)>::type> { /*! * @brief Adds the two summands only if no overflow occurs @@ -147,6 +148,42 @@ namespace Safe } }; + /*! + * @brief Overload of fallback_add_overflow for signed integers smaller + * then int. + */ + template + struct fallback_add_overflow::VALUE && sizeof(T) < sizeof(int)>::type> + { + /*! + * @brief Adds the two summands only if no overflow occurs + * + * This function adds summand_1 and summand_2 exploiting integer + * promotion rules, thereby not causing undefined behavior. The + * result is checked against the limits of T and true is returned if + * they are exceeded. Otherwise the sum is saved in result and false + * is returned. + * + * @return true on overflow, false on no overflow + * + * The value in result is only valid when the function returns + * false. + * + * Further information: + * https://wiki.sei.cmu.edu/confluence/display/c/INT02-C.+Understand+integer+conversion+rules + */ + static bool add(T summand_1, T summand_2, T& result) + { + const int res = summand_1 + summand_2; + if ((res > std::numeric_limits::max()) || (res < std::numeric_limits::min())) { + return true; + } else { + result = static_cast(res); + return false; + } + } + }; + /*! * @brief Overload of fallback_add_overflow for unsigned integers */