From Jason Turner

[format.formatter]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp85qhxpbc/{from.md → to.md} +165 -39
tmp/tmp85qhxpbc/{from.md → to.md} RENAMED
@@ -1,26 +1,29 @@
1
  ### Formatter <a id="format.formatter">[[format.formatter]]</a>
2
 
3
  #### Formatter requirements <a id="formatter.requirements">[[formatter.requirements]]</a>
4
 
5
- A type `F` meets the requirements if:
6
 
7
- - it meets the
8
  - *Cpp17DefaultConstructible* ([[cpp17.defaultconstructible]]),
9
  - *Cpp17CopyConstructible* ([[cpp17.copyconstructible]]),
10
- - *Cpp17CopyAssignable* ([[cpp17.copyassignable]]), and
 
11
  - *Cpp17Destructible* ([[cpp17.destructible]])
12
 
13
- requirements,
14
- - it is swappable [[swappable.requirements]] for lvalues, and
15
- - the expressions shown in [[formatter]] are valid and have the
16
- indicated semantics.
 
 
17
 
18
  Given character type `charT`, output iterator type `Out`, and formatting
19
- argument type `T`, in [[formatter]]:
20
 
21
- - `f` is a value of type `F`,
 
22
  - `u` is an lvalue of type `T`,
23
  - `t` is a value of a type convertible to (possibly const) `T`,
24
  - `PC` is `basic_format_parse_context<charT>`,
25
  - `FC` is `basic_format_context<Out, charT>`,
26
  - `pc` is an lvalue of type `PC`, and
@@ -32,35 +35,70 @@ string. If *format-spec* is empty then either `pc.begin() == pc.end()`
32
  or `*pc.begin() == '}'`.
33
 
34
  [*Note 1*: This allows formatters to emit meaningful error
35
  messages. — *end note*]
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  #### Formatter specializations <a id="format.formatter.spec">[[format.formatter.spec]]</a>
38
 
39
  The functions defined in [[format.functions]] use specializations of the
40
  class template `formatter` to format individual arguments.
41
 
42
  Let `charT` be either `char` or `wchar_t`. Each specialization of
43
- `formatter` is either enabled or disabled, as described below.
 
 
 
 
 
 
44
 
45
- [*Note 1*: Enabled specializations meet the requirements, and disabled
46
- specializations do not. — *end note*]
47
-
48
- Each header that declares the template `formatter` provides the
49
- following enabled specializations:
50
-
51
- - The specializations
52
  ``` cpp
53
  template<> struct formatter<char, char>;
54
  template<> struct formatter<char, wchar_t>;
55
  template<> struct formatter<wchar_t, wchar_t>;
56
  ```
57
- - For each `charT`, the string type specializations
58
  ``` cpp
59
  template<> struct formatter<charT*, charT>;
60
  template<> struct formatter<const charT*, charT>;
61
- template<size_t N> struct formatter<const charT[N], charT>;
62
  template<class traits, class Allocator>
63
  struct formatter<basic_string<charT, traits, Allocator>, charT>;
64
  template<class traits>
65
  struct formatter<basic_string_view<charT, traits>, charT>;
66
  ```
@@ -79,21 +117,21 @@ following enabled specializations:
79
 
80
  The `parse` member functions of these formatters interpret the format
81
  specification as a *std-format-spec* as described in
82
  [[format.string.std]].
83
 
84
- [*Note 2*: Specializations such as `formatter<wchar_t, char>` and
85
  `formatter<const char*, wchar_t>` that would require implicit multibyte
86
  / wide string or character conversion are disabled. — *end note*]
87
 
88
  For any types `T` and `charT` for which neither the library nor the user
89
  provides an explicit or partial specialization of the class template
90
  `formatter`, `formatter<T, charT>` is disabled.
91
 
92
  If the library provides an explicit or partial specialization of
93
- `formatter<T, charT>`, that specialization is enabled except as noted
94
- otherwise.
95
 
96
  If `F` is a disabled specialization of `formatter`, these values are
