From Jason Turner

[format]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwssptnoo/{from.md → to.md} +222 -90
tmp/tmpwssptnoo/{from.md → to.md} RENAMED
@@ -16,10 +16,21 @@ namespace std {
16
 
17
  // [format.fmt.string], class template basic_format_string
18
  template<class charT, class... Args>
19
  struct basic_format_string;
20
 
 
 
 
 
 
 
 
 
 
 
 
21
  template<class... Args>
22
  using format_string = basic_format_string<char, type_identity_t<Args>...>;
23
  template<class... Args>
24
  using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
25
 
@@ -85,10 +96,14 @@ namespace std {
85
  size_t formatted_size(const locale& loc, wformat_string<Args...> fmt, Args&&... args);
86
 
87
  // [format.formatter], formatter
88
  template<class T, class charT = char> struct formatter;
89
 
 
 
 
 
90
  // [format.formattable], concept formattable
91
  template<class T, class charT>
92
  concept formattable = see below;
93
 
94
  template<class R, class charT>
@@ -136,26 +151,27 @@ namespace std {
136
  template<ranges::input_range R, class charT>
137
  requires (format_kind<R> != range_format::disabled) &&
138
  formattable<ranges::range_reference_t<R>, charT>
139
  struct formatter<R, charT> : range-default-formatter<format_kind<R>, R, charT> { };
140
 
 
 
 
 
141
  // [format.arguments], arguments
142
  // [format.arg], class template basic_format_arg
143
  template<class Context> class basic_format_arg;
144
 
145
- template<class Visitor, class Context>
146
- decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
147
-
148
  // [format.arg.store], class template format-arg-store
149
  template<class Context, class... Args> class format-arg-store; // exposition only
150
 
151
  template<class Context = format_context, class... Args>
152
  format-arg-store<Context, Args...>
153
- make_format_args(Args&&... fmt_args);
154
  template<class... Args>
155
  format-arg-store<wformat_context, Args...>
156
- make_wformat_args(Args&&... args);
157
 
158
  // [format.error], class format_error
159
  class format_error;
160
  }
161
  ```
@@ -164,11 +180,11 @@ The class template `format_to_n_result` has the template parameters,
164
  data members, and special members specified above. It has no base
165
  classes or members other than those specified.
166
 
167
  ### Format string <a id="format.string">[[format.string]]</a>
168
 
169
- #### In general <a id="format.string.general">[[format.string.general]]</a>
170
 
171
  A *format string* for arguments `args` is a (possibly empty) sequence of
172
  *replacement fields*, *escape sequences*, and characters other than `{`
173
  and `}`. Let `charT` be the character type of the format string. Each
174
  character that is not part of a replacement field or an escape sequence
@@ -214,11 +230,11 @@ format-specifier
214
  ':' format-spec
215
  ```
216
 
217
  ``` bnf
218
  format-spec
219
- as specified by the formatter specialization for the argument type
220
  ```
221
 
222
  The *arg-id* field specifies the index of the argument in `args` whose
223
  value is to be formatted and inserted into the output instead of the
224
  replacement field. If there is no argument with the index *arg-id* in
@@ -263,14 +279,14 @@ conform to the format specifications for the argument type referred to
263
  by *arg-id*, the string is not a format string for `args`.
264
 
265
  [*Example 3*:
266
 
267
  - For arithmetic, pointer, and string types the *format-spec* is
268
- interpreted as a *std-format-spec* as described in
269
  [[format.string.std]].
270
  - For chrono types the *format-spec* is interpreted as a
271
- *chrono-format-spec* as described in [[time.format]].
272
  - For user-defined `formatter` specializations, the behavior of the
273
  `parse` member function determines how the *format-spec* is
274
  interpreted.
275
 
276
  — *end example*]
@@ -325,11 +341,11 @@ precision
325
  '.' '{' arg-idₒₚₜ '}'
326
  ```
327
 
328
  ``` bnf
329
  type one of
330
- 'a A b B c d e E f F g G o p s x X ?'
331
  ```
332
 
333
  Field widths are specified in *field width units*; the number of column
334
  positions required to display a sequence of characters in a terminal.
335
  The *minimum field width* is the number of field width units a
@@ -372,20 +388,22 @@ string s5 = format("{:6d}", c); // value of s5 is "\ \ \ 120"
372
  string s6 = format("{:6}", true); // value of s6 is "true\ \ "
373
  string s7 = format("{:*<6.3}", "123456"); // value of s7 is "123***"
374
  string s8 = format("{:02}", 1234); // value of s8 is "1234"
375
  string s9 = format("{:*<}", "12"); // value of s9 is "12"
376
  string sA = format("{:*<6}", "12345678"); // value of sA is "12345678"
 
 
377
  ```
378
 
379
  — *end example*]
380
 
381
  [*Note 4*: The *fill*, *align*, and `0` options have no effect when the
382
  minimum field width is not greater than the estimated field width
383
  because padding width is `0` in that case. Since fill characters are
384
  assumed to have a field width of `1`, use of a character with a
385
  different field width can produce misaligned output. The
386
- U+1f921 (clown face) character has a field width of `2`. The examples
387
  above that include that character illustrate the effect of the field
388
  width when that character is used as a fill character as opposed to when
389
  it is used as a formatting argument. — *end note*]
390
 
391
  **Table: Meaning of align options** <a id="format.align">[format.align]</a>
@@ -437,15 +455,16 @@ contain a decimal-point character, even if no digits follow it.
437
  Normally, a decimal-point character appears in the result of these
438
  conversions only if a digit follows it. In addition, for `g` and `G`
439
  conversions, trailing zeros are not removed from the result.
440
 
441
  The `0` option is valid for arithmetic types other than `charT` and
442
- `bool` or when an integer presentation type is specified. For formatting
443
- arguments that have a value other than an infinity or a NaN, this option
444
- pads the formatted argument by inserting the `0` character n times
445
- following the sign or base prefix indicators (if any) where n is `0` if
446
- the *align* option is present and is the padding width otherwise.
 
447
 
448
  [*Example 3*:
449
 
450
  ``` cpp
451
  char c = 120;
@@ -460,13 +479,13 @@ string s4 = format("{:06}", inf); // value of s4 is "\ \ \ inf" (0 has no
460
  The *width* option specifies the minimum field width. If the *width*
461
  option is absent, the minimum field width is `0`.
462
 
463
  If `{ \opt{arg-id} }` is used in a *width* or *precision* option, the
464
  value of the corresponding formatting argument is used as the value of
465
- the option. If the corresponding formatting argument is not of standard
466
- signed or unsigned integer type, or its value is negative, an exception
467
- of type `format_error` is thrown.
468
 
469
  If *positive-integer* is used in a *width* option, the value of the
470
  *positive-integer* is interpreted as a decimal integer and used as the
471
  value of the option.
472
 
@@ -475,25 +494,25 @@ locale-independent, *implementation-defined* encoding. Implementations
475
  should use either UTF-8, UTF-16, or UTF-32, on platforms capable of
476
  displaying Unicode text in a terminal.
477
 
478
  [*Note 5*:
479
 
480
- This is the case for Windows[^2]
481
 
482
- -based and many POSIX-based operating systems.
483
 
484
  — *end note*]
485
 
486
  For a sequence of characters in UTF-8, UTF-16, or UTF-32, an
487
  implementation should use as its field width the sum of the field widths
488
  of the first code point of each extended grapheme cluster. Extended
489
  grapheme clusters are defined by UAX \#29 of the Unicode Standard. The
490
  following code points have a field width of 2:
491
 
492
  - any code point with the `East_Asian_Width="W"` or
493
- `East_Asian_Width="F"` Derived Extracted Property as described by UAX
494
- \#44 of the Unicode Standard
495
  - `U+4dc0` – `U+4dff` (Yijing Hexagram Symbols)
496
  - `U+1f300` – `U+1f5ff` (Miscellaneous Symbols and Pictographs)
497
  - `U+1f900` – `U+1f9ff` (Supplemental Symbols and Pictographs)
498
 
499
  The field width of all other code points is 1.
@@ -583,13 +602,13 @@ The available `charT` presentation types are specified in
583
  [[format.type.char]].
584
 
585
  **Table: Meaning of type options for `charT`** <a id="format.type.char">[format.type.char]</a>
586
 
587
  | Type | Meaning |
588
- | ------------------------------ | --------------------------------------------------------------------- |
589
  | none, `c` | Copies the character to the output. |
590
- | % `b`, `B`, `d`, `o`, `x`, `X` | As specified in [[format.type.int]]. |
591
  | % `?` | Copies the escaped character [[format.string.escaped]] to the output. |
592
 
593
 
594
  The available `bool` presentation types are specified in
595
  [[format.type.bool]].
@@ -635,10 +654,11 @@ are specified in [[format.type.ptr]].
635
  **Table: Meaning of type options for pointer types** <a id="format.type.ptr">[format.type.ptr]</a>
636
 
637
  | Type | Meaning |
638
  | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
639
  | none, `p` | If `uintptr_t` is defined, \begin{codeblock} to_chars(first, last, reinterpret_cast<uintptr_t>(value), 16) \end{codeblock} with the prefix `0x` inserted immediately before the output of `to_chars`; otherwise, implementation-defined. |
 
640
 
641
 
642
  ### Error reporting <a id="format.err.report">[[format.err.report]]</a>
643
 
644
  Formatting functions throw `format_error` if an argument `fmt` is passed
@@ -656,10 +676,11 @@ namespace std {
656
  private:
657
  basic_string_view<charT> str; // exposition only
658
 
659
  public:
660
  template<class T> consteval basic_format_string(const T& s);
 
661
 
662
  constexpr basic_string_view<charT> get() const noexcept { return str; }
663
  };
664
  }
665
  ```
@@ -906,12 +927,12 @@ argument type `T`, in [[formatter.basic]] and [[formatter]]:
906
  - `pc` is an lvalue of type `PC`, and
907
  - `fc` is an lvalue of type `FC`.
908
 
909
  `pc.begin()` points to the beginning of the *format-spec*
910
  [[format.string]] of the replacement field being formatted in the format
911
- string. If *format-spec* is empty then either `pc.begin() == pc.end()`
912
- or `*pc.begin() == '}'`.
913
 
914
  [*Note 1*: This allows formatters to emit meaningful error
915
  messages. — *end note*]
916
 
917
  **Table: \newoldconcept{Formatter} requirements** <a id="formatter">[formatter]</a>
@@ -920,10 +941,22 @@ messages. — *end note*]
920
  | ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
921
  | `f.format(t, fc)` | `FC::iterator` | Formats `t` according to the specifiers stored in `*this`, writes the output to `fc.out()`, and returns an iterator past the end of the output range. The output shall only depend on `t`, `fc.locale()`, `fc.arg(n)` for any value `n` of type `size_t`, and the range {[}`pc.begin()`, `pc.end()`{)} from the last call to `f.parse(pc)`. |
922
  | `f.format(u, fc)` | `FC::iterator` | As above, but does not modify `u`. |
923
 
924
 
 
 
 
 
 
 
 
 
 
 
 
 
925
  #### Concept <a id="format.formattable">[[format.formattable]]</a>
926
 
927
  Let `fmt-iter-for<charT>` be an unspecified type that models
928
  `output_iterator<const charT&>` [[iterator.concept.output]].
929
 
@@ -939,11 +972,11 @@ template<class T, class Context,
939
  { cf.format(t, fc) } -> same_as<typename Context::iterator>;
940
  };
