Skip to content

Commit 988e8a4

Browse files
committed
Add support for _BitInt on clang
Issue #4007
1 parent 1408f18 commit 988e8a4

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

include/fmt/base.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,14 @@ enum class uint128_opt {};
427427
template <typename T> auto convert_for_visit(T) -> monostate { return {}; }
428428
#endif
429429

430+
#ifndef FMT_USE_BITINT
431+
# if FMT_CLANG_VERSION && FMT_CLANG_VERSION >= 1400
432+
# define FMT_USE_BITINT 1
433+
# else
434+
# define FMT_USE_BITINT 0
435+
# endif
436+
#endif
437+
430438
// Casts a nonnegative integer to unsigned.
431439
template <typename Int>
432440
FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t<Int> {
@@ -1484,6 +1492,20 @@ template <typename Context> struct arg_mapper {
14841492
FMT_MAP_API auto map(double val) -> double { return val; }
14851493
FMT_MAP_API auto map(long double val) -> long double { return val; }
14861494

1495+
#if FMT_USE_BITINT
1496+
# pragma clang diagnostic push
1497+
# pragma clang diagnostic ignored "-Wbit-int-extension"
1498+
template <class T, int N = 0> struct is_bitint : std::false_type {};
1499+
template <int N> struct is_bitint<_BitInt(N)> : std::true_type {};
1500+
template <int N> struct is_bitint<unsigned _BitInt(N)> : std::true_type {};
1501+
1502+
template <class T, FMT_ENABLE_IF(is_bitint<remove_cvref_t<T>>::value)>
1503+
FMT_MAP_API auto map(T&& val) -> decltype(val) {
1504+
return val;
1505+
}
1506+
# pragma clang diagnostic pop
1507+
#endif
1508+
14871509
FMT_MAP_API auto map(char_type* val) -> const char_type* { return val; }
14881510
FMT_MAP_API auto map(const char_type* val) -> const char_type* { return val; }
14891511
template <typename T, typename Char = char_t<T>,

test/format-test.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,3 +2442,30 @@ FMT_END_NAMESPACE
24422442
TEST(format_test, ustring) {
24432443
EXPECT_EQ(fmt::format("{}", ustring()), "ustring");
24442444
}
2445+
2446+
#if FMT_USE_BITINT
2447+
# pragma clang diagnostic push
2448+
# pragma clang diagnostic ignored "-Wbit-int-extension"
2449+
using BitIntS7 = _BitInt(7);
2450+
using BitIntU32 = unsigned _BitInt(32);
2451+
FMT_BEGIN_NAMESPACE
2452+
template <> struct formatter<BitIntS7> : formatter<int8_t> {};
2453+
2454+
template <> struct formatter<BitIntU32> : formatter<uint32_t> {};
2455+
FMT_END_NAMESPACE
2456+
2457+
TEST(format_test, bitint) {
2458+
EXPECT_EQ(fmt::format("{}", BitIntS7{0}), "0");
2459+
EXPECT_EQ(fmt::format("{}", BitIntU32{4294967295}), "4294967295");
2460+
2461+
auto a = BitIntS7{0};
2462+
auto b = BitIntU32{4294967295};
2463+
const auto c = BitIntS7{0};
2464+
const auto d = BitIntU32{4294967295};
2465+
EXPECT_EQ(fmt::format("{}", a), "0");
2466+
EXPECT_EQ(fmt::format("{}", b), "4294967295");
2467+
EXPECT_EQ(fmt::format("{}", c), "0");
2468+
EXPECT_EQ(fmt::format("{}", d), "4294967295");
2469+
}
2470+
# pragma clang diagnostic pop
2471+
#endif

0 commit comments

Comments
 (0)