-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FP formatting at compile-time #2426
FP formatting at compile-time #2426
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seem to be a few general portability issues that need to be addressed.
ec4e993
to
5bdc572
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
JFI, I will get back on this PR about a week later. |
5bdc572
to
30f17cc
Compare
JFI, I'm back on this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move bigint
constexprification to a separate PR since it's pretty straightforward?
7087b17
to
2f74e6c
Compare
Thanks for the update, I'll take a look shortly. As a general comment, could you move all straightforward additions of |
Done with #2470. I will rebase this PR then, as soon as the new one is merged. |
f645dc0
to
ff0cf70
Compare
Hmm... looks like we have problems with |
We could probably create a fallback |
ae1aeca
to
5911f4f
Compare
Without creating a fallback, but I managed to make it compile on GCC 11. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly looks good, a few more comments inline.
include/fmt/format.h
Outdated
} else { | ||
FMT_ASSERT(false, "floating point type is not supported"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can if + assert be replaced with a static_assert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like no because the code under is_constant_evaluated()
check is still a part of function code. Without optimization, it's not even omitted, according to Compiler Explorer. So this constant-evaluated code has to be valid, and when it contains static assert, which is false, then the "runtime" version of this function becomes ill-formed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure but at the very least we could drop the else branch because non-IEEE is very uncommon and we would get a reasonable error anyway from signbit
below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you dropped it from isinf and isfinite but not here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you dropped it from isinf and isfinite but not here.
Only because you wrote:
we would get a reasonable error anyway from
signbit
below.
and it's signbit
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this line is about the std::signbit()
call below, then we won't get a reasonable error from there in some cases when FP numbers are non-IEEE and std::signbit()
manages to work with them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we won't get a reasonable error from there in some cases when FP numbers are non-IEEE and std::signbit() manages to work with them
That seems fine to me. We'll either get an error if signbit
is not constexpr or it will return the correct result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed also here.
5911f4f
to
9285127
Compare
ecdd2a8
to
0f18453
Compare
if (const_check(!is_supported_floating_point(value))) return out; | ||
float_specs fspecs = parse_float_type_spec(specs); | ||
fspecs.sign = specs.sign; | ||
if (std::signbit(value)) { // value < 0 is false for NaN so use signbit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you keep the comment since it may not be obvious to the reader why we don't use < 0
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment reverted back.
include/fmt/format.h
Outdated
@@ -1886,22 +1897,95 @@ auto write_float(OutputIt out, const DecimalFP& fp, | |||
}); | |||
} | |||
|
|||
template <typename Char> class fallback_digit_grouping { | |||
public: | |||
explicit constexpr fallback_digit_grouping(locale_ref, bool) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it needs to be explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's just copied from digit_grouping
, done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more nits, otherwise LGTM.
I will address these nits and resolve merge conflicts tomorrow. |
* works only with FMT_HEADER_ONLY * works only with float and double types (not long double)
0f18453
to
ea86c06
Compare
Unfortunately, my continuous benchmark pages broke at some point (June 10). I will try to fix them soon since I have access to this Raspberry finally 😄. |
Merged, thanks! |
* works only with FMT_HEADER_ONLY * works only with float and double types (not long double)
Few points for this PR, I mentioned some of them in #1895 (comment):
FMT_HEADER_ONLY
fast_float
s, even when specs passed, because of the sign checkcompile-fp-test
added withHEADER_ONLY
argument (tested via G++11 C++20 and MSVC 2019 C++20 configs on CI), thecompile-test
still uses static(/shared?) library