Skip to content

Commit

Permalink
Add support for _BitInt on clang
Browse files Browse the repository at this point in the history
Issue #4007
  • Loading branch information
Arghnews committed Jul 13, 2024
1 parent 1408f18 commit 988e8a4
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
22 changes: 22 additions & 0 deletions include/fmt/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,14 @@ enum class uint128_opt {};
template <typename T> 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 <typename Int>
FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t<Int> {
Expand Down Expand Up @@ -1484,6 +1492,20 @@ template <typename Context> 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 <class T, int N = 0> struct is_bitint : std::false_type {};
template <int N> struct is_bitint<_BitInt(N)> : std::true_type {};
template <int N> struct is_bitint<unsigned _BitInt(N)> : std::true_type {};

template <class T, FMT_ENABLE_IF(is_bitint<remove_cvref_t<T>>::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 <typename T, typename Char = char_t<T>,
Expand Down
27 changes: 27 additions & 0 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<BitIntS7> : formatter<int8_t> {};

template <> struct formatter<BitIntU32> : formatter<uint32_t> {};
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

0 comments on commit 988e8a4

Please sign in to comment.