diff --git a/include/fmt/format.h b/include/fmt/format.h index 87fce444..2b7a933f 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -342,11 +342,13 @@ class uint128 { return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs}; } FMT_CONSTEXPR auto operator>>(int shift) const -> uint128 { + if (shift == 0) return *this; if (shift == 64) return {0, hi_}; if (shift > 64) return uint128(0, hi_) >> (shift - 64); return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)}; } FMT_CONSTEXPR auto operator<<(int shift) const -> uint128 { + if (shift == 0) return *this; if (shift == 64) return {lo_, 0}; if (shift > 64) return uint128(lo_, 0) << (shift - 64); return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)}; diff --git a/test/format-test.cc b/test/format-test.cc index b99c7a79..c61d2ce4 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -76,6 +76,11 @@ TEST(uint128_test, shift) { EXPECT_EQ(static_cast(n), 42); EXPECT_EQ(uint128(1) << 112, uint128(0x1000000000000, 0)); EXPECT_EQ(uint128(0x1000000000000, 0) >> 112, uint128(1)); + // FMT_CONSTEXPR turns an undefined shift into a compile error. + FMT_CONSTEXPR auto lshift = uint128(1, 2) << 0; + FMT_CONSTEXPR auto rshift = uint128(1, 2) >> 0; + EXPECT_EQ(lshift, uint128(1, 2)); + EXPECT_EQ(rshift, uint128(1, 2)); } TEST(uint128_test, minus) {