[libcxx-commits] [libcxx] 2858475 - [libc++][chrono] Fixes formatting duration subseconds.
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 11 11:40:03 PDT 2023
Author: Mark de Wever
Date: 2023-07-11T20:39:56+02:00
New Revision: 28584755e424b69c27247f895f917b7d59060bc6
URL: https://github.com/llvm/llvm-project/commit/28584755e424b69c27247f895f917b7d59060bc6
DIFF: https://github.com/llvm/llvm-project/commit/28584755e424b69c27247f895f917b7d59060bc6.diff
LOG: [libc++][chrono] Fixes formatting duration subseconds.
Fixes https://llvm.org/PR62082
Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D154851
Added:
Modified:
libcxx/include/__chrono/formatter.h
libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h
index 2de6e1420d1272..3793b53a80be81 100644
--- a/libcxx/include/__chrono/formatter.h
+++ b/libcxx/include/__chrono/formatter.h
@@ -100,12 +100,12 @@ __format_sub_seconds(const chrono::duration<_Rep, _Period>& __value, basic_strin
// 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);
}
diff --git a/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp b/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
index 88c3f62c8f269b..c3fd0f2315a453 100644
--- a/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
+++ b/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp
@@ -1091,12 +1091,56 @@ static void test_valid_values() {
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>>{5}); // 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")},
More information about the libcxx-commits
mailing list