Skip to content

Add support for _BitInt on clang - #4072

Merged
vitaut merged 1 commit into
fmtlib:masterfrom
Arghnews:support_bitint
Aug 29, 2024
Merged

Add support for _BitInt on clang#4072
vitaut merged 1 commit into
fmtlib:masterfrom
Arghnews:support_bitint

Conversation

@Arghnews

Copy link
Copy Markdown
Contributor

Issue #4007

Only enabled for clang >= 14 as that's all that supports _BitInt at the moment

We need a forwarding reference for map to be a "more specialized" match; const T&, T etc. are ambiguous.

I'm not too familiar, would there be a better way to do this by adding an entry into enum class type for _BitInts? Or this is fine?


Fyi this worked in version 9 because of this catch-all overload:

fmt/include/fmt/core.h

Lines 1506 to 1516 in a337011

template <typename T, typename U = remove_cvref_t<T>,
FMT_ENABLE_IF(!is_string<U>::value && !is_char<U>::value &&
!std::is_array<U>::value &&
!std::is_pointer<U>::value &&
!has_format_as<U>::value &&
(has_formatter<U, Context>::value ||
has_fallback_formatter<U, char_type>::value))>
FMT_CONSTEXPR FMT_INLINE auto map(T&& val)
-> decltype(this->do_map(std::forward<T>(val))) {
return do_map(std::forward<T>(val));
}

Which was then subsequently narrowed down to extended FP types (which "broke" the accidental support for this):

fmt/include/fmt/base.h

Lines 1527 to 1537 in 6a192f8

// is_fundamental is used to allow formatters for extended FP types.
template <typename T, typename U = remove_const_t<T>,
FMT_ENABLE_IF(
(std::is_class<U>::value || std::is_enum<U>::value ||
std::is_union<U>::value || std::is_fundamental<U>::value) &&
!has_to_string_view<U>::value && !is_char<U>::value &&
!is_named_arg<U>::value && !std::is_integral<U>::value &&
!std::is_arithmetic<format_as_t<U>>::value)>
FMT_MAP_API auto map(T& val) -> decltype(FMT_DECLTYPE_THIS do_map(val)) {
return do_map(val);
}

@Arghnews
Arghnews force-pushed the support_bitint branch 3 times, most recently from 903edfd to 3666cee Compare July 13, 2024 18:35
Comment thread include/fmt/base.h Outdated

@vitaut vitaut left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

Comment thread include/fmt/base.h Outdated
Comment thread include/fmt/base.h Outdated
Comment thread include/fmt/base.h Outdated
Comment thread test/format-test.cc Outdated
Comment thread include/fmt/base.h
@vitaut

vitaut commented Jul 27, 2024

Copy link
Copy Markdown
Contributor

@Arghnews, do you plan to update this PR or shall we close it for now (can be reopened later)?

@Arghnews

Copy link
Copy Markdown
Contributor Author

@Arghnews, do you plan to update this PR or shall we close it for now (can be reopened later)?

@vitaut Hi, sorry been busy and now I'm on holiday for 2 weeks, but will update once back and implement your feedback. I'd say leave it open and I'll update in 2-3 weeks, but it's up to you (can reopen of course). Cheers!

@vitaut

vitaut commented Jul 27, 2024

Copy link
Copy Markdown
Contributor

No hurry. Let's keep it open and enjoy your holiday!

@Arghnews
Arghnews force-pushed the support_bitint branch 2 times, most recently from 7322e2c to d8ad099 Compare August 26, 2024 14:00
@Arghnews

Copy link
Copy Markdown
Contributor Author

Hi,

Reworked this so that now fmtlib will format _BitInts up to 128 bits

Uses wider formatter ie. integer types are widened to 64bit if <= 64 bits wide (assume this is acceptable for performance)
If FMT_USE_INT128 then supports up to 128 bits

Can't write static_assert(fmt::is_formattable<signed_bitint<129>, char>{}, ""); as apple clang only allows up to 128 bits. BITINT_MAXWIDTH isn't defined, could check __apple_build_version__ but I just removed this test

Let me know any feedback @vitaut

@Arghnews
Arghnews requested a review from vitaut August 26, 2024 14:11

@vitaut vitaut left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments.

Comment thread include/fmt/base.h Outdated
Comment thread include/fmt/base.h Outdated
Comment thread include/fmt/base.h Outdated
Comment thread include/fmt/base.h Outdated
Comment thread include/fmt/format.h Outdated
Comment thread include/fmt/format.h Outdated
Comment thread test/format-test.cc Outdated
Comment thread test/format-test.cc Outdated
Comment thread test/format-test.cc
Comment thread include/fmt/format.h Outdated
Comment on lines +3959 to +3963
using type = conditional_t<
N <= 64, conditional_t<is_signed, int64_t, uint64_t>,
conditional_t<(N > 64 && N <= 128),
conditional_t<is_signed, __int128, unsigned __int128>,
void>>;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be moved to bitint_traits which would make number_of_bits and is_signed unnecessary.

@Arghnews Arghnews Aug 28, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be moved to bitint_traits which would make number_of_bits and is_signed unnecessary.

Nice suggestion, have done. Only thing to note, we must #include <cstdint> in base.h now, for the int64_t, if this is acceptable. This was already included in format.h

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use (unsigned) long long which is guaranteed to be at least 64-bit and avoid additional include.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use (unsigned) long long which is guaranteed to be at least 64-bit and avoid additional include.

Good shout, have made this change

Issue fmtlib#4007
Make _BitInt up to 128bits formattable
Note, libstdc++ is_signed doesn't work with _BitInt (so use own)
@vitaut
vitaut merged commit 5a0a373 into fmtlib:master Aug 29, 2024
@vitaut

vitaut commented Aug 29, 2024

Copy link
Copy Markdown
Contributor

Merged, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants