[libcxx-commits] [PATCH] D154851: [libc++][chrono] Fixes formatting duration subseconds.
Mark de Wever via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jul 10 08:10:09 PDT 2023
Mordante created this revision.
Herald added a project: All.
Mordante requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.
Fixes https://llvm.org/PR62082
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D154851
Files:
libcxx/include/__chrono/formatter.h
libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
Index: libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
===================================================================
--- libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
+++ libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
@@ -1091,12 +1091,56 @@
test_valid_fractional_values<CharT>();
}
+template <class CharT>
+static void test_pr62082() {
+ // Examples in https://llvm.org/PR62082
+ check(SV("39.223300"), SV("{:%S}"), std::chrono::duration<int, std::ratio<101, 103>>{40});
+ check(SV("01.4755859375"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 1024>>{1511});
+
+ // Test with all possible number of decimals [0, 18]. When it does not
+ // fit in 18 decimals it uses 6.
+ check(SV("05"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 1>>{10}); // 0
+
+ check(SV("05.0"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 2>>{10}); // 1
+ check(SV("05.5"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 2>>{11}); // 1
+
+ check(SV("01.00"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 4>>{4}); // 2
+ check(SV("01.50"), SV("{:%S}"), std::chrono::duration<double, std::ratio<1, 4>>{6}); // 2
+ check(SV("01.75"), SV("{:%S}"), std::chrono::duration<long double, std::ratio<1, 4>>{7}); // 2
+
+ check(SV("01.000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 8>>{8}); // 3
+ check(SV("01.0000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 16>>{16}); // 4
+ check(SV("01.00000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 32>>{32}); // 5
+ check(SV("01.000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 64>>{64}); // 6
+ check(SV("01.0000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 128>>{128}); // 7
+ check(SV("01.00000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 256>>{256}); // 8
+ check(SV("01.000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 512>>{512}); // 9
+ check(SV("01.0000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 1024>>{1024}); // 10
+ check(SV("01.00000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 2048>>{2048}); // 11
+ check(SV("01.000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 4096>>{4096}); // 12
+ check(SV("01.0000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 8192>>{8192}); // 13
+ check(SV("01.00000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 16384>>{16384}); // 14
+ check(SV("01.000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 32768>>{32768}); // 15
+ check(SV("01.0000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 65536>>{65536}); // 16
+ check(SV("01.00000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 131072>>{131072}); // 17
+ check(SV("01.000000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 262144>>{262144}); // 18
+ check(SV("01.000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 524288>>{524288}); // 19 -> 6
+
+ // Infinite number of decimals will use 6 decimals.
+ check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 9>>{1});
+ check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 9>>{1});
+ check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<double, std::ratio<1, 9>>{1});
+ check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<long double, std::ratio<1, 9>>{1});
+}
+
template <class CharT>
static void test() {
using namespace std::literals::chrono_literals;
test_no_chrono_specs<CharT>();
test_valid_values<CharT>();
+ test_pr62082<CharT>();
+
check_invalid_types<CharT>(
{SV("H"), SV("I"), SV("j"), SV("M"), SV("n"), SV("O"), SV("p"), SV("q"), SV("Q"), SV("r"),
SV("R"), SV("S"), SV("t"), SV("T"), SV("X"), SV("EX"), SV("OH"), SV("OI"), SV("OM"), SV("OS")},
Index: libcxx/include/__chrono/formatter.h
===================================================================
--- libcxx/include/__chrono/formatter.h
+++ libcxx/include/__chrono/formatter.h
@@ -100,12 +100,12 @@
// https://godbolt.org/z/6dsbnW8ba
std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
_LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"),
- __fraction.count(),
+ chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(),
chrono::hh_mm_ss<__duration>::fractional_width);
else
std::format_to(std::ostreambuf_iterator<_CharT>{__sstr},
_LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"),
- __fraction.count(),
+ chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(),
chrono::hh_mm_ss<__duration>::fractional_width);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154851.538654.patch
Type: text/x-patch
Size: 5116 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20230710/9c54f607/attachment.bin>
More information about the libcxx-commits
mailing list