97
  `false`:
98
 
99
  - `is_default_constructible_v<F>`,
@@ -112,11 +150,11 @@ An enabled specialization `formatter<T, charT>` meets the requirements
112
 
113
  enum color { red, green, blue };
114
  const char* color_names[] = { "red", "green", "blue" };
115
 
116
  template<> struct std::formatter<color> : std::formatter<const char*> {
117
- auto format(color c, format_context& ctx) {
118
  return formatter<const char*>::format(color_names[c], ctx);
119
  }
120
  };
121
 
122
  struct err {};
@@ -127,10 +165,95 @@ std::string s2 = std::format("{}", red); // OK, user-provided formatter
127
  std::string s3 = std::format("{}", err{}); // error: disabled formatter
128
  ```
129
 
130
  — *end example*]
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  #### Class template `basic_format_parse_context` <a id="format.parse.ctx">[[format.parse.ctx]]</a>
133
 
134
  ``` cpp
135
  namespace std {
136
  template<class charT>
@@ -199,37 +322,41 @@ constexpr void advance_to(const_iterator it);
199
 
200
  ``` cpp
201
  constexpr size_t next_arg_id();
202
  ```
203
 
204
- *Effects:* If `indexing_ != manual`, equivalent to:
205
 
206
  ``` cpp
207
  if (indexing_ == unknown)
208
  indexing_ = automatic;
209
  return next_arg_id_++;
210
  ```
211
 
212
- *Throws:* `format_error` if `indexing_ == manual` which indicates mixing
213
- of automatic and manual argument indexing.
 
 
 
 
214
 
215
  ``` cpp
216
  constexpr void check_arg_id(size_t id);
217
  ```
218
 
219
- *Effects:* If `indexing_ != automatic`, equivalent to:
220
 
221
  ``` cpp
222
  if (indexing_ == unknown)
223
  indexing_ = manual;
224
  ```
225
 
226
- *Throws:* `format_error` if `indexing_ == automatic` which indicates
227
- mixing of automatic and manual argument indexing.
228
 
229
- *Remarks:* Call expressions where `id >= num_args_` are not core
230
- constant expressions [[expr.const]].
231
 
232
  #### Class template `basic_format_context` <a id="format.context">[[format.context]]</a>
233
 
234
  ``` cpp
235
  namespace std {
@@ -241,11 +368,11 @@ namespace std {
241
  public:
242
  using iterator = Out;
243
  using char_type = charT;
244
  template<class T> using formatter_type = formatter<T, charT>;
245
 
246
- basic_format_arg<basic_format_context> arg(size_t id) const;
247
  std::locale locale();
248
 
249
  iterator out();
250
  void advance_to(iterator it);
251
  };
@@ -261,19 +388,18 @@ of the formatting arguments and the output iterator.
261
  `basic_format_context` with an output iterator that appends to `string`,
262
  such as `back_insert_iterator<string>`. Similarly, `wformat_context` is
263
  an alias for a specialization of `basic_format_context` with an output
264
  iterator that appends to `wstring`.
265
 
266
- [*Note 1*: For a given type `charT`, implementations are encouraged to
267
  provide a single instantiation of `basic_format_context` for appending
268
  to `basic_string<charT>`, `vector<charT>`, or any other container with
269
  contiguous storage by wrapping those in temporary objects with a uniform
270
- interface (such as a `span<charT>`) and polymorphic
271
- reallocation. — *end note*]
272
 
273
  ``` cpp
274
- basic_format_arg<basic_format_context> arg(size_t id) const;
275
  ```
276
 
277
  *Returns:* `args_.get(id)`.
278
 
279
  ``` cpp
@@ -285,17 +411,17 @@ takes one, and `std::locale()` otherwise.
285
 
286
  ``` cpp
287
  iterator out();
288
  ```
289
 
290
- *Returns:* `out_`.
291
 
292
  ``` cpp
293
  void advance_to(iterator it);
294
  ```
295
 
296
- *Effects:* Equivalent to: `out_ = it;`
297
 
298
  [*Example 1*:
299
 
300
  ``` cpp
301
  struct S { int value; };
@@ -317,11 +443,11 @@ template<> struct std::formatter<S> {
317
  ctx.check_arg_id(width_arg_id);
318
  return ++iter;
319
  }
320
 
321
  // Formats an S with width given by the argument width_arg_id.
322
- auto format(S s, format_context& ctx) {
323
  int width = visit_format_arg([](auto value) -> int {
324
  if constexpr (!is_integral_v<decltype(value)>)
325
  throw format_error("width is not integral");
326
  else if (value < 0 || value > numeric_limits<int>::max())
327
  throw format_error("invalid width");
 
1
  ### Formatter <a id="format.formatter">[[format.formatter]]</a>
2
 
3
  #### Formatter requirements <a id="formatter.requirements">[[formatter.requirements]]</a>
4
 
5
+ A type `F` meets the requirements if it meets the
6
 
 
7
  - *Cpp17DefaultConstructible* ([[cpp17.defaultconstructible]]),
8
  - *Cpp17CopyConstructible* ([[cpp17.copyconstructible]]),
9
+ - *Cpp17CopyAssignable* ([[cpp17.copyassignable]]),
10
+ - *Cpp17Swappable* [[swappable.requirements]], and
11
  - *Cpp17Destructible* ([[cpp17.destructible]])
12
 
13
+ requirements, and the expressions shown in [[formatter.basic]] are valid
14
+ and have the indicated semantics.
15
+
16
+ A type `F` meets the requirements if it meets the requirements and the
17
+ expressions shown in [[formatter]] are valid and have the indicated
18
+ semantics.
19
 
20
  Given character type `charT`, output iterator type `Out`, and formatting
21
+ argument type `T`, in [[formatter.basic]] and [[formatter]]:
22
 
23
+ - `f` is a value of type (possibly const) `F`,
24
+ - `g` is an lvalue of type `F`,
25
  - `u` is an lvalue of type `T`,
26
  - `t` is a value of a type convertible to (possibly const) `T`,
27
  - `PC` is `basic_format_parse_context<charT>`,
28
  - `FC` is `basic_format_context<Out, charT>`,
29
  - `pc` is an lvalue of type `PC`, and
 
35
  or `*pc.begin() == '}'`.
36
 
37
  [*Note 1*: This allows formatters to emit meaningful error
38
  messages. — *end note*]
39
 
40
+ **Table: \newoldconcept{Formatter} requirements** <a id="formatter">[formatter]</a>
41
+
42
+ | Expression | Return type | Requirement |
43
+ | ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44
+ | `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)`. |
45
+ | `f.format(u, fc)` | `FC::iterator` | As above, but does not modify `u`. |
46
+
47
+
48
+ #### Concept <a id="format.formattable">[[format.formattable]]</a>
49
+
50
+ Let `fmt-iter-for<charT>` be an unspecified type that models
51
+ `output_iterator<const charT&>` [[iterator.concept.output]].
52
+
53
+ ``` cpp
54
+ template<class T, class Context,
55
+ class Formatter = typename Context::template formatter_type<remove_const_t<T>>>
56
+ concept formattable-with = // exposition only
57
+ semiregular<Formatter> &&
58
+ requires(Formatter& f, const Formatter& cf, T&& t, Context fc,
59
+ basic_format_parse_context<typename Context::char_type> pc)
60
+ {
61
+ { f.parse(pc) } -> same_as<typename decltype(pc)::iterator>;
62
+ { cf.format(t, fc) } -> same_as<typename Context::iterator>;
63
+ };
64
+
65
+ template<class T, class charT>
66
+ concept formattable =
67
+ formattable-with<remove_reference_t<T>, basic_format_context<fmt-iter-for<charT>>>;
68
+ ```
69
+
70
+ A type `T` and a character type `charT` model `formattable` if
71
+ `formatter<remove_cvref_t<T>, charT>` meets the requirements
72
+ [[formatter.requirements]] and, if `remove_reference_t<T>` is
73
+ const-qualified, the requirements.
74
+
75
  #### Formatter specializations <a id="format.formatter.spec">[[format.formatter.spec]]</a>
76
 
77
  The functions defined in [[format.functions]] use specializations of the
78
  class template `formatter` to format individual arguments.
79
 
80
  Let `charT` be either `char` or `wchar_t`. Each specialization of
81
+ `formatter` is either enabled or disabled, as described below. A
82
+ *debug-enabled* specialization of `formatter` additionally provides a
83
+ public, constexpr, non-static member function `set_debug_format()` which
84
+ modifies the state of the `formatter` to be as if the type of the
85
+ *std-format-spec* parsed by the last call to `parse` were `?`. Each
86
+ header that declares the template `formatter` provides the following
87
+ enabled specializations:
88
 
89
+ - The debug-enabled specializations
 
 
 
 
 
 
90
  ``` cpp
91
  template<> struct formatter<char, char>;
92
  template<> struct formatter<char, wchar_t>;
93
  template<> struct formatter<wchar_t, wchar_t>;
94
  ```
95
+ - For each `charT`, the debug-enabled string type specializations
96
  ``` cpp
97
  template<> struct formatter<charT*, charT>;
98
  template<> struct formatter<const charT*, charT>;
99
+ template<size_t N> struct formatter<charT[N], charT>;
100
  template<class traits, class Allocator>
101
  struct formatter<basic_string<charT, traits, Allocator>, charT>;
102
  template<class traits>
103
  struct formatter<basic_string_view<charT, traits>, charT>;
104
  ```
 
117
 
118
  The `parse` member functions of these formatters interpret the format
119
  specification as a *std-format-spec* as described in
120
  [[format.string.std]].
121
 
122
+ [*Note 1*: Specializations such as `formatter<wchar_t, char>` and
123
  `formatter<const char*, wchar_t>` that would require implicit multibyte
124
  / wide string or character conversion are disabled. — *end note*]
125
 
126
  For any types `T` and `charT` for which neither the library nor the user
127
  provides an explicit or partial specialization of the class template
128
  `formatter`, `formatter<T, charT>` is disabled.
129
 
130
  If the library provides an explicit or partial specialization of
131
+ `formatter<T, charT>`, that specialization is enabled and meets the
132
+ requirements except as noted otherwise.
133
 
134
  If `F` is a disabled specialization of `formatter`, these values are
135
  `false`:
136
 
137
  - `is_default_constructible_v<F>`,
 
150
 
151
  enum color { red, green, blue };
152
  const char* color_names[] = { "red", "green", "blue" };
153
 
154
  template<> struct std::formatter<color> : std::formatter<const char*> {
155
+ auto format(color c, format_context& ctx) const {
156
  return formatter<const char*>::format(color_names[c], ctx);
157
  }
158
  };
159
 
160
  struct err {};
 
165
  std::string s3 = std::format("{}", err{}); // error: disabled formatter
166
  ```
167
 
168
  — *end example*]
