diff --git a/include/fmt/base.h b/include/fmt/base.h index d4a3474de5527..d974b498625f2 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -427,6 +427,14 @@ enum class uint128_opt {}; template auto convert_for_visit(T) -> monostate { return {}; } #endif +#ifndef FMT_USE_BITINT +# if FMT_CLANG_VERSION && FMT_CLANG_VERSION >= 1400 +# define FMT_USE_BITINT 1 +# else +# define FMT_USE_BITINT 0 +# endif +#endif + // Casts a nonnegative integer to unsigned. template FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t { @@ -1188,7 +1196,7 @@ namespace detail { namespace detect { template struct is_back_insert_iterator> : std::true_type {}; -} +} // namespace detect template struct locking : std::true_type {}; @@ -1487,6 +1495,22 @@ template struct arg_mapper { FMT_MAP_API auto map(double val) -> double { return val; } FMT_MAP_API auto map(long double val) -> long double { return val; } +#if FMT_USE_BITINT +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wbit-int-extension" + template struct is_bitint : std::false_type {}; + + template struct is_bitint<_BitInt(N)> : std::true_type {}; + + template struct is_bitint : std::true_type {}; + + template >::value)> + FMT_MAP_API auto map(T&& val) -> decltype(val) { + return val; + } +# pragma clang diagnostic pop +#endif + FMT_MAP_API auto map(char_type* val) -> const char_type* { return val; } FMT_MAP_API auto map(const char_type* val) -> const char_type* { return val; } template , diff --git a/test/format-test.cc b/test/format-test.cc index a9ef19fc19c81..2643a535a3104 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2442,3 +2442,30 @@ FMT_END_NAMESPACE TEST(format_test, ustring) { EXPECT_EQ(fmt::format("{}", ustring()), "ustring"); } + +#if FMT_USE_BITINT +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wbit-int-extension" +using BitIntS7 = _BitInt(7); +using BitIntU32 = unsigned _BitInt(32); +FMT_BEGIN_NAMESPACE +template <> struct formatter : formatter {}; + +template <> struct formatter : formatter {}; +FMT_END_NAMESPACE + +TEST(format_test, bitint) { + EXPECT_EQ(fmt::format("{}", BitIntS7{0}), "0"); + EXPECT_EQ(fmt::format("{}", BitIntU32{4294967295}), "4294967295"); + + auto a = BitIntS7{0}; + auto b = BitIntU32{4294967295}; + const auto c = BitIntS7{0}; + const auto d = BitIntU32{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"); +} +# pragma clang diagnostic pop +#endif