This adds a grouping option to the standard format spec, placed after the width and before the precision:
[[fill]align][sign][#][0][width][grouping][.precision][L][type]
grouping ::= "'" [" " | "," | "_" | "'"]Digits are grouped in threes counting from the decimal marker. The character
after ' selects the separator:
| Option | Separator | Groups | With L |
|---|---|---|---|
' | U+202F NARROW NO-BREAK SPACE | integer and fraction part | decimal point only |
' | U+0020 SPACE | integer and fraction part | decimal point only |
', '_ '' | , _ ' | integer part only | error |
fmt::format("{:'}", 1234567); // "1 234 567" (U+202F)
fmt::format("{:'.6f}", 1234567.891234); // "1 234 567.891 234" (U+202F)
fmt::format("{:',.6f}", 1234567.891234); // "1,234,567.891234"
fmt::format("{:010',}", 1234567); // "01,234,567"' alone follows ISO 80000-1 and the SI Brochure. For char, U+202F is
emitted as UTF-8 when the literal encoding is UTF-8 and falls back to U+0020
otherwise. Wide character types get a single code unit. Each separator counts
as one column, so fill and alignment work as usual.
The option applies to integers (d or no type) and to floating-point values
(e, E, f, F, g, G or no type). The exponent is never grouped. With
0, the padding zeros are grouped too. Other combinations are format errors,
and checked format strings report them at compile time.
FMT_ISO_GROUPING_MIN2=1 enables the four-digit exception, which leaves a part of
exactly four digits unsplit.
This is the prototype for the WG21 paper P4410R0, "Locale-independent digit
grouping in std::format", and is opened as a draft to collect feedback.
Tests cover every separator, all character types, the error cases,
compile-time checks, locales and the four-digit exception.
🤖 Generated with Claude Code
Activity
2This pull request is a draft
Merging is unavailable until it is marked ready for review.