169
 
170
+ #### Formatting escaped characters and strings <a id="format.string.escaped">[[format.string.escaped]]</a>
171
+
172
+ A character or string can be formatted as *escaped* to make it more
173
+ suitable for debugging or for logging.
174
+
175
+ The escaped string *E* representation of a string *S* is constructed by
176
+ encoding a sequence of characters as follows. The associated character
177
+ encoding *CE* for `charT` ([[lex.string.literal]]) is used to both
178
+ interpret *S* and construct *E*.
179
+
180
+ - U+0022 (quotation mark) (`"`) is appended to *E*.
181
+ - For each code unit sequence *X* in *S* that either encodes a single
182
+ character, is a shift sequence, or is a sequence of ill-formed code
183
+ units, processing is in order as follows:
184
+ - If *X* encodes a single character *C*, then:
185
+ - If *C* is one of the characters in [[format.escape.sequences]],
186
+ then the two characters shown as the corresponding escape sequence
187
+ are appended to *E*.
188
+ - Otherwise, if *C* is not U+0020 (space) and
189
+ - *CE* is UTF-8, UTF-16, or UTF-32 and *C* corresponds to a
190
+ Unicode scalar value whose Unicode property `General_Category`
191
+ has a value in the groups `Separator` (`Z`) or `Other` (`C`), as
192
+ described by UAX \#44 of the Unicode Standard, or
193
+ - *CE* is UTF-8, UTF-16, or UTF-32 and *C* corresponds to a
194
+ Unicode scalar value with the Unicode property
195
+ `Grapheme_Extend=Yes` as described by UAX \#44 of the Unicode
196
+ Standard and *C* is not immediately preceded in *S* by a
197
+ character *P* appended to *E* without translation to an escape
198
+ sequence, or
199
+ - *CE* is neither UTF-8, UTF-16, nor UTF-32 and *C* is one of an
200
+ implementation-defined set of separator or non-printable
201
+ characters
202
+
203
+ then the sequence `\u{hex-digit-sequence}` is appended to *E*,
204
+ where `hex-digit-sequence` is the shortest hexadecimal
205
+ representation of *C* using lower-case hexadecimal digits.
206
+ - Otherwise, *C* is appended to *E*.
207
+ - Otherwise, if *X* is a shift sequence, the effect on *E* and further
208
+ decoding of *S* is unspecified. *Recommended practice:* A shift
209
+ sequence should be represented in *E* such that the original code
210
+ unit sequence of *S* can be reconstructed.
211
+ - Otherwise (*X* is a sequence of ill-formed code units), each code
212
+ unit *U* is appended to *E* in order as the sequence
213
+ `\x{hex-digit-sequence}`, where `hex-digit-sequence` is the shortest
214
+ hexadecimal representation of *U* using lower-case hexadecimal
215
+ digits.
216
+ - Finally, U+0022 (quotation mark) (`"`) is appended to *E*.
217
+
218
+ **Table: Mapping of characters to escape sequences** <a id="format.escape.sequences">[format.escape.sequences]</a>
219
+
220
+ | Character | Escape sequence |
221
+ | ----------------------------- | --------------- |
222
+ | U+0009 (character tabulation) | `\t` |
223
+ | % U+000a (line feed) | `\n` |
224
+ | % U+000d (carriage return) | `\r` |
225
+ | % U+0022 (quotation mark) | `\"` |
226
+ | % U+005c (reverse solidus) | `` |
227
+
228
+
229
+ The escaped string representation of a character *C* is equivalent to
230
+ the escaped string representation of a string of *C*, except that:
231
+
232
+ - the result starts and ends with U+0027 (apostrophe) (`'`) instead of
233
+ U+0022 (quotation mark) (`"`), and
234
+ - if *C* is U+0027 (apostrophe), the two characters `\'` are appended to
235
+ *E*, and
236
+ - if *C* is U+0022 (quotation mark), then *C* is appended unchanged.
237
+
238
+ [*Example 1*:
239
+
240
+ ``` cpp
241
+ string s0 = format("[{}]", "h\tllo"); // s0 has value: [h\ \ \ \ llo]
242
+ string s1 = format("[{:?}]", "h\tllo"); // s1 has value: ["h\ tllo"]
243
+ string s3 = format("[{:?}, {:?}]", '\'', '"'); // s3 has value: ['\ '', '"']
244
+
245
+ // The following examples assume use of the UTF-8 encoding
246
+ string s4 = format("[{:?}]", string("\0 \n \t \x02 \x1b", 9));
247
+ // s4 has value: ["\ u{0\ \ n \ t \ u{2} \ u{1b}"]}
248
+ string s5 = format("[{:?}]", "\xc3\x28"); // invalid UTF-8, s5 has value: ["\ x{c3\("]}
249
+ string s7 = format("[{:?}]", "\u0301"); // s7 has value: ["\ u{301"]}
250
+ string s8 = format("[{:?}]", "\\\u0301"); // s8 has value: ["\ \ \ u{301"]}
251
+ ```
252
+
253
+ — *end example*]
254
+
255
  #### Class template `basic_format_parse_context` <a id="format.parse.ctx">[[format.parse.ctx]]</a>
