diff options
-rw-r--r-- | libstdc++-v3/include/std/chrono | 99 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/duration/io.cc | 54 |
2 files changed, 153 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index c8060d7..0662e26 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -37,6 +37,10 @@ #else #include <bits/chrono.h> +#if __cplusplus > 201703L +# include <sstream> // ostringstream +# include <bits/charconv.h> +#endif namespace std _GLIBCXX_VISIBILITY(default) { @@ -2077,6 +2081,101 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @} } // inline namespace chrono_literals } // inline namespace literals + + namespace chrono + { + /// @addtogroup chrono + /// @{ + + /// @cond undocumented + namespace __detail + { + template<typename _Period> + const char* + __units_suffix_misc(char* __buf, size_t __n) noexcept + { + namespace __tc = std::__detail; + char* __p = __buf; + __p[0] = '['; + unsigned __nlen = __tc::__to_chars_len((uintmax_t)_Period::num); + __tc::__to_chars_10_impl(__p + 1, __nlen, (uintmax_t)_Period::num); + __p += 1 + __nlen; + if constexpr (_Period::den != 1) + { + __p[0] = '/'; + unsigned __dlen = __tc::__to_chars_len((uintmax_t)_Period::den); + __tc::__to_chars_10_impl(__p + 1, __dlen, (uintmax_t)_Period::den); + __p += 1 + __dlen; + } + __p[0] = ']'; + __p[1] = 's'; + __p[2] = '\0'; + return __buf; + } + + template<typename _Period, typename _CharT> + auto + __units_suffix(char* __buf, size_t __n) noexcept + { +#define _GLIBCXX_UNITS_SUFFIX(period, suffix) \ + if constexpr (is_same_v<_Period, period>) \ + { \ + if constexpr (is_same_v<_CharT, wchar_t>) \ + return L##suffix; \ + else \ + return suffix; \ + } \ + else + + _GLIBCXX_UNITS_SUFFIX(atto, "as") + _GLIBCXX_UNITS_SUFFIX(femto, "fs") + _GLIBCXX_UNITS_SUFFIX(pico, "ps") + _GLIBCXX_UNITS_SUFFIX(nano, "ns") + _GLIBCXX_UNITS_SUFFIX(micro, "\u00b5s") + _GLIBCXX_UNITS_SUFFIX(milli, "ms") + _GLIBCXX_UNITS_SUFFIX(centi, "cs") + _GLIBCXX_UNITS_SUFFIX(deci, "ds") + _GLIBCXX_UNITS_SUFFIX(ratio<1>, "s") + _GLIBCXX_UNITS_SUFFIX(deca, "das") + _GLIBCXX_UNITS_SUFFIX(hecto, "hs") + _GLIBCXX_UNITS_SUFFIX(kilo, "ks") + _GLIBCXX_UNITS_SUFFIX(mega, "Ms") + _GLIBCXX_UNITS_SUFFIX(giga, "Gs") + _GLIBCXX_UNITS_SUFFIX(tera, "Ts") + _GLIBCXX_UNITS_SUFFIX(tera, "Ts") + _GLIBCXX_UNITS_SUFFIX(peta, "Ps") + _GLIBCXX_UNITS_SUFFIX(exa, "Es") + _GLIBCXX_UNITS_SUFFIX(ratio<60>, "min") + _GLIBCXX_UNITS_SUFFIX(ratio<3600>, "h") + _GLIBCXX_UNITS_SUFFIX(ratio<86400>, "d") +#undef _GLIBCXX_UNITS_SUFFIX + return __detail::__units_suffix_misc<_Period>(__buf, __n); + } + } // namespace __detail + /// @endcond + + template<typename _CharT, typename _Traits, + typename _Rep, typename _Period> + inline basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const duration<_Rep, _Period>& __d) + { + using period = typename _Period::type; + char __buf[sizeof("[/]s") + 2 * numeric_limits<intmax_t>::digits10]; + std::basic_ostringstream<_CharT, _Traits> __s; + __s.flags(__os.flags()); + __s.imbue(__os.getloc()); + __s.precision(__os.precision()); + __s << __d.count(); + __s << __detail::__units_suffix<period, _CharT>(__buf, sizeof(__buf)); + __os << std::move(__s).str(); + return __os; + } + + // TODO: from_stream for duration + + /// @} group chrono + } // namespace chrono #endif // C++20 _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/20_util/duration/io.cc b/libstdc++-v3/testsuite/20_util/duration/io.cc new file mode 100644 index 0000000..405e1af --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/duration/io.cc @@ -0,0 +1,54 @@ +// { dg-options "-std=gnu++20" } +// { dg-do run { target c++20 } } + +#include <chrono> +#include <sstream> +#include <testsuite_hooks.h> + +void +test01() +{ + using namespace std::chrono; + std::stringstream ss; + ss << 0s << '\n'; + ss << 3h + 5min << '\n'; + ss << duration<long, std::ratio<2>>(3) << '\n'; + ss << duration<long, std::ratio<2, 3>>(9) << '\n'; + std::string s; + std::getline(ss, s); + VERIFY( s == "0s" ); + std::getline(ss, s); + VERIFY( s == "185min" ); + std::getline(ss, s); + VERIFY( s == "3[2]s" ); + std::getline(ss, s); + VERIFY( s == "9[2/3]s" ); +} + +void +test02() +{ +#ifdef _GLIBCXX_USE_WCHAR_T + using namespace std::chrono; + std::wstringstream ss; + ss << 0s << L'\n'; + ss << 3h + 5min << L'\n'; + ss << duration<long, std::ratio<2>>(3) << L'\n'; + ss << duration<long, std::ratio<2, 3>>(9) << L'\n'; + std::wstring s; + std::getline(ss, s); + VERIFY( s == L"0s" ); + std::getline(ss, s); + VERIFY( s == L"185min" ); + std::getline(ss, s); + VERIFY( s == L"3[2]s" ); + std::getline(ss, s); + VERIFY( s == L"9[2/3]s" ); +#endif +} + +int main() +{ + test01(); + test02(); +} |