89 template <
bool B,
class T =
void>
120 template <
typename T>
122 T summand_1, T summand_2, T& result)
124 if (((summand_2 >= 0) && (summand_1 > std::numeric_limits<T>::max() - summand_2)) ||
125 ((summand_2 < 0) && (summand_1 < std::numeric_limits<T>::min() - summand_2))) {
128 result = summand_1 + summand_2;
152 template <
typename T>
153 typename enable_if<is_signed<T>::VALUE &&
sizeof(T) <
sizeof(
int),
bool>::type fallback_add_overflow(
154 T summand_1, T summand_2, T& result)
156 const int res = summand_1 + summand_2;
157 if ((res > std::numeric_limits<T>::max()) || (res < std::numeric_limits<T>::min())) {
160 result =
static_cast<T
>(res);
181 template <
typename T>
182 typename enable_if<!is_signed<T>::VALUE,
bool>::type fallback_add_overflow(T summand_1, T summand_2, T& result)
184 result = summand_1 + summand_2;
185 return result < summand_1;
201 template <
typename T>
202 bool builtin_add_overflow(T summand_1, T summand_2, T& result)
204 return fallback_add_overflow(summand_1, summand_2, result);
207#if defined(__GNUC__) || defined(__clang__)
208#if __GNUC__ >= 5 || __clang_major__ >= 3
220#define SPECIALIZE_builtin_add_overflow(type, builtin_name) \
224 inline bool builtin_add_overflow<type>(type summand_1, type summand_2, type & result) \
226 return builtin_name(summand_1, summand_2, &result); \
229 SPECIALIZE_builtin_add_overflow(
int, __builtin_sadd_overflow);
230 SPECIALIZE_builtin_add_overflow(
long, __builtin_saddl_overflow);
231 SPECIALIZE_builtin_add_overflow(
long long, __builtin_saddll_overflow);
233 SPECIALIZE_builtin_add_overflow(
unsigned int, __builtin_uadd_overflow);
234 SPECIALIZE_builtin_add_overflow(
unsigned long, __builtin_uaddl_overflow);
235 SPECIALIZE_builtin_add_overflow(
unsigned long long, __builtin_uaddll_overflow);
237#undef SPECIALIZE_builtin_add_overflow
240#elif defined(_MSC_VER)
257#define SPECIALIZE_builtin_add_overflow_WIN(type, builtin_name) \
259 inline bool builtin_add_overflow(type summand_1, type summand_2, type& result) \
261 return builtin_name(summand_1, summand_2, &result) != S_OK; \
264 SPECIALIZE_builtin_add_overflow_WIN(
unsigned int, UIntAdd);
265 SPECIALIZE_builtin_add_overflow_WIN(
unsigned long, ULongAdd);
266 SPECIALIZE_builtin_add_overflow_WIN(
unsigned long long, ULongLongAdd);
268#undef SPECIALIZE_builtin_add_overflow_WIN