This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

3317. Incorrect operator<< for floating-point durations

Section: 30.5.11 [time.duration.io] Status: C++20 Submitter: United States Opened: 2019-11-05 Last modified: 2021-02-25

Priority: 0

View all other issues in [time.duration.io].

View all issues with C++20 status.

Discussion:

Addresses US 334

operator<< for floating-point durations always produces output with six digits after the decimal point, and doesn't use the stream's locale either.

Proposed change:

Rewrite the specification to not rely on to_string() for floating-point formatting.

[2019-11 Status to Ready during Wednesday morning issue processing in Belfast.]

Proposed resolution:

This wording is relative to N4835.

  1. Modify 30.5.11 [time.duration.io] as indicated:

    template<class charT, class traits, class Rep, class Period>
      basic_ostream<charT, traits>&
        operator<<(basic_ostream<charT, traits>& os, const duration<Rep, Period>& d);
    

    -1- Requires: Rep is an integral type whose integer conversion rank (6.8.6 [conv.rank]) is greater than or equal to that of short, or a floating-point type. charT is char or wchar_t.

    -2- Effects: Forms a basic_string<charT, traits> from d.count() using to_string if charT is char, or to_wstring if charT is wchar_t. Appends the units suffix described below to the basic_string. Inserts the resulting basic_string into os. [Note: This specification ensures that the result of this streaming operation will obey the width and alignment properties of the stream. — end note]Inserts the duration d onto the stream os as if it were implemented as follows:

    basic_ostringstream<charT, traits> s;
    s.flags(os.flags());
    s.imbue(os.getloc());
    s.precision(os.precision());
    s << d.count() << units_suffix;
    return os << s.str();
    

    -3- The units suffixunits_suffix depends on the type Period::type as follows:

    1. (3.1) — If Period::type is atto, the suffixunits_suffix is "as".

    2. (3.2) — Otherwise, if Period::type is femto, the suffixunits_suffix is "fs".

    3. (3.3) — Otherwise, if Period::type is pico, the suffixunits_suffix is "ps".

    4. (3.4) — Otherwise, if Period::type is nano, the suffixunits_suffix is "ns".

    5. (3.5) — Otherwise, if Period::type is micro, the suffixunits_suffix is "µs" ("\u00b5\u0073").

    6. (3.6) — Otherwise, if Period::type is milli, the suffixunits_suffix is "ms".

    7. (3.7) — Otherwise, if Period::type is centi, the suffixunits_suffix is "cs".

    8. (3.8) — Otherwise, if Period::type is deci, the suffixunits_suffix is "ds".

    9. (3.9) — Otherwise, if Period::type is ratio<1>, the suffixunits_suffix is "s".

    10. (3.10) — Otherwise, if Period::type is deca, the suffixunits_suffix is "das".

    11. (3.11) — Otherwise, if Period::type is hecto, the suffixunits_suffix is "hs".

    12. (3.12) — Otherwise, if Period::type is kilo, the suffixunits_suffix is "ks".

    13. (3.13) — Otherwise, if Period::type is mega, the suffixunits_suffix is "Ms".

    14. (3.14) — Otherwise, if Period::type is giga, the suffixunits_suffix is "Gs".

    15. (3.15) — Otherwise, if Period::type is tera, the suffixunits_suffix is "Ts".

    16. (3.16) — Otherwise, if Period::type is peta, the suffixunits_suffix is "Ps".

    17. (3.17) — Otherwise, if Period::type is exa, the suffixunits_suffix is "Es".

    18. (3.18) — Otherwise, if Period::type is ratio<60>, the suffixunits_suffix is "min".

    19. (3.19) — Otherwise, if Period::type is ratio<3600>, the suffixunits_suffix is "h".

    20. (3.20) — Otherwise, if Period::type is ratio<86400>, the suffixunits_suffix is "d".

    21. (3.21) — Otherwise, if Period::type::den == 1, the suffixunits_suffix is "[num]s".

    22. (3.22) — Otherwise, the suffixunits_suffix is "[num/den]s".

    In the list above the use of num and den refer to the static data members of Period::type, which are converted to arrays of charT using a decimal conversion with no leading zeroes.

    -4- If Period::type is micro, but the character U+00B5 cannot be represented in the encoding used for charT, the unit suffixunits_suffix "us" is used instead of "µs".

    -5- Returns: os.