-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
When #1341 implemented operator<<(basic_ostream&, const duration&), its unit suffix logic handled only char and wchar_t:
Lines 625 to 662 in 6458199
| #define _IF_PERIOD_RETURN_SUFFIX_ELSE(_TYPE, _SUFFIX) \ | |
| if constexpr (is_same_v<_Period, _TYPE>) { \ | |
| if constexpr (is_same_v<_CharT, char>) { \ | |
| return _SUFFIX; \ | |
| } else { \ | |
| return L##_SUFFIX; \ | |
| } \ | |
| } else | |
| template <class _CharT, class _Period> | |
| _NODISCARD constexpr const _CharT* _Get_literal_unit_suffix() { | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(atto, "as") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(femto, "fs") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(pico, "ps") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(nano, "ns") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(micro, "us") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(milli, "ms") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(centi, "cs") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(deci, "ds") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(seconds::period, "s") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(deca, "das") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(hecto, "hs") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(kilo, "ks") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(mega, "Ms") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(giga, "Gs") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(tera, "Ts") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(peta, "Ps") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(exa, "Es") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(minutes::period, "min") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(hours::period, "h") | |
| _IF_PERIOD_RETURN_SUFFIX_ELSE(ratio<86400>, "d") | |
| { | |
| return nullptr; | |
| } | |
| } | |
| #undef _IF_PERIOD_RETURN_SUFFIX_ELSE |
However, WG21-N4868 27.5.11 [time.duration.io]/1 doesn't limit charT to being only char and wchar_t. Instead, it depicts narrow string literals being directly streamed into the basic_ostream regardless of its charT (which works because const char * is always streamable, albeit with reduced performance if the types differ).
Retaining the wchar_t logic is permitted and improves performance, so we just need to fix this for other character types (like char8_t, char16_t, and char32_t).
@MattStephanson's first suggested strategy in #1341 (comment) sounds good:
I think I can just switch the order of the
if/elseto makecharthe fallback, then use aconditionalto get the correct return type.
We should also add test coverage for this - it doesn't have to be exhaustive, just testing a literal and a general suffix for another character type would be sufficient.