941
 
942
  template<class T, class charT>
943
  concept formattable =
944
- formattable-with<remove_reference_t<T>, basic_format_context<fmt-iter-for<charT>>>;
945
  ```
946
 
947
  A type `T` and a character type `charT` model `formattable` if
948
  `formatter<remove_cvref_t<T>, charT>` meets the requirements
949
  [[formatter.requirements]] and, if `remove_reference_t<T>` is
@@ -991,16 +1024,37 @@ enabled specializations:
991
  template<> struct formatter<void*, charT>;
992
  template<> struct formatter<const void*, charT>;
993
  ```
994
 
995
  The `parse` member functions of these formatters interpret the format
996
- specification as a *std-format-spec* as described in
997
  [[format.string.std]].
998
 
999
- [*Note 1*: Specializations such as `formatter<wchar_t, char>` and
1000
- `formatter<const char*, wchar_t>` that would require implicit multibyte
1001
- / wide string or character conversion are disabled. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1002
 
1003
  For any types `T` and `charT` for which neither the library nor the user
1004
  provides an explicit or partial specialization of the class template
1005
  `formatter`, `formatter<T, charT>` is disabled.
1006
 
@@ -1022,10 +1076,11 @@ An enabled specialization `formatter<T, charT>` meets the requirements
1022
 
1023
  [*Example 1*:
1024
 
1025
  ``` cpp
1026
  #include <format>
 
1027
 
1028
  enum color { red, green, blue };
1029
  const char* color_names[] = { "red", "green", "blue" };
1030
 
1031
  template<> struct std::formatter<color> : std::formatter<const char*> {
@@ -1115,18 +1170,21 @@ the escaped string representation of a string of *C*, except that:
1115
  [*Example 1*:
1116
 
1117
  ``` cpp
1118
  string s0 = format("[{}]", "h\tllo"); // s0 has value: [h\ \ \ \ llo]
1119
  string s1 = format("[{:?}]", "h\tllo"); // s1 has value: ["h\ tllo"]
 
1120
  string s3 = format("[{:?}, {:?}]", '\'', '"'); // s3 has value: ['\ '', '"']
1121
 
1122
  // The following examples assume use of the UTF-8 encoding
1123
  string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9));
1124
  // s4 has value: ["\ u{0\ \ n \ t \ u{2} \ u{1b}"]}
1125
  string s5 = format("[{:?}]", "\xc3\x28"); // invalid UTF-8, s5 has value: ["\ x{c3\("]}
1126
- string s7 = format("[{:?}]", "\u0301"); // s7 has value: ["\ u{301"]}
1127
- string s8 = format("[{:?}]", "\\\u0301"); // s8 has value: ["\ \ \ u{301"]}
 
 
1128
  ```
1129
 
1130
  — *end example*]
1131
 
1132
  #### Class template `basic_format_parse_context` <a id="format.parse.ctx">[[format.parse.ctx]]</a>
@@ -1135,11 +1193,11 @@ string s8 = format("[{:?}]", "\\\u0301"); // s8 has value: ["\ \ \ u{3
1135
  namespace std {
1136
  template<class charT>
1137
  class basic_format_parse_context {
1138
  public:
1139
  using char_type = charT;
1140
- using const_iterator = typename basic_string_view<charT>::const_iterator;
1141
  using iterator = const_iterator;
1142
 
1143
  private:
1144
  iterator begin_; // exposition only
1145
  iterator end_; // exposition only
@@ -1147,37 +1205,49 @@ namespace std {
1147
  indexing indexing_; // exposition only
1148
  size_t next_arg_id_; // exposition only
1149
  size_t num_args_; // exposition only
1150
 
1151
  public:
1152
- constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
1153
- size_t num_args = 0) noexcept;
1154
  basic_format_parse_context(const basic_format_parse_context&) = delete;
1155
  basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
1156
 
1157
  constexpr const_iterator begin() const noexcept;
1158
  constexpr const_iterator end() const noexcept;
1159
  constexpr void advance_to(const_iterator it);
1160
 
1161
  constexpr size_t next_arg_id();
1162
  constexpr void check_arg_id(size_t id);
 
 
 
 
 
1163
  };
1164
  }
1165
  ```
