2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2015 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_UTIL_OVERFLOW_H
18 #define incl_HPHP_UTIL_OVERFLOW_H
23 typename
std::enable_if
<std::is_integral
<T
>::value
, bool>::type
24 add_overflow(T a
, T b
) {
25 // Cast to unsigned so that ua + ub isn't undefined.
26 auto const ua
= static_cast<typename
std::make_unsigned
<T
>::type
>(a
);
27 auto const ub
= static_cast<typename
std::make_unsigned
<T
>::type
>(b
);
29 // Overflow if the inputs have the same sign, and the result of addition has
31 return (~(ua
^ ub
) & (ua
^ (ua
+ ub
))) >> std::numeric_limits
<T
>::digits
;
35 typename
std::enable_if
<std::is_integral
<T
>::value
, bool>::type
36 sub_overflow(T a
, T b
) {
37 if (b
== std::numeric_limits
<T
>::min()) {
38 // a - (INT_MIN) --> a - (-huge) --> a + huge
41 return add_overflow(a
, -b
);
45 typename
std::enable_if
<std::is_integral
<T
>::value
, bool>::type
46 mul_overflow(T a
, T b
) {
47 auto max
= std::numeric_limits
<T
>::max();
48 auto min
= std::numeric_limits
<T
>::min();
50 // Handle bad div cases first.
51 if (a
== 0 || b
== 0) {
54 if ((a
== min
&& b
== -1) || (b
== min
&& a
== -1)) {