| Index: src/utils.h
|
| diff --git a/src/utils.h b/src/utils.h
|
| index 0ea1de1e0732ec289a27776867bd770d6cd4fbfd..6d0d3c84a3845750283340bf2bf611576f460994 100644
|
| --- a/src/utils.h
|
| +++ b/src/utils.h
|
| @@ -137,15 +137,20 @@ inline int MostSignificantBit(uint32_t x) {
|
| return nibble + msb4[x];
|
| }
|
|
|
| -
|
| -// The C++ standard leaves the semantics of '>>' undefined for
|
| -// negative signed operands. Most implementations do the right thing,
|
| -// though.
|
| -inline int ArithmeticShiftRight(int x, int s) {
|
| - return x >> s;
|
| +template <typename T>
|
| +static T ArithmeticShiftRight(T x, int shift) {
|
| + DCHECK_LE(0, shift);
|
| + if (x < 0) {
|
| + // Right shift of signed values is implementation defined. Simulate a
|
| + // true arithmetic right shift by adding leading sign bits.
|
| + using UnsignedT = typename std::make_unsigned<T>::type;
|
| + UnsignedT mask = ~(static_cast<UnsignedT>(~0) >> shift);
|
| + return (static_cast<UnsignedT>(x) >> shift) | mask;
|
| + } else {
|
| + return x >> shift;
|
| + }
|
| }
|
|
|
| -
|
| template <typename T>
|
| int Compare(const T& a, const T& b) {
|
| if (a == b)
|
|
|