From d38f72aff28d234cd6b379510a98480162a9141c Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 17 Feb 2022 20:24:42 -0800 Subject: [PATCH] Refactor fallback ints --- include/fmt/format-inl.h | 2 +- include/fmt/format.h | 42 ++++++++++++++++++++++------------------ test/format-impl-test.cc | 2 +- test/format-test.cc | 10 +++++----- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 4f9d98f8..99be0d4d 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -141,7 +141,7 @@ FMT_FUNC std::system_error vsystem_error(int error_code, string_view format_str, namespace detail { -template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) { +template <> FMT_FUNC int count_digits<4>(detail::uintptr_fallback n) { // fallback_uintptr is always stored in little endian. int i = static_cast(sizeof(void*)) - 1; while (i > 0 && n.value[i] == 0) --i; diff --git a/include/fmt/format.h b/include/fmt/format.h index 5b2fcae9..a32c2b53 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -315,12 +315,12 @@ inline auto is_big_endian() -> bool { } // A fallback implementation of uintptr_t for systems that lack it. -struct fallback_uintptr { +struct uintptr_fallback { unsigned char value[sizeof(void*)]; - fallback_uintptr() = default; - explicit fallback_uintptr(const void* p) { - *this = bit_cast(p); + uintptr_fallback() = default; + explicit uintptr_fallback(const void* p) { + *this = bit_cast(p); if (const_check(is_big_endian())) { for (size_t i = 0, j = sizeof(void*) - 1; i < j; ++i, --j) std::swap(value[i], value[j]); @@ -333,42 +333,46 @@ inline auto to_uintptr(const void* p) -> uintptr_t { return bit_cast(p); } #else -using uintptr_t = fallback_uintptr; -inline auto to_uintptr(const void* p) -> fallback_uintptr { - return fallback_uintptr(p); +using uintptr_t = uintptr_fallback; +inline auto to_uintptr(const void* p) -> uintptr_fallback { + return uintptr_fallback(p); } #endif -class uint128_t { +class uint128_fallback { private: uint64_t lo_, hi_; - constexpr uint128_t(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {} + constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {} public: - constexpr uint128_t(uint64_t value = 0) : lo_(value), hi_(0) {} + constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {} explicit operator int() const { return static_cast(lo_); } explicit operator uint64_t() const { return lo_; } - friend auto operator==(const uint128_t& lhs, const uint128_t& rhs) -> bool { + friend auto operator==(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> bool { return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_; } - friend auto operator&(const uint128_t& lhs, const uint128_t& rhs) - -> uint128_t { + friend auto operator&(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> uint128_fallback { return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_}; } - friend auto operator-(const uint128_t& lhs, uint64_t rhs) -> uint128_t { + friend auto operator-(const uint128_fallback& lhs, uint64_t rhs) + -> uint128_fallback { FMT_ASSERT(lhs.lo_ >= rhs, ""); return {lhs.hi_, lhs.lo_ - rhs}; } - auto operator>>(int shift) const -> uint128_t { + auto operator>>(int shift) const -> uint128_fallback { if (shift == 64) return {0, hi_}; return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)}; } - auto operator<<(int shift) const -> uint128_t { + auto operator<<(int shift) const -> uint128_fallback { if (shift == 64) return {lo_, 0}; return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)}; } }; +using uint128_t = conditional_t; + // Returns the largest possible value for type T. Same as // std::numeric_limits::max() but shorter and not affected by the max macro. template constexpr auto max_value() -> T { @@ -380,7 +384,7 @@ template constexpr auto num_bits() -> int { // std::numeric_limits::digits may return 0 for 128-bit ints. template <> constexpr auto num_bits() -> int { return 128; } template <> constexpr auto num_bits() -> int { return 128; } -template <> constexpr auto num_bits() -> int { +template <> constexpr auto num_bits() -> int { return static_cast(sizeof(void*) * std::numeric_limits::digits); } @@ -1035,7 +1039,7 @@ FMT_CONSTEXPR auto count_digits(UInt n) -> int { }(n); } -template <> auto count_digits<4>(detail::fallback_uintptr n) -> int; +template <> auto count_digits<4>(detail::uintptr_fallback n) -> int; #ifdef FMT_BUILTIN_CLZ // It is a separate function rather than a part of count_digits to workaround @@ -1179,7 +1183,7 @@ FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits, } template -auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, +auto format_uint(Char* buffer, detail::uintptr_fallback n, int num_digits, bool = false) -> Char* { auto char_digits = std::numeric_limits::digits / 4; int start = (num_digits + char_digits - 1) / char_digits - 1; diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc index a012306f..90105b5a 100644 --- a/test/format-impl-test.cc +++ b/test/format-impl-test.cc @@ -361,7 +361,7 @@ TEST(format_impl_test, write_fallback_uintptr) { std::string s; fmt::detail::write_ptr( std::back_inserter(s), - fmt::detail::fallback_uintptr(reinterpret_cast(0xface)), nullptr); + fmt::detail::uintptr_fallback(reinterpret_cast(0xface)), nullptr); EXPECT_EQ(s, "0xface"); } diff --git a/test/format-test.cc b/test/format-test.cc index 92dcfd21..72423017 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -40,16 +40,16 @@ using testing::StrictMock; enum { buffer_size = 256 }; TEST(uint128_test, ctor) { - using fmt::detail::uint128_t; - auto n = uint128_t(); + using fmt::detail::uint128_fallback; + auto n = uint128_fallback(); EXPECT_EQ(n, 0); - n = uint128_t(42); + n = uint128_fallback(42); EXPECT_EQ(n, 42); EXPECT_EQ(static_cast(n), 42); } TEST(uint128_test, shift) { - auto n = fmt::detail::uint128_t(42); + auto n = fmt::detail::uint128_fallback(42); n = n << 64; EXPECT_EQ(static_cast(n), 0); n = n >> 64; @@ -62,7 +62,7 @@ TEST(uint128_test, shift) { } TEST(uint128_test, minus) { - auto n = fmt::detail::uint128_t(42); + auto n = fmt::detail::uint128_fallback(42); EXPECT_EQ(n - 2, 40); }