1166
 
1167
  An instance of `basic_format_parse_context` holds the format string
1168
- parsing state consisting of the format string range being parsed and the
1169
- argument counter for automatic indexing.
 
 
 
 
1170
 
1171
  ``` cpp
1172
- constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
1173
- size_t num_args = 0) noexcept;
1174
  ```
1175
 
1176
  *Effects:* Initializes `begin_` with `fmt.begin()`, `end_` with
1177
  `fmt.end()`, `indexing_` with `unknown`, `next_arg_id_` with `0`, and
1178
- `num_args_` with `num_args`.
 
 
 
 
 
1179
 
1180
  ``` cpp
1181
  constexpr const_iterator begin() const noexcept;
1182
  ```
1183
 
@@ -1207,12 +1277,14 @@ constexpr size_t next_arg_id();
1207
  if (indexing_ == unknown)
1208
  indexing_ = automatic;
1209
  return next_arg_id_++;
1210
  ```
1211
 
1212
- *Throws:* `format_error` if `indexing_ == manual` is `true` which
1213
- indicates mixing of automatic and manual argument indexing.
 
 
1214
 
1215
  *Remarks:* Let *`cur-arg-id`* be the value of `next_arg_id_` prior to
1216
  this call. Call expressions where *`cur-arg-id`*` >= num_args_` is
1217
  `true` are not core constant expressions [[expr.const]].
1218
 
@@ -1225,25 +1297,67 @@ constexpr void check_arg_id(size_t id);
1225
  ``` cpp
1226
  if (indexing_ == unknown)
1227
  indexing_ = manual;
1228
  ```
1229
 
1230
- *Throws:* `format_error` if `indexing_ == automatic` is `true` which
1231
- indicates mixing of automatic and manual argument indexing.
1232
 
1233
- *Remarks:* Call expressions where `id >= num_args_` is `true` are not
1234
- core constant expressions [[expr.const]].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1235
 
1236
  #### Class template `basic_format_context` <a id="format.context">[[format.context]]</a>
1237
 
1238
  ``` cpp
