duration
formatters format custom rep
types?Section: 30.12 [time.format] Status: New Submitter: Jonathan Wakely Opened: 2024-07-08 Last modified: 2024-07-31
Priority: 3
View other active issues in [time.format].
View all other issues in [time.format].
View all issues with New status.
Discussion:
The formatter<chrono::duration<Rep, Period>, charT>
partial specialization needs to be able to format the Rep
type, because
the %Q
conversion specifier says to format the value returned by .count()
which is of type Rep
. This implies that the Rep
type must be formattable,
although the precise method of formatting it is not specified. Presumably
either format("{}", d.count())
or
ostrm << d.count()
needs to work.
28.5.6.4 [format.formatter.spec] p2 (2.3) says:
For eachHowever, nothing prevents the excluded types being used as thecharT
, for each cv-unqualified arithmetic typeArithmeticT
other thanchar
,wchar_t
,char8_t
,char16_t
, orchar32_t
, a specialization:template<> struct formatter<ArithmeticT, charT>;
rep
for a
chrono::duration
.
This means you can use chrono::duration<wchar_t>
and
chrono::duration<char8_t>
as durations,
but you can't format them to char
strings.
I think only the %Q
conversion specifier formats the rep
type directly
(without converting durations to formattable types like hours
or seconds
),
and so I don't think this problem exists for other chrono formatter
specializations, because %Q
can only be used for durations
(that's not entirely clear, since %q
and %Q
are specified to format
"the duration's unit suffix" and "the duration's numeric value",
but presumably that means they can only be used for duration
types).
Should the specialization of formatter
for chrono::duration
be constrained
to require that the rep
type can be formatted?
Or should the %Q
conversion specifier say that the numeric value is
formatted by inserting into an ostream
(which would treat wchar_t
and
char8_t
rep types as characters, not integers)?
Or should %Q
say that the numeric value is converted to an integral type,
which we know how to format?
This is somewhat related to issue 953, since it's unclear which operations "a class emulating an arithmetic type" needs to support.
[2024-07-31; Reflector poll]
Set priority to 3 after reflector poll.
"Don't convert to an integer type, that would be wrong for
duration<long double>
and could overflow for
duration<BigInt>
."
"%Q
could format using +d.count()
"
Some requests to disallow using code unit types as duration reps,
e.g. duration<char>
. Alternatively it just shouldn't
be formattable. Alternatively, don't bother preventing dumb things.
There's a similar issue in operator<<
for
duration
, which writes d.count()
to the stream. For a custom rep type
that might be ill-formed. For character types it might print as a character
not an integer.
Proposed resolution:
This wording is relative to N4986.
Modify 30.2 [time.syn] as indicated:
namespace std { template<class Rep, class Period, class charT> requires formattable<Rep, charT> struct formatter<chrono::duration<Rep, Period>, charT>; template<class Duration, class charT> struct formatter<chrono::sys_time<Duration>, charT>;