From 96930161f918d08a689076f500f128522a237a75 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 27 Mar 2022 08:07:45 -0700 Subject: [PATCH] Implement 128-bit operator+= for uint128_fallback --- include/fmt/format.h | 9 ++++++--- test/format-test.cc | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index 60e9b3d7..59b8077b 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -363,9 +363,12 @@ class uint128_fallback { FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback& { return *this = *this >> shift; } - FMT_CONSTEXPR void operator+=(uint64_t n) { - lo_ += n; - if (lo_ < n) ++hi_; + FMT_CONSTEXPR void operator+=(uint128_fallback n) { + uint64_t new_lo = lo_ + n.lo_; + uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0); + FMT_ASSERT(new_hi >= hi_, ""); + lo_ = new_lo; + hi_ = new_hi; } }; diff --git a/test/format-test.cc b/test/format-test.cc index 1bee1aa4..b5ecd03c 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -33,6 +33,7 @@ using fmt::memory_buffer; using fmt::runtime; using fmt::string_view; using fmt::detail::max_value; +using fmt::detail::uint128_fallback; using testing::Return; using testing::StrictMock; @@ -40,7 +41,6 @@ using testing::StrictMock; enum { buffer_size = 256 }; TEST(uint128_test, ctor) { - using fmt::detail::uint128_fallback; auto n = uint128_fallback(); EXPECT_EQ(n, 0); n = uint128_fallback(42); @@ -49,7 +49,7 @@ TEST(uint128_test, ctor) { } TEST(uint128_test, shift) { - auto n = fmt::detail::uint128_fallback(42); + auto n = uint128_fallback(42); n = n << 64; EXPECT_EQ(static_cast(n), 0); n = n >> 64; @@ -62,10 +62,19 @@ TEST(uint128_test, shift) { } TEST(uint128_test, minus) { - auto n = fmt::detail::uint128_fallback(42); + auto n = uint128_fallback(42); EXPECT_EQ(n - 2, 40); } +TEST(uint128_test, plus_assign) { + auto n = uint128_fallback(32); + n += uint128_fallback(10); + EXPECT_EQ(n, 42); + n = uint128_fallback(max_value()); + n += uint128_fallback(1); + EXPECT_EQ(n, uint128_fallback(1) << 64); +} + template void check_isfinite() { using fmt::detail::isfinite; EXPECT_TRUE(isfinite(Float(0.0)));