|
| 1 | +<?xml version='1.0' encoding='utf-8' standalone='no'?> |
| 2 | +<!DOCTYPE issue SYSTEM "lwg-issue.dtd"> |
| 3 | + |
| 4 | +<issue num="4118" status="New"> |
| 5 | +<title>How should `duration` formatters format custom `rep` types?</title> |
| 6 | +<section><sref ref="[time.format]"/></section> |
| 7 | +<submitter>Jonathan Wakely</submitter> |
| 8 | +<date>08 Jul 2024</date> |
| 9 | +<priority>99</priority> |
| 10 | + |
| 11 | +<discussion> |
| 12 | +<p> |
| 13 | +The <code>formatter<chrono::duration<Rep, Period>, charT></code> |
| 14 | +partial specialization needs to be able to format the `Rep` type, because |
| 15 | +the `%Q` conversion specifier says to format the value returned by `.count()` |
| 16 | +which is of type `Rep`. This implies that the `Rep` type must be formattable, |
| 17 | +although the precise method of formatting it is not specified. Presumably |
| 18 | +either <code>format("{}", d.count())</code> or |
| 19 | +<code>ostrm << d.count()</code> needs to work. |
| 20 | +</p> |
| 21 | + |
| 22 | +<p> |
| 23 | +<sref ref="[format.formatter.spec]"/> p2 (2.3) says: |
| 24 | +<blockquote> |
| 25 | +For each `charT`, for each cv-unqualified arithmetic type `ArithmeticT` |
| 26 | +other than `char`, `wchar_t`, `char8_t`, `char16_t`, or `char32_t`, |
| 27 | +a specialization: |
| 28 | +<code>template<> struct formatter<ArithmeticT, charT>;</code> |
| 29 | +</blockquote> |
| 30 | +However, nothing prevents the excluded types being used as the `rep` for a |
| 31 | +`chrono::duration`. |
| 32 | +This means you can use <code>chrono::duration<wchar_t></code> and |
| 33 | +<code>chrono::duration<char8_t></code> as durations, |
| 34 | +but you can't format them to `char` strings. |
| 35 | +</p> |
| 36 | + |
| 37 | +<p> |
| 38 | +I think only the `%Q` conversion specifier formats the `rep` type directly |
| 39 | +(without converting durations to formattable types like `hours` or `seconds`), |
| 40 | +and so I don't think this problem exists for other chrono `formatter` |
| 41 | +specializations, because `%Q` can only be used for durations |
| 42 | +(that's not <i>entirely</i> clear, since `%q` and `%Q` are specified to format |
| 43 | +"the duration's unit suffix" and "the duration's numeric value", |
| 44 | +but presumably that means they can only be used for `duration` types). |
| 45 | +</p> |
| 46 | + |
| 47 | +<p> |
| 48 | +Should the specialization of `formatter` for `chrono::duration` be constrained |
| 49 | +to require that the `rep` type can be formatted? |
| 50 | +Or should the `%Q` conversion specifier say that the numeric value is |
| 51 | +formatted by inserting into an `ostream` (which would treat `wchar_t` and |
| 52 | +`char8_t` rep types as characters, not integers)? |
| 53 | +Or should `%Q` say that the numeric value is converted to an integral type, |
| 54 | +which we know how to format? |
| 55 | +</p> |
| 56 | + |
| 57 | +<p> |
| 58 | +This is somewhat related to issue <iref num="953"/>, since it's unclear |
| 59 | +which operations "a class emulating an arithmetic type" needs to support. |
| 60 | +</p> |
| 61 | +</discussion> |
| 62 | + |
| 63 | +<resolution> |
| 64 | +<p> |
| 65 | +This wording is relative to <paper num="N4981"/>. |
| 66 | +</p> |
| 67 | +<ol> |
| 68 | +<li><p>Modify <sref ref="[meta.unary.prop]"/> as indicated:</p> |
| 69 | + |
| 70 | +<blockquote> |
| 71 | +<table style="border: 1px solid; border-spacing: 1.5em"> |
| 72 | +<thead style="text-align: center"> |
| 73 | +<tr><th>Specifier</th><th>Replacement</th></tr> |
| 74 | +</thead> |
| 75 | +<tbody style="vertical-align: top"> |
| 76 | +<tr><td>…</td><td>…</td><td>…</td></tr> |
| 77 | +<tr> |
| 78 | +<td> `%Q` </td> |
| 79 | +<td> |
| 80 | +The duration’s numeric value (as if extracted via `.count()` |
| 81 | +<ins>and converted to `intmax_t`</ins> |
| 82 | +). |
| 83 | +</td> |
| 84 | +</tr> |
| 85 | +</tbody> |
| 86 | +</table> |
| 87 | +</blockquote> |
| 88 | +</li> |
| 89 | +</ol> |
| 90 | +</resolution> |
| 91 | + |
| 92 | +</issue> |
0 commit comments