256
 
257
  ``` cpp
258
  namespace std {
259
  template<class charT>
 
322
 
323
  ``` cpp
324
  constexpr size_t next_arg_id();
325
  ```
326
 
327
+ *Effects:* If `indexing_ != manual` is `true`, equivalent to:
328
 
329
  ``` cpp
330
  if (indexing_ == unknown)
331
  indexing_ = automatic;
332
  return next_arg_id_++;
333
  ```
334
 
335
+ *Throws:* `format_error` if `indexing_ == manual` is `true` which
336
+ indicates mixing of automatic and manual argument indexing.
337
+
338
+ *Remarks:* Let *`cur-arg-id`* be the value of `next_arg_id_` prior to
339
+ this call. Call expressions where *`cur-arg-id`*` >= num_args_` is
340
+ `true` are not core constant expressions [[expr.const]].
341
 
342
  ``` cpp
343
  constexpr void check_arg_id(size_t id);
344
  ```
345
 
346
+ *Effects:* If `indexing_ != automatic` is `true`, equivalent to:
347
 
348
  ``` cpp
349
  if (indexing_ == unknown)
350
  indexing_ = manual;
351
  ```
352
 
353
+ *Throws:* `format_error` if `indexing_ == automatic` is `true` which
354
+ indicates mixing of automatic and manual argument indexing.
355
 
356
+ *Remarks:* Call expressions where `id >= num_args_` is `true` are not
357
+ core constant expressions [[expr.const]].
358
 
359
  #### Class template `basic_format_context` <a id="format.context">[[format.context]]</a>
360
 
361
  ``` cpp
