25 #ifndef XAPIAN_INCLUDED_OVERFLOW_H    26 #define XAPIAN_INCLUDED_OVERFLOW_H    29 # error config.h must be included first in each C++ source file    32 #include <type_traits>    34 #if !HAVE_DECL___BUILTIN_ADD_OVERFLOW || !HAVE_DECL___BUILTIN_SUB_OVERFLOW    35 # if HAVE_DECL__ADDCARRY_U32 || HAVE_DECL__ADDCARRY_U64 || \    36      HAVE_DECL__SUBBORROW_U32 || HAVE_DECL__SUBBORROW_U64    54 template<
typename T1, 
typename T2, 
typename R>
    55 typename std::enable_if<std::is_unsigned<T1>::value &&
    56                         std::is_unsigned<T2>::value &&
    57                         std::is_unsigned<R>::value, 
bool>::type
    59 #if HAVE_DECL___BUILTIN_ADD_OVERFLOW    60     return __builtin_add_overflow(a, b, &res);
    67     res = 
static_cast<R
>(r);
    73     typedef decltype(r) r_type;
    74     return (
sizeof(R) <= 
sizeof(T1) || 
sizeof(R) <= 
sizeof(T2)) &&
    75            (r_type(res) != r || r < r_type(b));
    79 #if !HAVE_DECL___BUILTIN_ADD_OVERFLOW    83 # if HAVE_DECL__ADDCARRY_U32    91     return _addcarry_u32(0, a, b, &res) != 0;
    95 # if HAVE_DECL__ADDCARRY_U64   100               unsigned __int64>(
unsigned __int64 a,
   102                                 unsigned __int64& res) {
   103     return _addcarry_u64(0, a, b, &res) != 0;
   121 template<
typename T1, 
typename T2, 
typename R>
   122 typename std::enable_if<std::is_unsigned<T1>::value &&
   123                         std::is_unsigned<T2>::value &&
   124                         std::is_unsigned<R>::value, 
bool>::type
   126 #if HAVE_DECL___BUILTIN_ADD_OVERFLOW   127     return __builtin_sub_overflow(a, b, &res);
   134     res = 
static_cast<R
>(r);
   137     typedef decltype(r) r_type;
   138     return r_type(res) != r || r > r_type(a);
   142 #if !HAVE_DECL___BUILTIN_SUB_OVERFLOW   146 # if HAVE_DECL__SUBBORROW_U32   151               unsigned>(
unsigned a,
   154     return _subborrow_u32(0, a, b, &res) != 0;
   158 # if HAVE_DECL__SUBBORROW_U64   163               unsigned __int64>(
unsigned __int64 a,
   165                                 unsigned __int64& res) {
   166     return _subborrow_u64(0, a, b, &res) != 0;
   184 template<
typename T1, 
typename T2, 
typename R>
   185 typename std::enable_if<std::is_unsigned<T1>::value &&
   186                         std::is_unsigned<T2>::value &&
   187                         std::is_unsigned<R>::value, 
bool>::type
   189 #if HAVE_DECL___BUILTIN_MUL_OVERFLOW   190     return __builtin_mul_overflow(a, b, &res);
   197     res = 
static_cast<R
>(r);
   200     typedef decltype(r) r_type;
   201     return r_type(res) != r || (a != 0 && r / r_type(a) != r_type(b));
   205 #endif // XAPIAN_INCLUDED_OVERFLOW_H std::enable_if< std::is_unsigned< T1 >::value &&std::is_unsigned< T2 >::value &&std::is_unsigned< R >::value, bool >::type add_overflows(T1 a, T2 b, R &res)
Addition with overflow checking. 
 
std::enable_if< std::is_unsigned< T1 >::value &&std::is_unsigned< T2 >::value &&std::is_unsigned< R >::value, bool >::type sub_overflows(T1 a, T2 b, R &res)
Subtraction with overflow checking. 
 
std::enable_if< std::is_unsigned< T1 >::value &&std::is_unsigned< T2 >::value &&std::is_unsigned< R >::value, bool >::type mul_overflows(T1 a, T2 b, R &res)
Multiplication with overflow checking.