82 template <
bool B,
class T =
void>
113 template <
typename T>
115 T summand_1, T summand_2, T& result)
117 if (((summand_2 >= 0) && (summand_1 > std::numeric_limits<T>::max() - summand_2)) ||
118 ((summand_2 < 0) && (summand_1 < std::numeric_limits<T>::min() - summand_2))) {
121 result = summand_1 + summand_2;
145 template <
typename T>
146 typename enable_if<is_signed<T>::VALUE &&
sizeof(T) <
sizeof(
int),
bool>::type
fallback_add_overflow(
147 T summand_1, T summand_2, T& result)
149 const int res = summand_1 + summand_2;
150 if ((res > std::numeric_limits<T>::max()) || (res < std::numeric_limits<T>::min())) {
153 result =
static_cast<T
>(res);
174 template <
typename T>
175 typename enable_if<!is_signed<T>::VALUE,
bool>::type
fallback_add_overflow(T summand_1, T summand_2, T& result)
177 result = summand_1 + summand_2;
178 return result < summand_1;
194 template <
typename T>
195 bool builtin_add_overflow(T summand_1, T summand_2, T& result)
200#if defined(__GNUC__) || defined(__clang__)
201#if __GNUC__ >= 5 || __clang_major__ >= 3
213#define SPECIALIZE_builtin_add_overflow(type, builtin_name) \
217 inline bool builtin_add_overflow<type>(type summand_1, type summand_2, type & result) \
219 return builtin_name(summand_1, summand_2, &result); \
222 SPECIALIZE_builtin_add_overflow(
int, __builtin_sadd_overflow);
223 SPECIALIZE_builtin_add_overflow(
long, __builtin_saddl_overflow);
224 SPECIALIZE_builtin_add_overflow(
long long, __builtin_saddll_overflow);
226 SPECIALIZE_builtin_add_overflow(
unsigned int, __builtin_uadd_overflow);
227 SPECIALIZE_builtin_add_overflow(
unsigned long, __builtin_uaddl_overflow);
228 SPECIALIZE_builtin_add_overflow(
unsigned long long, __builtin_uaddll_overflow);
230#undef SPECIALIZE_builtin_add_overflow
233#elif defined(_MSC_VER)
250#define SPECIALIZE_builtin_add_overflow_WIN(type, builtin_name) \
252 inline bool builtin_add_overflow(type summand_1, type summand_2, type& result) \
254 return builtin_name(summand_1, summand_2, &result) != S_OK; \
257 SPECIALIZE_builtin_add_overflow_WIN(
unsigned int, UIntAdd);
258 SPECIALIZE_builtin_add_overflow_WIN(
unsigned long, ULongAdd);
259 SPECIALIZE_builtin_add_overflow_WIN(
unsigned long long, ULongLongAdd);
261#undef SPECIALIZE_builtin_add_overflow_WIN