@@ -40,16 +40,15 @@ namespace internal {
4040 return !check_##_op_name##_##_type##_##_type (u, v, out); \
4141 }
4242
43- #define SAFE_INT_OPS_WITH_OVERFLOW (_func_name, _psnip_op ) \
44- SAFE_INT_OP_WITH_OVERFLOW (_func_name, _psnip_op , int32_t , int32) \
45- SAFE_INT_OP_WITH_OVERFLOW (_func_name, _psnip_op , int64_t , int64) \
46- SAFE_INT_OP_WITH_OVERFLOW (_func_name, _psnip_op , uint32_t , uint32) \
47- SAFE_INT_OP_WITH_OVERFLOW (_func_name, _psnip_op , uint64_t , uint64)
43+ #define SAFE_INT_OPS_WITH_OVERFLOW (_func_name, _op_name ) \
44+ SAFE_INT_OP_WITH_OVERFLOW (_func_name, _op_name , int32_t , int32) \
45+ SAFE_INT_OP_WITH_OVERFLOW (_func_name, _op_name , int64_t , int64) \
46+ SAFE_INT_OP_WITH_OVERFLOW (_func_name, _op_name , uint32_t , uint32) \
47+ SAFE_INT_OP_WITH_OVERFLOW (_func_name, _op_name , uint64_t , uint64)
4848
4949SAFE_INT_OPS_WITH_OVERFLOW (SafeIntAddWithOverflow, add)
5050SAFE_INT_OPS_WITH_OVERFLOW (SafeIntSubtractWithOverflow, sub)
5151SAFE_INT_OPS_WITH_OVERFLOW (SafeIntMultiplyWithOverflow, mul)
52- SAFE_INT_OPS_WITH_OVERFLOW (SafeIntDivideWithOverflow, div)
5352
5453#undef SAFE_INT_OP_WITH_OVERFLOW
5554#undef SAFE_INT_OPS_WITH_OVERFLOW
@@ -77,8 +76,8 @@ template <typename Int>
7776 return __builtin_add_overflow (u, v, out);
7877#else
7978 if constexpr (sizeof (Int) < 4 ) {
80- auto r =
81- static_cast <upscaled_int32_t <Int> > (u) + static_cast <upscaled_int32_t <Int> >(v);
79+ using UpscaledInt = upscaled_int32_t <Int>;
80+ auto r = static_cast <UpscaledInt> (u) + static_cast <UpscaledInt >(v);
8281 *out = static_cast <Int>(r);
8382 return r != *out;
8483 } else {
@@ -93,8 +92,8 @@ template <typename Int>
9392 return __builtin_sub_overflow (u, v, out);
9493#else
9594 if constexpr (sizeof (Int) < 4 ) {
96- auto r =
97- static_cast <upscaled_int32_t <Int> > (u) - static_cast <upscaled_int32_t <Int> >(v);
95+ using UpscaledInt = upscaled_int32_t <Int>;
96+ auto r = static_cast <UpscaledInt> (u) - static_cast <UpscaledInt >(v);
9897 *out = static_cast <Int>(r);
9998 return r != *out;
10099 } else {
@@ -109,8 +108,8 @@ template <typename Int>
109108 return __builtin_mul_overflow (u, v, out);
110109#else
111110 if constexpr (sizeof (Int) < 4 ) {
112- auto r =
113- static_cast <upscaled_int32_t <Int> > (u) * static_cast <upscaled_int32_t <Int> >(v);
111+ using UpscaledInt = upscaled_int32_t <Int>;
112+ auto r = static_cast <UpscaledInt> (u) * static_cast <UpscaledInt >(v);
114113 *out = static_cast <Int>(r);
115114 return r != *out;
116115 } else {
@@ -122,17 +121,18 @@ template <typename Int>
122121template <typename Int>
123122[[nodiscard]] bool DivideWithOverflowGeneric (Int u, Int v, Int* out) {
124123 if (v == 0 ) {
124+ *out = Int{};
125125 return true ;
126126 }
127- if constexpr (sizeof (Int) < 4 ) {
128- using UpscaledInt = upscaled_int32_t <Int>;
129- UpscaledInt r;
130- bool error = SafeIntDivideWithOverflow (UpscaledInt{u}, UpscaledInt{v}, &r);
131- *out = static_cast <Int>(r);
132- return error || r != *out;
133- } else {
134- return SafeIntDivideWithOverflow (u, v, out);
127+ if constexpr (std::is_signed_v<Int>) {
128+ constexpr auto kMin = std::numeric_limits<Int>::min ();
129+ if (u == kMin && v == -1 ) {
130+ *out = kMin ;
131+ return true ;
132+ }
135133 }
134+ *out = u / v;
135+ return false ;
136136}
137137
138138// Define non-generic versions of the above so as to benefit from automatic
@@ -141,7 +141,7 @@ template <typename Int>
141141
142142#define NON_GENERIC_OP_WITH_OVERFLOW (_func_name, _c_type ) \
143143 [[nodiscard]] inline bool _func_name (_c_type u, _c_type v, _c_type* out) { \
144- return _func_name##Generic (u, v, out); \
144+ return ARROW_PREDICT_FALSE ( _func_name##Generic (u, v, out)); \
145145 }
146146
147147#define NON_GENERIC_OPS_WITH_OVERFLOW (_func_name ) \
0 commit comments