[libcxx-commits] [PATCH] D103433: [libc++][format] Adds integer formatter.
Mark de Wever via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jul 18 09:42:17 PDT 2021
Mordante marked 11 inline comments as done.
Mordante added a comment.
Thanks for the review!
================
Comment at: libcxx/include/__format/formatter_integer.h:111-116
+ using _To = long long;
+ if (__value < numeric_limits<_To>::min() ||
+ __value > numeric_limits<_To>::max())
+ __throw_format_error("128 bit value is outside of implemented range");
+
+ return _Base::format(static_cast<_To>(__value), __ctx);
----------------
vitaut wrote:
> AFAICS `to_chars` supports 128-bit integers (https://godbolt.org/z/7GTPrcq88) or am I missing something?
libc++ accepts 128-bit integers, but silently truncates them to 64-bit. IMO this is a bug and it's on my TODO to fix this.
It's visible in the generated assembly, it contains a`std::__1::__itoa::__pow10_64` lookup table instead of a `std::__1::__itoa::__pow10_128`.
================
Comment at: libcxx/include/__format/formatter_integral.h:88
+ __parser_locale_specific_form> {
+public:
+ /**
----------------
vitaut wrote:
> Why not make these protected to keep the public API of `formatter` specializations clean?
Good catch!
================
Comment at: libcxx/include/__format/formatter_integral.h:136
+ if (this->__alignment == _Flags::_Alignment::__default)
+ this->__alignment = _Flags::_Alignment::__left;
+ }
----------------
vitaut wrote:
> Here and elsewhere the default alignment should depend on the presentation type: http://eel.is/c++draft/format#tab:format.align
>
> i.e. `format("{:10}", true)` is left-aligned while `format("{:10d}", true)` is right-aligned.
This function is only called when a char is used for the char representation is selected.
Only the `__handle_integer` is used slightly different. That was basically done to use different formatting for
`format("{:6c}", 42)` and `format("{:6}", '*')`. But I'll adjust `__handle_integer`.
See my response to https://reviews.llvm.org/D103433/new/#inline-1010793 for more information.
================
Comment at: libcxx/include/__format/formatter_integral.h:304
+ if (__value < 0) {
+ __negative = true;
+ __r = __complement(__r);
----------------
vitaut wrote:
> Why store `__negative` instead of passing it as an argument to `__format_unsigned_integral`?
Basically to avoid passing an argument to a forwarding function. IMO both are a valid design choice. But as you mention in another comment "Among other things this would inhibit format string compilation in the future. Please remove.". So I'll apply your suggestion.
================
Comment at: libcxx/include/__format/formatter_integral.h:315-316
+ __format_char(integral auto __value, auto& __ctx) -> decltype(__ctx.out()) {
+ if (this->__alignment == _Flags::_Alignment::__default)
+ this->__alignment = _Flags::_Alignment::__right;
+
----------------
vitaut wrote:
> Isn't the alignment supposed to be resolved at parse time by calling `__handle_char` / `__handle_bool`?
Only partly, not for integers formatted as char. But I'll adjust this.
See my response to https://reviews.llvm.org/D103433/new/#inline-1010793 for more information.
================
Comment at: libcxx/include/__format/formatter_integral.h:329
+ if (__value >
+ static_cast<make_signed_t<_CharT>>(numeric_limits<_CharT>::max()))
+ __throw_format_error(
----------------
vitaut wrote:
> `_CharT` is already signed so `make_signed_t` doesn't do anything. Did you mean `make_unsigned_t`?
Should indeed be `make_unsigned_t`. Odd the compiler doesn't complain about a useless cast.
================
Comment at: libcxx/test/std/utilities/format/format.functions/tests.inc:392-393
+ // *** align-fill & width ***
+ // TODO FMT Validate whether this should be left aligned
+ test(STR("answer is ' *'"), STR("answer is '{:6c}'"), I(42));
+ test(STR("answer is ' *'"), STR("answer is '{:>6c}'"), I(42));
----------------
vitaut wrote:
> Per my earlier comment this should indeed be left-aligned.
I assumed that was intended. However my interpretation of the wording requires it to be right aligned:
`This is the default for arithmetic types other than charT and bool or when an integer presentation type is specified.`
My interpretation is that the supplied type in an aritmetic type, so this rule applies.
Do you agree with my interpretation?
I agree it's silly that the result of `format("{:6c}", 42);` differs from the result of `format("{:6}", '*');`. So I'll adjust it.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D103433/new/
https://reviews.llvm.org/D103433
More information about the libcxx-commits
mailing list