1239
  namespace std {
1240
  template<class Out, class charT>
1241
  class basic_format_context {
1242
  basic_format_args<basic_format_context> args_; // exposition only
1243
  Out out_; // exposition only
1244
 
 
 
 
1245
  public:
1246
  using iterator = Out;
1247
  using char_type = charT;
1248
  template<class T> using formatter_type = formatter<T, charT>;
1249
 
@@ -1257,10 +1371,14 @@ namespace std {
1257
  ```
1258
 
1259
  An instance of `basic_format_context` holds formatting state consisting
1260
  of the formatting arguments and the output iterator.
1261
 
 
 
 
 
1262
  `Out` shall model `output_iterator<const charT&>`.
1263
 
1264
  `format_context` is an alias for a specialization of
1265
  `basic_format_context` with an output iterator that appends to `string`,
1266
  such as `back_insert_iterator<string>`. Similarly, `wformat_context` is
@@ -1307,33 +1425,34 @@ template<> struct std::formatter<S> {
1307
  size_t width_arg_id = 0;
1308
 
1309
  // Parses a width argument id in the format { digit }.
1310
  constexpr auto parse(format_parse_context& ctx) {
1311
  auto iter = ctx.begin();
 
1312
  auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; };
1313
  if (get_char() != '{')
1314
  return iter;
1315
  ++iter;
1316
  char c = get_char();
1317
- if (!isdigit(c) || (++iter, get_char()) != '}')
1318
  throw format_error("invalid format");
1319
  width_arg_id = c - '0';
1320
  ctx.check_arg_id(width_arg_id);
1321
  return ++iter;
1322
  }
1323
 
1324
  // Formats an S with width given by the argument width_arg_id.
1325
  auto format(S s, format_context& ctx) const {
1326
- int width = visit_format_arg([](auto value) -> int {
1327
  if constexpr (!is_integral_v<decltype(value)>)
1328
  throw format_error("width is not integral");
1329
  else if (value < 0 || value > numeric_limits<int>::max())
1330
  throw format_error("invalid width");
1331
  else
1332
  return value;
1333
- }, ctx.arg(width_arg_id));
1334
- return format_to(ctx.out(), "{0:x<{1}}", s.value, width);
1335
  }
1336
  };
1337
 
1338
  std::string s = std::format("{0:{1}}", S{42}, 10); // value of s is "xxxxxxxx42"
1339
  ```
@@ -1492,15 +1611,17 @@ closing-bracket_ = closing;
1492
  template<class ParseContext>
1493
  constexpr typename ParseContext::iterator
1494
  parse(ParseContext& ctx);
1495
  ```
1496
 
1497
- *Effects:* Parses the format specifier as a *range-format-spec* and
1498
- stores the parsed specifiers in `*this`. The values of
1499
- *opening-bracket\_*, *closing-bracket\_*, and *separator\_* are modified
1500
- if and only if required by the *range-type* or the `n` option, if
1501
- present. If:
 
 
1502
 
1503
  - the *range-type* is neither `s` nor `?s`,
1504
  - *`underlying_`*`.set_debug_format()` is a valid expression, and
1505
  - there is no *range-underlying-spec*,
1506
 
@@ -1765,11 +1886,11 @@ namespace std {
1765
  class basic_format_arg {
1766
  public:
1767
  class handle;
1768
 
1769
  private:
1770
- using char_type = typename Context::char_type; // exposition only
1771
 
1772
  variant<monostate, bool, char_type,
1773
  int, unsigned int, long long int, unsigned long long int,
1774
  float, double, long double,
1775
  const char_type*, basic_string_view<char_type>,
@@ -1779,10 +1900,15 @@ namespace std {
1779
 
1780
  public:
1781
  basic_format_arg() noexcept;
1782
 
1783
  explicit operator bool() const noexcept;
 
 
 
 
 
1784
  };
1785
  }
1786
  ```
1787
 
1788
  An instance of `basic_format_arg` provides access to a formatting
@@ -1802,17 +1928,17 @@ template<class T> explicit basic_format_arg(T& v) noexcept;
1802
  ```
1803
 
1804
  *Constraints:* `T` satisfies `formattable-with<Context>`.
1805
 
1806
  *Preconditions:* If `decay_t<T>` is `char_type*` or `const char_type*`,
1807
- `static_cast<const char_type*>(v)` points to a NTCTS [[defns.ntcts]].
1808
 
1809
  *Effects:* Let `TD` be `remove_const_t<T>`.
1810
 
1811
  - If `TD` is `bool` or `char_type`, initializes `value` with `v`;
1812
  - otherwise, if `TD` is `char` and `char_type` is `wchar_t`, initializes
1813
- `value` with `static_cast<wchar_t>(v)`;
1814
  - otherwise, if `TD` is a signed integer type [[basic.fundamental]] and
1815
  `sizeof(TD) <= sizeof(int)`, initializes `value` with
1816
  `static_cast<int>(v)`;
1817
  - otherwise, if `TD` is an unsigned integer type and
1818
  `sizeof(TD) <= sizeof(unsigned int)`, initializes `value` with
@@ -1843,10 +1969,26 @@ is ill-formed unless the user provides an enabled specialization of
1843
  explicit operator bool() const noexcept;
1844
  ```
1845
 
1846
  *Returns:* `!holds_alternative<monostate>(value)`.
1847
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1848
  The class `handle` allows formatting an object of a user-defined type.
1849
 
1850
  ``` cpp
1851
  namespace std {
1852
  template<class Context>
@@ -1855,12 +1997,10 @@ namespace std {
1855
  void (*format_)(basic_format_parse_context<char_type>&,
1856
  Context&, const void*); // exposition only
1857
 
1858
  template<class T> explicit handle(T& val) noexcept; // exposition only
1859
 
1860
- friend class basic_format_arg<Context>; // exposition only
1861
-
1862
  public:
1863
  void format(basic_format_parse_context<char_type>&, Context& ctx) const;
1864
  };
1865
  }
1866
  ```
@@ -1893,18 +2033,10 @@ Let
1893
  void format(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx) const;
1894
  ```
1895
 
1896
  *Effects:* Equivalent to: `format_(parse_ctx, format_ctx, ptr_);`
1897
 
1898
- ``` cpp
1899
- template<class Visitor, class Context>
1900
- decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
1901
- ```
1902
-
1903
- *Effects:* Equivalent to:
1904
- `return visit(std::forward<Visitor>(vis), arg.value);`
1905
-
1906
  #### Class template *`format-arg-store`* <a id="format.arg.store">[[format.arg.store]]</a>
1907
 
1908
  ``` cpp
1909
  namespace std {
1910
  template<class Context, class... Args>
@@ -1916,25 +2048,25 @@ namespace std {
1916
 
1917
  An instance of *`format-arg-store`* stores formatting arguments.
1918
 
1919
  ``` cpp
1920
  template<class Context = format_context, class... Args>
1921
- format-arg-store<Context, Args...> make_format_args(Args&&... fmt_args);
1922
  ```
1923
 
1924
  *Preconditions:* The type
1925
- `typename Context::template formatter_type<remove_cvref_t<``Tᵢ``>>`
1926
  meets the requirements [[formatter.requirements]] for each `Tᵢ` in
1927
  `Args`.
1928
 
1929
  *Returns:* An object of type *`format-arg-store`*`<Context, Args...>`
1930
  whose *args* data member is initialized with
1931
  `{basic_format_arg<Context>(fmt_args)...}`.
1932
 
1933
  ``` cpp
1934
  template<class... Args>
1935
- format-arg-store<wformat_context, Args...> make_wformat_args(Args&&... args);
1936
  ```
1937
 
1938
  *Effects:* Equivalent to:
1939
  `return make_format_args<wformat_context>(args...);`
1940
 
@@ -1946,12 +2078,10 @@ namespace std {
1946
  class basic_format_args {
1947
  size_t size_; // exposition only
1948
  const basic_format_arg<Context>* data_; // exposition only
1949
 
1950
  public:
1951
- basic_format_args() noexcept;
1952
-
1953
  template<class... Args>
1954
  basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
1955
 
1956
  basic_format_arg<Context> get(size_t i) const noexcept;
1957
  };
@@ -1960,22 +2090,19 @@ namespace std {
1960
  basic_format_args(format-arg-store<Context, Args...>) -> basic_format_args<Context>;
1961
  }
1962
  ```
1963
 
1964
  An instance of `basic_format_args` provides access to formatting
1965
- arguments. Implementations should optimize the representation of
1966
- `basic_format_args` for a small number of formatting arguments.
 
 
 
1967
 
1968
  [*Note 1*: For example, by storing indices of type alternatives
1969
  separately from values and packing the former. — *end note*]
1970
 
1971
- ``` cpp
1972
- basic_format_args() noexcept;
1973
- ```
1974
-
1975
- *Effects:* Initializes `size_` with `0`.
1976
-
1977
  ``` cpp
1978
  template<class... Args>
1979
  basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
1980
  ```
1981
 
@@ -2015,10 +2142,14 @@ namespace std {
2015
 
2016
  template<class FormatContext>
2017
  typename FormatContext::iterator
2018
  format(see below& elems, FormatContext& ctx) const;
2019
  };
 
 
 
 
2020
  }
2021
  ```
2022
 
2023
  The `parse` member functions of these formatters interpret the format
2024
  specification as a *tuple-format-spec* according to the following
@@ -2084,16 +2215,17 @@ closing-bracket_ = closing;
2084
  template<class ParseContext>
2085
  constexpr typename ParseContext::iterator
2086
  parse(ParseContext& ctx);
2087
  ```
2088
 
2089
- *Effects:* Parses the format specifier as a *tuple-format-spec* and
2090
  stores the parsed specifiers in `*this`. The values of
2091
  *opening-bracket\_*, *closing-bracket\_*, and *separator\_* are modified
2092
  if and only if required by the *tuple-type*, if present. For each
2093
- element *`e`* in *underlying\_*, if *`e`*`.set_debug_format()` is a
2094
- valid expression, calls *`e`*`.set_debug_format()`.
 
2095
 
2096
  *Returns:* An iterator past the end of the *tuple-format-spec*.
2097
 
2098
  ``` cpp
2099
  template<class FormatContext>
@@ -2123,26 +2255,26 @@ the *tuple-format-spec*:
2123
 
2124
  ``` cpp
2125
  namespace std {
2126
  class format_error : public runtime_error {
2127
  public:
2128
- explicit format_error(const string& what_arg);
2129
- explicit format_error(const char* what_arg);
2130
  };
2131
  }
2132
  ```
2133
 
2134
  The class `format_error` defines the type of objects thrown as
2135
  exceptions to report errors from the formatting library.
2136
 
2137
  ``` cpp
2138
- format_error(const string& what_arg);
2139
  ```
2140
 
2141
  *Ensures:* `strcmp(what(), what_arg.c_str()) == 0`.
2142
 
2143
  ``` cpp
2144
- format_error(const char* what_arg);
2145
  ```
2146
 
2147
  *Ensures:* `strcmp(what(), what_arg) == 0`.
2148
 
 
16
 
17
  // [format.fmt.string], class template basic_format_string
18
  template<class charT, class... Args>
19
  struct basic_format_string;
20
 
21
+ template<class charT> struct runtime-format-string { // exposition only
22
+ private:
23
+ basic_string_view<charT> str; // exposition only
24
+ public:
25
+ runtime-format-string(basic_string_view<charT> s) noexcept : str(s) {}
26
+ runtime-format-string(const runtime-format-string&) = delete;
27
+ runtime-format-string& operator=(const runtime-format-string&) = delete;
28
+ };
29
+ runtime-format-string<char> runtime_format(string_view fmt) noexcept { return fmt; }
30
+ runtime-format-string<wchar_t> runtime_format(wstring_view fmt) noexcept { return fmt; }
31
+
32
  template<class... Args>
33
  using format_string = basic_format_string<char, type_identity_t<Args>...>;
34
  template<class... Args>
35
  using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
36
 
 
96
  size_t formatted_size(const locale& loc, wformat_string<Args...> fmt, Args&&... args);
97
 
98
  // [format.formatter], formatter
99
  template<class T, class charT = char> struct formatter;
100
 
101
+ // [format.formatter.locking], formatter locking
102
+ template<class T>
103
+ constexpr bool enable_nonlocking_formatter_optimization = false;
104
+
105
  // [format.formattable], concept formattable
106
  template<class T, class charT>
107
  concept formattable = see below;
108
 
109
  template<class R, class charT>
 
151
  template<ranges::input_range R, class charT>
152
  requires (format_kind<R> != range_format::disabled) &&
153
  formattable<ranges::range_reference_t<R>, charT>
154
  struct formatter<R, charT> : range-default-formatter<format_kind<R>, R, charT> { };
155
 
156
+ template<ranges::input_range R>
157
+ requires (format_kind<R> != range_format::disabled)
158
+ constexpr bool enable_nonlocking_formatter_optimization<R> = false;
159
+
160
  // [format.arguments], arguments
161
  // [format.arg], class template basic_format_arg
162
  template<class Context> class basic_format_arg;
163
 
 
 
 
164
  // [format.arg.store], class template format-arg-store
165
  template<class Context, class... Args> class format-arg-store; // exposition only
166
 
167
  template<class Context = format_context, class... Args>
168
  format-arg-store<Context, Args...>
169
+ make_format_args(Args&... fmt_args);
170
  template<class... Args>
171
  format-arg-store<wformat_context, Args...>
172
+ make_wformat_args(Args&... args);
173
 
174
  // [format.error], class format_error
175
  class format_error;
176
  }
177
  ```
 
180
  data members, and special members specified above. It has no base
181
  classes or members other than those specified.
182
 
183
  ### Format string <a id="format.string">[[format.string]]</a>
184
 
185
+ #### General <a id="format.string.general">[[format.string.general]]</a>
186
 
187
  A *format string* for arguments `args` is a (possibly empty) sequence of
188
  *replacement fields*, *escape sequences*, and characters other than `{`
189
  and `}`. Let `charT` be the character type of the format string. Each
190
  character that is not part of a replacement field or an escape sequence
 
230
  ':' format-spec
231
  ```
232
 
233
  ``` bnf
234
  format-spec
235
+ as specified by the formatter specialization for the argument type; cannot start with '}'
236
  ```
237
 
238
  The *arg-id* field specifies the index of the argument in `args` whose
239
  value is to be formatted and inserted into the output instead of the
240
  replacement field. If there is no argument with the index *arg-id* in
 
279
  by *arg-id*, the string is not a format string for `args`.
280
 
281
  [*Example 3*:
282
 
283
  - For arithmetic, pointer, and string types the *format-spec* is
284
+ interpreted as a *std-format-spec* as described in 
285
  [[format.string.std]].
286
  - For chrono types the *format-spec* is interpreted as a
287
+ *chrono-format-spec* as described in  [[time.format]].
288
  - For user-defined `formatter` specializations, the behavior of the
289
  `parse` member function determines how the *format-spec* is
290
  interpreted.
291
 
292
  — *end example*]
 
341
  '.' '{' arg-idₒₚₜ '}'
342
  ```
343
 
344
  ``` bnf
345
  type one of
346
+ 'a A b B c d e E f F g G o p P s x X ?'
347
  ```
348
 
349
  Field widths are specified in *field width units*; the number of column
350
  positions required to display a sequence of characters in a terminal.
351
  The *minimum field width* is the number of field width units a
 
388
  string s6 = format("{:6}", true); // value of s6 is "true\ \ "
389
  string s7 = format("{:*<6.3}", "123456"); // value of s7 is "123***"
390
  string s8 = format("{:02}", 1234); // value of s8 is "1234"
391
  string s9 = format("{:*<}", "12"); // value of s9 is "12"
392
  string sA = format("{:*<6}", "12345678"); // value of sA is "12345678"
393
+ string sB = format("{:\importexample[-2pt]{example_05}\kern0.75pt^6}", "x"); // value of sB is "\importexample[-2pt]{example_05\importexample[-2pt]{example_05}x\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}"}
394
+ string sC = format("{:*^6}", "\importexample[-2pt]{example_05}\kern0.75pt\importexample[-2pt]{example_05}\kern0.75pt\importexample[-2pt]{example_05}\kern0.75pt"); // value of sC is "\importexample[-2pt]{example_05\importexample[-2pt]{example_05}\importexample[-2pt]{example_05}"}
395
  ```
396
 
397
  — *end example*]
398
 
399
  [*Note 4*: The *fill*, *align*, and `0` options have no effect when the
400
  minimum field width is not greater than the estimated field width
401
  because padding width is `0` in that case. Since fill characters are
402
  assumed to have a field width of `1`, use of a character with a
403
  different field width can produce misaligned output. The
404
+ (U+1f921 (clown face)) character has a field width of `2`. The examples
405
  above that include that character illustrate the effect of the field
406
  width when that character is used as a fill character as opposed to when
407
  it is used as a formatting argument. — *end note*]
408
 
409
  **Table: Meaning of align options** <a id="format.align">[format.align]</a>
 
455
  Normally, a decimal-point character appears in the result of these
456
  conversions only if a digit follows it. In addition, for `g` and `G`
457
  conversions, trailing zeros are not removed from the result.
458
 
459
  The `0` option is valid for arithmetic types other than `charT` and
460
+ `bool`, pointer types, or when an integer presentation type is
461
+ specified. For formatting arguments that have a value other than an
462
+ infinity or a NaN, this option pads the formatted argument by inserting
463
+ the `0` character n times following the sign or base prefix indicators
464
+ (if any) where n is `0` if the *align* option is present and is the
465
+ padding width otherwise.
466
 
467
  [*Example 3*:
468
 
469
  ``` cpp
470
  char c = 120;
 
479
  The *width* option specifies the minimum field width. If the *width*
480
  option is absent, the minimum field width is `0`.
481
 
482
  If `{ \opt{arg-id} }` is used in a *width* or *precision* option, the
483
  value of the corresponding formatting argument is used as the value of
484
+ the option. The option is valid only if the corresponding formatting
485
+ argument is of standard signed or unsigned integer type. If its value is
486
+ negative, an exception of type `format_error` is thrown.
487
 
488
  If *positive-integer* is used in a *width* option, the value of the
489
  *positive-integer* is interpreted as a decimal integer and used as the
490
  value of the option.
491
 
 
494
  should use either UTF-8, UTF-16, or UTF-32, on platforms capable of
495
  displaying Unicode text in a terminal.
496
 
497
  [*Note 5*:
498
 
499
+ This is the case for Windows®-based[^25]
500
 
501
+ and many POSIX-based operating systems.
502
 
503
  — *end note*]
504
 
505
  For a sequence of characters in UTF-8, UTF-16, or UTF-32, an
506
  implementation should use as its field width the sum of the field widths
507
  of the first code point of each extended grapheme cluster. Extended
508
  grapheme clusters are defined by UAX \#29 of the Unicode Standard. The
509
  following code points have a field width of 2:
510
 
511
  - any code point with the `East_Asian_Width="W"` or
512
+ `East_Asian_Width="F"` property as described by UAX \#44 of the
513
+ Unicode Standard
514
  - `U+4dc0` – `U+4dff` (Yijing Hexagram Symbols)
515
  - `U+1f300` – `U+1f5ff` (Miscellaneous Symbols and Pictographs)
516
  - `U+1f900` – `U+1f9ff` (Supplemental Symbols and Pictographs)
517
 
518
  The field width of all other code points is 1.
 
602
  [[format.type.char]].
603
 
604
  **Table: Meaning of type options for `charT`** <a id="format.type.char">[format.type.char]</a>
605
 
606
  | Type | Meaning |
607
+ | ------------------------------ | ---------------------------------------------------------------------------------------------------------- |
608
  | none, `c` | Copies the character to the output. |
609
+ | % `b`, `B`, `d`, `o`, `x`, `X` | As specified in [[format.type.int]] with `value` converted to the unsigned version of the underlying type. |
610
  | % `?` | Copies the escaped character [[format.string.escaped]] to the output. |
611
 
612
 
613
  The available `bool` presentation types are specified in
614
  [[format.type.bool]].
 
654
  **Table: Meaning of type options for pointer types** <a id="format.type.ptr">[format.type.ptr]</a>
655
 
656
  | Type | Meaning |
657
  | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
658
  | none, `p` | If `uintptr_t` is defined, \begin{codeblock} to_chars(first, last, reinterpret_cast<uintptr_t>(value), 16) \end{codeblock} with the prefix `0x` inserted immediately before the output of `to_chars`; otherwise, implementation-defined. |
659
+ | `P` | The same as `p`, except that it uses uppercase letters for digits above `9` and the base prefix is `0X`. |
660
 
661
 
662
  ### Error reporting <a id="format.err.report">[[format.err.report]]</a>
663
 
664
  Formatting functions throw `format_error` if an argument `fmt` is passed
 
676
  private:
677
  basic_string_view<charT> str; // exposition only
678
 
679
  public:
680
  template<class T> consteval basic_format_string(const T& s);
681
+ basic_format_string(runtime-format-string<charT> s) noexcept : str(s.str) {}
682
 
683
  constexpr basic_string_view<charT> get() const noexcept { return str; }
684
  };
685
  }
686
  ```
 
927
  - `pc` is an lvalue of type `PC`, and
928
  - `fc` is an lvalue of type `FC`.
929
 
930
  `pc.begin()` points to the beginning of the *format-spec*
931
  [[format.string]] of the replacement field being formatted in the format
932
+ string. If *format-spec* is not present or empty then either
933
+ `pc.begin() == pc.end()` or `*pc.begin() == '}'`.
934
 
935
  [*Note 1*: This allows formatters to emit meaningful error
936
  messages. — *end note*]
937
 
938
  **Table: \newoldconcept{Formatter} requirements** <a id="formatter">[formatter]</a>
 
941
  | ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
942
  | `f.format(t, fc)` | `FC::iterator` | Formats `t` according to the specifiers stored in `*this`, writes the output to `fc.out()`, and returns an iterator past the end of the output range. The output shall only depend on `t`, `fc.locale()`, `fc.arg(n)` for any value `n` of type `size_t`, and the range {[}`pc.begin()`, `pc.end()`{)} from the last call to `f.parse(pc)`. |
943
  | `f.format(u, fc)` | `FC::iterator` | As above, but does not modify `u`. |
944
 
945
 
946
+ #### Formatter locking <a id="format.formatter.locking">[[format.formatter.locking]]</a>
947
+
948
+ ``` cpp
949
+ template<class T>
950
+ constexpr bool enable_nonlocking_formatter_optimization = false;
951
+ ```
952
+
953
+ *Remarks:* Pursuant to [[namespace.std]], users may specialize
954
+ `enable_nonlocking_formatter_optimization` for cv-unqualified
955
+ program-defined types. Such specializations shall be usable in constant
956
+ expressions [[expr.const]] and have type `const bool`.
957
+
958
  #### Concept <a id="format.formattable">[[format.formattable]]</a>
959
 
960
  Let `fmt-iter-for<charT>` be an unspecified type that models
961
  `output_iterator<const charT&>` [[iterator.concept.output]].
962
 
 
972
  { cf.format(t, fc) } -> same_as<typename Context::iterator>;
973
  };
974
 
975
  template<class T, class charT>
976
  concept formattable =
977
+ formattable-with<remove_reference_t<T>, basic_format_context<fmt-iter-for<charT>, charT>>;
978
  ```
979
 
980
  A type `T` and a character type `charT` model `formattable` if
981
  `formatter<remove_cvref_t<T>, charT>` meets the requirements
982
  [[formatter.requirements]] and, if `remove_reference_t<T>` is
 
1024
  template<> struct formatter<void*, charT>;
1025
  template<> struct formatter<const void*, charT>;
1026
  ```
1027
 
1028
  The `parse` member functions of these formatters interpret the format
1029
+ specification as a *std-format-spec* as described in 
1030
  [[format.string.std]].
1031
 
1032
+ Unless specified otherwise, for each type `T` for which a `formatter`
1033
+ specialization is provided by the library, each of the headers provides
1034
+ the following specialization:
1035
+
1036
+ ``` cpp
1037
+ template<> inline constexpr bool enable_nonlocking_formatter_optimization<T> = true;
1038
+ ```
1039
+
1040
+ [*Note 1*: Specializations such as `formatter<wchar_t, char>` that
1041
+ would require implicit multibyte / wide string or character conversion
1042
+ are disabled. — *end note*]
1043
+
1044
+ The header `<format>` provides the following disabled specializations:
1045
+
1046
+ - The string type specializations
1047
+ ``` cpp
1048
+ template<> struct formatter<char*, wchar_t>;
1049
+ template<> struct formatter<const char*, wchar_t>;
1050
+ template<size_t N> struct formatter<char[N], wchar_t>;
1051
+ template<class traits, class Allocator>
1052
+ struct formatter<basic_string<char, traits, Allocator>, wchar_t>;
1053
+ template<class traits>
1054
+ struct formatter<basic_string_view<char, traits>, wchar_t>;
1055
+ ```
1056
 
1057
  For any types `T` and `charT` for which neither the library nor the user
1058
  provides an explicit or partial specialization of the class template
1059
  `formatter`, `formatter<T, charT>` is disabled.
1060
 
 
1076
 
1077
  [*Example 1*:
1078
 
1079
  ``` cpp
1080
  #include <format>
1081
+ #include <string>
1082
 
1083
  enum color { red, green, blue };
1084
  const char* color_names[] = { "red", "green", "blue" };
1085
 
1086
  template<> struct std::formatter<color> : std::formatter<const char*> {
 
1170
  [*Example 1*:
1171
 
1172
  ``` cpp
1173
  string s0 = format("[{}]", "h\tllo"); // s0 has value: [h\ \ \ \ llo]
1174
  string s1 = format("[{:?}]", "h\tllo"); // s1 has value: ["h\ tllo"]
1175
+ string s2 = format("[{:?}]", "\importexample[-2.5pt]{example_01}"); \kern1.25pt// s2 has value: ["\importexample[-2.5pt]{example_01"]}
1176
  string s3 = format("[{:?}, {:?}]", '\'', '"'); // s3 has value: ['\ '', '"']
1177
 
1178
  // The following examples assume use of the UTF-8 encoding
1179
  string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9));
1180
  // s4 has value: ["\ u{0\ \ n \ t \ u{2} \ u{1b}"]}
1181
  string s5 = format("[{:?}]", "\xc3\x28"); // invalid UTF-8, s5 has value: ["\ x{c3\("]}
1182
+ string s6 = format("[{:?}]", "\importexample{example_02}"); \kern0.75pt// s6 has value: ["\importexample{example_03{u}{200d}\importexample{example_04}"]}
1183
+ string s7 = format("[{:?}]", "\u0301"); // s7 has value: ["\ u{301\"]}
1184
+ string s8 = format("[{:?}]", "\\\u0301"); // s8 has value: ["\ \ \ u{301\"]}
1185
+ string s9 = format("[{:?}]", "e\u0301\u0323"); // s9 has value: ["\importexample[-2pt]{example_06"]}
1186
  ```
1187
 
1188
  — *end example*]
1189
 
1190
  #### Class template `basic_format_parse_context` <a id="format.parse.ctx">[[format.parse.ctx]]</a>
 
1193
  namespace std {
1194
  template<class charT>
1195
  class basic_format_parse_context {
1196
  public:
1197
  using char_type = charT;
1198
+ using const_iterator = basic_string_view<charT>::const_iterator;
1199
  using iterator = const_iterator;
1200
 
1201
  private:
1202
  iterator begin_; // exposition only
1203
  iterator end_; // exposition only
 
1205
  indexing indexing_; // exposition only
1206
  size_t next_arg_id_; // exposition only
1207
  size_t num_args_; // exposition only
1208
 
1209
  public:
1210
+ constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt) noexcept;
 
1211
  basic_format_parse_context(const basic_format_parse_context&) = delete;
1212
  basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
1213
 
1214
  constexpr const_iterator begin() const noexcept;
1215
  constexpr const_iterator end() const noexcept;
1216
  constexpr void advance_to(const_iterator it);
1217
 
1218
  constexpr size_t next_arg_id();
1219
  constexpr void check_arg_id(size_t id);
1220
+
1221
+ template<class... Ts>
1222
+ constexpr void check_dynamic_spec(size_t id) noexcept;
1223
+ constexpr void check_dynamic_spec_integral(size_t id) noexcept;
1224
+ constexpr void check_dynamic_spec_string(size_t id) noexcept;
1225
  };
1226
  }
1227
  ```
1228
 
1229
  An instance of `basic_format_parse_context` holds the format string
1230
+ parsing state, consisting of the format string range being parsed and
1231
+ the argument counter for automatic indexing.
1232
+
1233
+ If a program declares an explicit or partial specialization of
1234
+ `basic_format_parse_context`, the program is ill-formed, no diagnostic
1235
+ required.
1236
 
1237
  ``` cpp
1238
+ constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt) noexcept;
 
1239
  ```
1240
 
1241
  *Effects:* Initializes `begin_` with `fmt.begin()`, `end_` with
1242
  `fmt.end()`, `indexing_` with `unknown`, `next_arg_id_` with `0`, and
1243
+ `num_args_` with `0`.
1244
+
1245
+ [*Note 1*: Any call to `next_arg_id`, `check_arg_id`, or
1246
+ `check_dynamic_spec` on an instance of `basic_format_parse_context`
1247
+ initialized using this constructor is not a core constant
1248
+ expression. — *end note*]
1249
 
1250
  ``` cpp
1251
  constexpr const_iterator begin() const noexcept;
1252
  ```
1253
 
 
1277
  if (indexing_ == unknown)
1278
  indexing_ = automatic;
1279
  return next_arg_id_++;
1280
  ```
1281
 
1282
+ *Throws:* `format_error` if `indexing_ == manual` is `true`.
1283
+
1284
+ [*Note 2*: This indicates mixing of automatic and manual argument
1285
+ indexing. — *end note*]
1286
 
1287
  *Remarks:* Let *`cur-arg-id`* be the value of `next_arg_id_` prior to
1288
  this call. Call expressions where *`cur-arg-id`*` >= num_args_` is
1289
  `true` are not core constant expressions [[expr.const]].
1290
 
 
1297
  ``` cpp
1298
  if (indexing_ == unknown)
1299
  indexing_ = manual;
1300
  ```
1301
 
1302
+ *Throws:* `format_error` if `indexing_ == automatic` is `true`.
 
1303
 
1304
+ [*Note 3*: This indicates mixing of automatic and manual argument
1305
+ indexing. *end note*]
1306
+
1307
+ *Remarks:* A call to this function is a core constant
1308
+ expression [[expr.const]] only if `id < num_args_` is `true`.
1309
+
1310
+ ``` cpp
1311
+ template<class... Ts>
1312
+ constexpr void check_dynamic_spec(size_t id) noexcept;
1313
+ ```
1314
+
1315
+ *Mandates:* `sizeof...(Ts)` ≥ 1. The types in `Ts...` are unique. Each
1316
+ type in `Ts...` is one of `bool`, `char_type`, `int`, `unsigned int`,
1317
+ `long long int`, `unsigned long long int`, `float`, `double`,
1318
+ `long double`, `const char_type*`, `basic_string_view<char_type>`, or
1319
+ `const void*`.
1320
+
1321
+ *Remarks:* A call to this function is a core constant expression only if
1322
+
1323
+ - `id < num_args_` is `true` and
1324
+ - the type of the corresponding format argument (after conversion to
1325
+ `basic_format_arg<Context>`) is one of the types in `Ts...`.
1326
+
1327
+ ``` cpp
1328
+ constexpr void check_dynamic_spec_integral(size_t id) noexcept;
1329
+ ```
1330
+
1331
+ *Effects:* Equivalent to:
1332
+
1333
+ ``` cpp
1334
+ check_dynamic_spec<int, unsigned int, long long int, unsigned long long int>(id);
1335
+ ```
1336
+
1337
+ ``` cpp
1338
+ constexpr void check_dynamic_spec_string(size_t id) noexcept;
1339
+ ```
1340
+
1341
+ *Effects:* Equivalent to:
1342
+
1343
+ ``` cpp
1344
+ check_dynamic_spec<const char_type*, basic_string_view<char_type>>(id);
1345
+ ```
1346
 
1347
  #### Class template `basic_format_context` <a id="format.context">[[format.context]]</a>
1348
 
1349
  ``` cpp
1350
  namespace std {
1351
  template<class Out, class charT>
1352
  class basic_format_context {
1353
  basic_format_args<basic_format_context> args_; // exposition only
1354
  Out out_; // exposition only
1355
 
1356
+ basic_format_context(const basic_format_context&) = delete;
1357
+ basic_format_context& operator=(const basic_format_context&) = delete;
1358
+
1359
  public:
1360
  using iterator = Out;
1361
  using char_type = charT;
1362
  template<class T> using formatter_type = formatter<T, charT>;
1363
 
 
1371
  ```
1372
 
1373
  An instance of `basic_format_context` holds formatting state consisting
1374
  of the formatting arguments and the output iterator.
1375
 
1376
+ If a program declares an explicit or partial specialization of
1377
+ `basic_format_context`, the program is ill-formed, no diagnostic
1378
+ required.
1379
+
1380
  `Out` shall model `output_iterator<const charT&>`.
1381
 
1382
  `format_context` is an alias for a specialization of
1383
  `basic_format_context` with an output iterator that appends to `string`,
1384
  such as `back_insert_iterator<string>`. Similarly, `wformat_context` is
 
1425
  size_t width_arg_id = 0;
1426
 
1427
  // Parses a width argument id in the format { digit }.
1428
  constexpr auto parse(format_parse_context& ctx) {
1429
  auto iter = ctx.begin();
1430
+ auto is_digit = [](auto c) { return c >= '0' && c <= '9'; };
1431
  auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; };
1432
  if (get_char() != '{')
1433
  return iter;
1434
  ++iter;
1435
  char c = get_char();
1436
+ if (!is_digit(c) || (++iter, get_char()) != '}')
1437
  throw format_error("invalid format");
1438
  width_arg_id = c - '0';
1439
  ctx.check_arg_id(width_arg_id);
1440
  return ++iter;
1441
  }
1442
 
1443
  // Formats an S with width given by the argument width_arg_id.
1444
  auto format(S s, format_context& ctx) const {
1445
+ int width = ctx.arg(width_arg_id).visit([](auto value) -> int {
1446
  if constexpr (!is_integral_v<decltype(value)>)
1447
  throw format_error("width is not integral");
1448
  else if (value < 0 || value > numeric_limits<int>::max())
1449
  throw format_error("invalid width");
1450
  else
1451
  return value;
1452
+ });
1453
+ return format_to(ctx.out(), "{0:x>{1}}", s.value, width);
1454
  }
1455
  };
1456
 
1457
  std::string s = std::format("{0:{1}}", S{42}, 10); // value of s is "xxxxxxxx42"
1458
  ```
 
1611
  template<class ParseContext>
1612
  constexpr typename ParseContext::iterator
1613
  parse(ParseContext& ctx);
1614
  ```
1615
 
1616
+ *Effects:* Parses the format specifiers as a *range-format-spec* and
1617
+ stores the parsed specifiers in `*this`. Calls
1618
+ *`underlying_`*`.parse(ctx)` to parse *format-spec* in
1619
+ *range-format-spec* or, if the latter is not present, an empty
1620
+ *format-spec*. The values of *opening-bracket\_*, *closing-bracket\_*,
1621
+ and *separator\_* are modified if and only if required by the
1622
+ *range-type* or the `n` option, if present. If:
1623
 
1624
  - the *range-type* is neither `s` nor `?s`,
1625
  - *`underlying_`*`.set_debug_format()` is a valid expression, and
1626
  - there is no *range-underlying-spec*,
1627
 
 
1886
  class basic_format_arg {
1887
  public:
1888
  class handle;
1889
 
1890
  private:
1891
+ using char_type = Context::char_type; // exposition only
1892
 
1893
  variant<monostate, bool, char_type,
1894
  int, unsigned int, long long int, unsigned long long int,
1895
  float, double, long double,
1896
  const char_type*, basic_string_view<char_type>,
 
1900
 
1901
  public:
1902
  basic_format_arg() noexcept;
1903
 
1904
  explicit operator bool() const noexcept;
1905
+
1906
+ template<class Visitor>
1907
+ decltype(auto) visit(this basic_format_arg arg, Visitor&& vis);
1908
+ template<class R, class Visitor>
1909
+ R visit(this basic_format_arg arg, Visitor&& vis);
1910
  };
1911
  }
1912
  ```
1913
 
1914
  An instance of `basic_format_arg` provides access to a formatting
 
1928
  ```
1929
 
1930
  *Constraints:* `T` satisfies `formattable-with<Context>`.
1931
 
1932
  *Preconditions:* If `decay_t<T>` is `char_type*` or `const char_type*`,
1933
+ `static_cast<const char_type*>(v)` points to an NTCTS [[defns.ntcts]].
1934
 
1935
  *Effects:* Let `TD` be `remove_const_t<T>`.
1936
 
1937
  - If `TD` is `bool` or `char_type`, initializes `value` with `v`;
1938
  - otherwise, if `TD` is `char` and `char_type` is `wchar_t`, initializes
1939
+ `value` with `static_cast<wchar_t>(static_cast<unsigned char>(v))`;
1940
  - otherwise, if `TD` is a signed integer type [[basic.fundamental]] and
1941
  `sizeof(TD) <= sizeof(int)`, initializes `value` with
1942
  `static_cast<int>(v)`;
1943
  - otherwise, if `TD` is an unsigned integer type and
1944
  `sizeof(TD) <= sizeof(unsigned int)`, initializes `value` with
 
1969
  explicit operator bool() const noexcept;
1970
  ```
1971
 
1972
  *Returns:* `!holds_alternative<monostate>(value)`.
1973
 
1974
+ ``` cpp
1975
+ template<class Visitor>
1976
+ decltype(auto) visit(this basic_format_arg arg, Visitor&& vis);
1977
+ ```
1978
+
1979
+ *Effects:* Equivalent to:
1980
+ `return arg.value.visit(std::forward<Visitor>(vis));`
1981
+
1982
+ ``` cpp
1983
+ template<class R, class Visitor>
1984
+ R visit(this basic_format_arg arg, Visitor&& vis);
1985
+ ```
1986
+
1987
+ *Effects:* Equivalent to:
1988
+ `return arg.value.visit<R>(std::forward<Visitor>(vis));`
1989
+
1990
  The class `handle` allows formatting an object of a user-defined type.
1991
 
1992
  ``` cpp
1993
  namespace std {
1994
  template<class Context>
 
1997
  void (*format_)(basic_format_parse_context<char_type>&,
1998
  Context&, const void*); // exposition only
1999
 
2000
  template<class T> explicit handle(T& val) noexcept; // exposition only
2001
 
 
 
2002
  public:
2003
  void format(basic_format_parse_context<char_type>&, Context& ctx) const;
2004
  };
2005
  }
2006
  ```
 
2033
  void format(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx) const;
2034
  ```
2035
 
2036
  *Effects:* Equivalent to: `format_(parse_ctx, format_ctx, ptr_);`
2037
 
 
 
 
 
 
 
 
 
2038
  #### Class template *`format-arg-store`* <a id="format.arg.store">[[format.arg.store]]</a>
2039
 
2040
  ``` cpp
2041
  namespace std {
2042
  template<class Context, class... Args>
 
2048
 
2049
  An instance of *`format-arg-store`* stores formatting arguments.
2050
 
2051
  ``` cpp
2052
  template<class Context = format_context, class... Args>
2053
+ format-arg-store<Context, Args...> make_format_args(Args&... fmt_args);
2054
  ```
2055
 
2056
  *Preconditions:* The type
2057
+ `typename Context::template formatter_type<remove_const_t<``Tᵢ``>>`
2058
  meets the requirements [[formatter.requirements]] for each `Tᵢ` in
2059
  `Args`.
2060
 
2061
  *Returns:* An object of type *`format-arg-store`*`<Context, Args...>`
2062
  whose *args* data member is initialized with
2063
  `{basic_format_arg<Context>(fmt_args)...}`.
2064
 
2065
  ``` cpp
2066
  template<class... Args>
2067
+ format-arg-store<wformat_context, Args...> make_wformat_args(Args&... args);
2068
  ```
2069
 
2070
  *Effects:* Equivalent to:
2071
  `return make_format_args<wformat_context>(args...);`
2072
 
 
2078
  class basic_format_args {
2079
  size_t size_; // exposition only
2080
  const basic_format_arg<Context>* data_; // exposition only
2081
 
2082
  public:
 
 
2083
  template<class... Args>
2084
  basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
2085
 
2086
  basic_format_arg<Context> get(size_t i) const noexcept;
2087
  };
 
2090
  basic_format_args(format-arg-store<Context, Args...>) -> basic_format_args<Context>;
2091
  }
2092
  ```
2093
 
2094
  An instance of `basic_format_args` provides access to formatting
2095
+ arguments.
2096
+
2097
+ *Recommended practice:* Implementations should optimize the
2098
+ representation of `basic_format_args` for a small number of formatting
2099
+ arguments.
2100
 
2101
  [*Note 1*: For example, by storing indices of type alternatives
2102
  separately from values and packing the former. — *end note*]
2103
 
 
 
 
 
 
 
2104
  ``` cpp
2105
  template<class... Args>
2106
  basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
2107
  ```
2108
 
 
2142
 
2143
  template<class FormatContext>
2144
  typename FormatContext::iterator
2145
  format(see below& elems, FormatContext& ctx) const;
2146
  };
2147
+
2148
+ template<class... Ts>
2149
+ constexpr bool enable_nonlocking_formatter_optimization<pair-or-tuple<Ts...>> =
2150
+ (enable_nonlocking_formatter_optimization<Ts> && ...);
2151
  }
2152
  ```
2153
 
2154
  The `parse` member functions of these formatters interpret the format
2155
  specification as a *tuple-format-spec* according to the following
 
2215
  template<class ParseContext>
2216
  constexpr typename ParseContext::iterator
2217
  parse(ParseContext& ctx);
2218
  ```
2219
 
2220
+ *Effects:* Parses the format specifiers as a *tuple-format-spec* and
2221
  stores the parsed specifiers in `*this`. The values of
2222
  *opening-bracket\_*, *closing-bracket\_*, and *separator\_* are modified
2223
  if and only if required by the *tuple-type*, if present. For each
2224
+ element *`e`* in *underlying\_*, calls *`e`*`.parse(ctx)` to parse an
2225
+ empty *format-spec* and, if *`e`*`.set_debug_format()` is a valid
2226
+ expression, calls *`e`*`.set_debug_format()`.
2227
 
2228
  *Returns:* An iterator past the end of the *tuple-format-spec*.
2229
 
2230
  ``` cpp
2231
  template<class FormatContext>
 
2255
 
2256
  ``` cpp
2257
  namespace std {
2258
  class format_error : public runtime_error {
2259
  public:
2260
+ constexpr explicit format_error(const string& what_arg);
2261
+ constexpr explicit format_error(const char* what_arg);
2262
  };
2263
  }
2264
  ```
2265
 
2266
  The class `format_error` defines the type of objects thrown as
2267
  exceptions to report errors from the formatting library.
2268
 
2269
  ``` cpp
2270
+ constexpr format_error(const string& what_arg);
2271
  ```
2272
 
2273
  *Ensures:* `strcmp(what(), what_arg.c_str()) == 0`.
2274
 
2275
  ``` cpp
2276
+ constexpr format_error(const char* what_arg);
2277
  ```
2278
 
2279
  *Ensures:* `strcmp(what(), what_arg) == 0`.
2280