diff --git a/src/common/utilities.cpp b/src/common/utilities.cpp index 48adb85e3f..4ce0ae5c06 100644 --- a/src/common/utilities.cpp +++ b/src/common/utilities.cpp @@ -69,52 +69,6 @@ int levenshtein(const std::string &s1, const std::string &s2) return result; } -bool rathena::util::safe_substraction( int64 a, int64 b, int64& result ){ -#if __has_builtin( __builtin_sub_overflow ) || ( defined( __GNUC__ ) && !defined( __clang__ ) && defined( GCC_VERSION ) && GCC_VERSION >= 50100 ) - return __builtin_sub_overflow( a, b, &result ); -#else - bool overflow = false; - - if( b < 0 ){ - if( a > ( INT64_MAX + b ) ){ - overflow = true; - } - }else{ - if( a < ( INT64_MIN + b ) ){ - overflow = true; - } - } - - result = a - b; - - return overflow; -#endif -} - -bool rathena::util::safe_multiplication( int64 a, int64 b, int64& result ){ -#if __has_builtin( __builtin_mul_overflow ) || ( defined( __GNUC__ ) && !defined( __clang__ ) && defined( GCC_VERSION ) && GCC_VERSION >= 50100 ) - return __builtin_mul_overflow( a, b, &result ); -#else - result = a * b; - - if( a > 0 ){ - if( b > 0 ){ - return result < 0; - }else if( b < 0 ){ - return result > 0; - } - }else if( a < 0 ){ - if( b > 0 ){ - return result > 0; - }else if( b < 0 ){ - return result < 0; - } - } - - return false; -#endif -} - void rathena::util::string_left_pad_inplace(std::string& str, char padding, size_t num) { str.insert(0, min(0, num - str.length()), padding); diff --git a/src/common/utilities.hpp b/src/common/utilities.hpp index f7a10dad9a..b818544586 100644 --- a/src/common/utilities.hpp +++ b/src/common/utilities.hpp @@ -233,26 +233,25 @@ namespace rathena { } } + template ::value, T>::type> + bool safe_addition( T a, T b, T& result ){ #if __has_builtin( __builtin_add_overflow ) || ( defined( __GNUC__ ) && !defined( __clang__ ) && defined( GCC_VERSION ) && GCC_VERSION >= 50100 ) - template bool safe_addition(T a, T b, T &result) { - return __builtin_add_overflow(a, b, &result); - } + return __builtin_add_overflow( a, b, &result ); #else - template bool safe_addition( T a, T b, T& result ){ bool overflow = false; if( std::numeric_limits::is_signed ){ if( b < 0 ){ - if( a < ( (std::numeric_limits::min)() - b ) ){ + if( a < ( std::numeric_limits::min() - b ) ){ overflow = true; } }else{ - if( a > ( (std::numeric_limits::max)() - b ) ){ + if( a > ( std::numeric_limits::max() - b ) ){ overflow = true; } } }else{ - if( a > ( (std::numeric_limits::max)() - b ) ){ + if( a > ( std::numeric_limits::max() - b ) ){ overflow = true; } } @@ -260,11 +259,56 @@ namespace rathena { result = a + b; return overflow; - } #endif + } - bool safe_substraction( int64 a, int64 b, int64& result ); - bool safe_multiplication( int64 a, int64 b, int64& result ); + template ::value, T>::type> + bool safe_substraction( T a, T b, T& result ){ +#if __has_builtin( __builtin_sub_overflow ) || ( defined( __GNUC__ ) && !defined( __clang__ ) && defined( GCC_VERSION ) && GCC_VERSION >= 50100 ) + return __builtin_sub_overflow( a, b, &result ); +#else + bool overflow = false; + + if( b < 0 ){ + if( a > ( std::numeric_limits::max() + b ) ){ + overflow = true; + } + }else{ + if( a < ( std::numeric_limits::min() + b ) ){ + overflow = true; + } + } + + result = a - b; + + return overflow; +#endif + } + + template ::value, T>::type> + bool safe_multiplication( T a, T b, T& result ){ +#if __has_builtin( __builtin_mul_overflow ) || ( defined( __GNUC__ ) && !defined( __clang__ ) && defined( GCC_VERSION ) && GCC_VERSION >= 50100 ) + return __builtin_mul_overflow( a, b, &result ); +#else + result = a * b; + + if( a > 0 ){ + if( b > 0 ){ + return result < 0; + }else if( b < 0 ){ + return result > 0; + } + }else if( a < 0 ){ + if( b > 0 ){ + return result > 0; + }else if( b < 0 ){ + return result < 0; + } + } + + return false; +#endif + } /** * Safely add values without overflowing.