362
  namespace std {
 
368
  public:
369
  using iterator = Out;
370
  using char_type = charT;
371
  template<class T> using formatter_type = formatter<T, charT>;
372
 
373
+ basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
374
  std::locale locale();
375
 
376
  iterator out();
377
  void advance_to(iterator it);
378
  };
 
388
  `basic_format_context` with an output iterator that appends to `string`,
389
  such as `back_insert_iterator<string>`. Similarly, `wformat_context` is
390
  an alias for a specialization of `basic_format_context` with an output
391
  iterator that appends to `wstring`.
392
 
393
+ *Recommended practice:* For a given type `charT`, implementations should
394
  provide a single instantiation of `basic_format_context` for appending
395
  to `basic_string<charT>`, `vector<charT>`, or any other container with
396
  contiguous storage by wrapping those in temporary objects with a uniform
397
+ interface (such as a `span<charT>`) and polymorphic reallocation.
 
398
 
399
  ``` cpp
400
+ basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
401
  ```
402
 
403
  *Returns:* `args_.get(id)`.
404
 
405
  ``` cpp
 
411
 
412
  ``` cpp
413
  iterator out();
414
  ```
415
 
416
+ *Effects:* Equivalent to: `return std::move(out_);`
417
 
418
  ``` cpp
419
  void advance_to(iterator it);
420
  ```
421
 
422
+ *Effects:* Equivalent to: `out_ = std::move(it);`
423
 
424
  [*Example 1*:
425
 
426
  ``` cpp
427
  struct S { int value; };
 
443
  ctx.check_arg_id(width_arg_id);
444
  return ++iter;
445
  }
446
 
447
  // Formats an S with width given by the argument width_arg_id.
448
+ auto format(S s, format_context& ctx) const {
449
  int width = visit_format_arg([](auto value) -> int {
450
  if constexpr (!is_integral_v<decltype(value)>)
451
  throw format_error("width is not integral");
452
  else if (value < 0 || value > numeric_limits<int>::max())
453
  throw format_error("invalid width");