diff --git a/include/fmt/base.h b/include/fmt/base.h index 28df1e4b..9b34edd0 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -417,22 +417,15 @@ template auto convert_for_visit(T) -> monostate { return {}; } # define FMT_USE_BITINT (FMT_CLANG_VERSION >= 1400) #endif -template struct bitint_traits {}; #if FMT_USE_BITINT # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wbit-int-extension" - -template struct bitint_traits<_BitInt(N)> { - static constexpr bool is_formattable = N <= 128; - using format_type = conditional_t<(N <= 64), long long, __int128>; -}; -template struct bitint_traits { - static constexpr bool is_formattable = N <= 128; - using format_type = - conditional_t<(N <= 64), unsigned long long, unsigned __int128>; -}; - +template using bitint = _BitInt(N); +template using ubitint = unsigned _BitInt(N); # pragma clang diagnostic pop +#else +template struct bitint {}; +template struct ubitint {}; #endif // FMT_USE_BITINT // Casts a nonnegative integer to unsigned. @@ -1170,12 +1163,20 @@ template struct arg_mapper { FMT_MAP_API auto map(double x) -> double { return x; } FMT_MAP_API auto map(long double x) -> long double { return x; } - template ::is_formattable)> - FMT_MAP_API auto map(T x) -> typename bitint_traits::format_type { + template + FMT_MAP_API auto map(bitint x) -> long long { return x; } - template ::is_formattable)> - FMT_MAP_API auto map(T) -> unformattable { + template + FMT_MAP_API auto map(ubitint x) -> unsigned long long { + return x; + } + template 64)> + FMT_MAP_API auto map(bitint) -> unformattable { + return {}; + } + template 64)> + FMT_MAP_API auto map(ubitint) -> unformattable { return {}; } diff --git a/include/fmt/format.h b/include/fmt/format.h index f24b14df..5f83aad0 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3973,10 +3973,11 @@ template class formatter, Char> : public formatter, Char> {}; -template -struct formatter::is_formattable)>> - : formatter::format_type, Char> {}; +template +struct formatter, Char> : formatter {}; +template +struct formatter, Char> + : formatter {}; /** * Converts `p` to `const void*` for pointer formatting. diff --git a/test/format-test.cc b/test/format-test.cc index 6491449f..1fe575ab 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2518,59 +2518,36 @@ TEST(format_test, writer) { #if FMT_USE_BITINT # pragma clang diagnostic ignored "-Wbit-int-extension" -template -using bitint_helper = - fmt::conditional_t; -template using signed_bitint = bitint_helper; -template using unsigned_bitint = bitint_helper; - TEST(format_test, bitint) { - EXPECT_EQ(fmt::format("{}", unsigned_bitint<3>(7)), "7"); - EXPECT_EQ(fmt::format("{}", signed_bitint<7>()), "0"); + using fmt::detail::bitint; + using fmt::detail::ubitint; + + EXPECT_EQ(fmt::format("{}", ubitint<3>(7)), "7"); + EXPECT_EQ(fmt::format("{}", bitint<7>()), "0"); - EXPECT_EQ(fmt::format("{}", unsigned_bitint<15>(31000)), "31000"); - EXPECT_EQ(fmt::format("{}", signed_bitint<16>(INT16_MIN)), "-32768"); - EXPECT_EQ(fmt::format("{}", signed_bitint<16>(INT16_MAX)), "32767"); + EXPECT_EQ(fmt::format("{}", ubitint<15>(31000)), "31000"); + EXPECT_EQ(fmt::format("{}", bitint<16>(INT16_MIN)), "-32768"); + EXPECT_EQ(fmt::format("{}", bitint<16>(INT16_MAX)), "32767"); - EXPECT_EQ(fmt::format("{}", unsigned_bitint<32>(4294967295)), "4294967295"); + EXPECT_EQ(fmt::format("{}", ubitint<32>(4294967295)), "4294967295"); - EXPECT_EQ(fmt::format("{}", unsigned_bitint<47>(140737488355327ULL)), + EXPECT_EQ(fmt::format("{}", ubitint<47>(140737488355327ULL)), "140737488355327"); - EXPECT_EQ(fmt::format("{}", signed_bitint<47>(-40737488355327LL)), + EXPECT_EQ(fmt::format("{}", bitint<47>(-40737488355327LL)), "-40737488355327"); // Check lvalues and const - auto a = signed_bitint<8>(0); - auto b = unsigned_bitint<32>(4294967295); - const auto c = signed_bitint<7>(0); - const auto d = unsigned_bitint<32>(4294967295); + auto a = bitint<8>(0); + auto b = ubitint<32>(4294967295); + const auto c = bitint<7>(0); + const auto d = ubitint<32>(4294967295); EXPECT_EQ(fmt::format("{}", a), "0"); EXPECT_EQ(fmt::format("{}", b), "4294967295"); EXPECT_EQ(fmt::format("{}", c), "0"); EXPECT_EQ(fmt::format("{}", d), "4294967295"); - static_assert(fmt::is_formattable, char>{}, ""); - static_assert(fmt::is_formattable, char>{}, ""); - -# if FMT_USE_INT128 - static_assert(fmt::is_formattable, char>{}, ""); - static_assert(fmt::is_formattable, char>{}, ""); - - EXPECT_EQ(fmt::format("{}", signed_bitint<128>(0)), "0"); - EXPECT_EQ(fmt::format("{}", unsigned_bitint<128>(0)), "0"); - EXPECT_EQ("9223372036854775808", - fmt::format("{}", signed_bitint<65>(INT64_MAX) + 1)); - EXPECT_EQ("-9223372036854775809", - fmt::format("{}", signed_bitint<65>(INT64_MIN) - 1)); - EXPECT_EQ("18446744073709551616", - fmt::format("{}", unsigned_bitint<66>(UINT64_MAX) + 1)); - EXPECT_EQ("170141183460469231731687303715884105727", - fmt::format("{}", signed_bitint<128>(int128_max))); - EXPECT_EQ("-170141183460469231731687303715884105728", - fmt::format("{}", signed_bitint<128>(int128_min))); - EXPECT_EQ("340282366920938463463374607431768211455", - fmt::format("{}", unsigned_bitint<128>(uint128_max))); -# endif + static_assert(fmt::is_formattable, char>{}, ""); + static_assert(fmt::is_formattable, char>{}, ""); } #endif