From 38a810023a87daede7e4caf2f7057832a1232558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Fri, 21 Nov 2025 08:08:04 +0100 Subject: [PATCH 01/13] Add tests --- .../test.cpp | 317 ++++++++++++++---- 1 file changed, 252 insertions(+), 65 deletions(-) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index 09cb4b1f4b2..2849b219271 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -15,86 +15,278 @@ #include #include +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__); + using namespace std; using namespace std::chrono; -struct not_a_clock { - bool rep(); - static char period; - int duration(); - static float time_point; - using is_steady = long; - static int now; +struct real_fake_clock { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); }; -struct real_fake_clock { - using rep = bool; - using period = char; - using duration = float; - using time_point = int; - static long is_steady; - static short now(); +struct rep_missing { + + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); +}; + +struct rep_not_type { + char rep; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); +}; + +struct rep_wrong_type { + using rep = real_fake_clock; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); +}; + +struct period_missing { + using rep = long long; + + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); }; -struct no_rep { - using period = char; - using duration = float; - using time_point = int; - static long is_steady; - static short now(); +struct period_not_type { + using rep = long long; + char period; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); }; -struct no_period { - using rep = bool; - using duration = float; - using time_point = int; - static long is_steady; - static short now(); +struct period_wrong_type { + using rep = long long; + using period = char; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); }; -struct no_duration { - using rep = bool; - using period = char; - using time_point = int; - static long is_steady; - static short now(); +struct duration_missing { + using rep = long long; + using period = micro; + + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); +}; + +struct duration_not_type { + using rep = long long; + using period = micro; + char duration; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); }; -struct no_time_point { - using rep = bool; - using period = char; - using duration = float; - static long is_steady; - static short now(); +struct duration_wrong_type { + using rep = long long; + using period = micro; + using duration = int; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); }; -struct no_steady { - using rep = bool; - using period = char; - using duration = float; - using time_point = int; - static short now(); +struct duration_slightly_wrong_type { + using rep = long long; + using period = micro; + using duration = milliseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); }; -struct no_now { - using rep = bool; - using period = char; - using duration = float; - using time_point = int; - static long is_steady; +struct duration_slightly_wrong_type2 { + using rep = long long; + using period = micro; + using duration = duration; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); }; -static_assert(is_clock::value, "steady_clock is not a clock"); -static_assert(is_clock_v, "steady_clock is not a clock"); -static_assert(is_clock_v, "real_fake_clock is not a clock"); -static_assert(!is_clock_v, "not_a_clock is a clock"); +struct time_point_missing { + using rep = long long; + using period = micro; + using duration = microseconds; + + constexpr static bool is_steady = false; + static time_point now(); +}; + +struct time_point_not_type { + using rep = long long; + using period = micro; + using duration = microseconds; + char time_point; + constexpr static bool is_steady = false; + static chrono::time_point now(); +}; + +struct time_point_wrong_type { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = int; + constexpr static bool is_steady = false; + static time_point now(); +}; + +struct time_point_wrong_type2 { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); +}; + +struct time_point_different_clock_ok { + using rep = long long; + using period = milli; + using duration = milliseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now(); +}; + +struct is_steady_missing { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + + static time_point now(); +}; + +struct is_steady_type { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + using is_steady = bool; + static time_point now(); +}; + +struct is_steady_member { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + bool is_steady; + static time_point now(); +}; + +struct now_missing { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; +}; + +struct now_type { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + using now = time_point; +}; + +struct now_not_fun { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static time_point now; +}; + +struct now_not_static { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + time_point now(); +}; + +struct now_wrong_type { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + constexpr static bool is_steady = false; + static duration now(); +}; + +// Check standard clocks +STATIC_ASSERT(is_clock::value); +STATIC_ASSERT(is_clock_v); +STATIC_ASSERT(is_clock_v); +STATIC_ASSERT(is_clock_v); +STATIC_ASSERT(is_clock_v); +STATIC_ASSERT(is_clock_v); +STATIC_ASSERT(is_clock_v); +STATIC_ASSERT(is_clock_v); + +// Check custom clocks +STATIC_ASSERT(is_clock_v); + +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); + +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); + +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); + +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(is_clock_v); + +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); + +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); +STATIC_ASSERT(!is_clock_v); -static_assert(!is_clock_v, "no_rep is a clock"); -static_assert(!is_clock_v, "no_period is a clock"); -static_assert(!is_clock_v, "no_duration is a clock"); -static_assert(!is_clock_v, "no_time_point is a clock"); -static_assert(!is_clock_v, "no_steady is a clock"); -static_assert(!is_clock_v, "no_now is a clock"); void test_is_leap_second(const year_month_day& ymd) { const sys_days ls{ymd}; @@ -376,11 +568,6 @@ void test_clock_cast() { assert(clock_cast(sys_seconds{sys_days{2000y / January / 1}}).time_since_epoch() == 946'684'822s); } -static_assert(is_clock_v); -static_assert(is_clock_v); -static_assert(is_clock_v); -static_assert(is_clock_v); - tzdb copy_tzdb() { const auto& my_tzdb = get_tzdb_list().front(); vector zones; From 68b732cec4f5be2372b9263c2a5f53536cf590c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Fri, 21 Nov 2025 08:09:22 +0100 Subject: [PATCH 02/13] Perform additional (stricter) checks in std::chrono::is_clock_v --- stl/inc/__msvc_chrono.hpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/stl/inc/__msvc_chrono.hpp b/stl/inc/__msvc_chrono.hpp index 094f700699d..540f2d109ed 100644 --- a/stl/inc/__msvc_chrono.hpp +++ b/stl/inc/__msvc_chrono.hpp @@ -58,15 +58,32 @@ namespace chrono { } }; + _EXPORT_STD template > + class duration; + + _EXPORT_STD template + class time_point; + #if _HAS_CXX20 _EXPORT_STD template _NO_SPECIALIZATIONS_OF_VARIABLE_TEMPLATES constexpr bool is_clock_v = requires { + // Basic checks from https://eel.is/c++draft/time.traits.is.clock#1 typename _Clock::rep; typename _Clock::period; typename _Clock::duration; typename _Clock::time_point; _Clock::is_steady; _Clock::now(); + + // Complete checks from https://eel.is/c++draft/tab:time.clock + // "An arithmetic type or a class emulating an arithmetic type" is not checked + requires _Is_ratio_v; + requires same_as>; + requires same_as> + || same_as>; + { _Clock::is_steady } -> std::same_as; + { _Clock::now() } -> std::same_as; }; _EXPORT_STD template struct _NO_SPECIALIZATIONS_CITING("N5014 [time.traits.is.clock]/2") is_clock : bool_constant> {}; @@ -84,9 +101,6 @@ namespace chrono { true; #endif // ^^^ !_HAS_CXX20 ^^^ - _EXPORT_STD template > - class duration; - template constexpr bool _Is_duration_v = _Is_specialization_v<_Ty, duration>; @@ -203,7 +217,7 @@ namespace chrono { _Rep _MyRep; // the stored rep }; - _EXPORT_STD template + _EXPORT_STD template class time_point { // represents a point in time public: using clock = _Clock; From 8417029f1e078196fafc90cf93a59a022d27e811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Fri, 21 Nov 2025 08:16:33 +0100 Subject: [PATCH 03/13] Replace _Clock::now() with _Clock::now to reject typedefs --- stl/inc/__msvc_chrono.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/__msvc_chrono.hpp b/stl/inc/__msvc_chrono.hpp index 540f2d109ed..9dfffb642f1 100644 --- a/stl/inc/__msvc_chrono.hpp +++ b/stl/inc/__msvc_chrono.hpp @@ -73,7 +73,7 @@ namespace chrono { typename _Clock::duration; typename _Clock::time_point; _Clock::is_steady; - _Clock::now(); + _Clock::now; // Complete checks from https://eel.is/c++draft/tab:time.clock // "An arithmetic type or a class emulating an arithmetic type" is not checked From aeeea02e4ca1132ecc0ad6a55ad46496c62b97e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Fri, 21 Nov 2025 08:52:44 +0100 Subject: [PATCH 04/13] Replace links in comments with proper reference to the standard --- stl/inc/__msvc_chrono.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/__msvc_chrono.hpp b/stl/inc/__msvc_chrono.hpp index 9dfffb642f1..105766a52f0 100644 --- a/stl/inc/__msvc_chrono.hpp +++ b/stl/inc/__msvc_chrono.hpp @@ -67,7 +67,7 @@ namespace chrono { #if _HAS_CXX20 _EXPORT_STD template _NO_SPECIALIZATIONS_OF_VARIABLE_TEMPLATES constexpr bool is_clock_v = requires { - // Basic checks from https://eel.is/c++draft/time.traits.is.clock#1 + // Basic checks from N5014 [time.traits.is.clock] / 1 typename _Clock::rep; typename _Clock::period; typename _Clock::duration; @@ -75,7 +75,7 @@ namespace chrono { _Clock::is_steady; _Clock::now; - // Complete checks from https://eel.is/c++draft/tab:time.clock + // Additional stricter checks from N5014 [time.clock.req] / 2 // "An arithmetic type or a class emulating an arithmetic type" is not checked requires _Is_ratio_v; requires same_as>; From 290c5eba1f15a1251e4cbe8916ffdc218dcccb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Fri, 21 Nov 2025 10:09:43 +0100 Subject: [PATCH 05/13] Correct endline character --- stl/inc/__msvc_chrono.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/__msvc_chrono.hpp b/stl/inc/__msvc_chrono.hpp index 105766a52f0..55caba6382c 100644 --- a/stl/inc/__msvc_chrono.hpp +++ b/stl/inc/__msvc_chrono.hpp @@ -67,7 +67,7 @@ namespace chrono { #if _HAS_CXX20 _EXPORT_STD template _NO_SPECIALIZATIONS_OF_VARIABLE_TEMPLATES constexpr bool is_clock_v = requires { - // Basic checks from N5014 [time.traits.is.clock] / 1 + // Basic checks from N5014 [time.traits.is.clock]/1 typename _Clock::rep; typename _Clock::period; typename _Clock::duration; @@ -75,7 +75,7 @@ namespace chrono { _Clock::is_steady; _Clock::now; - // Additional stricter checks from N5014 [time.clock.req] / 2 + // Additional stricter checks from N5014 [time.clock.req]/2 // "An arithmetic type or a class emulating an arithmetic type" is not checked requires _Is_ratio_v; requires same_as>; From a14115e386d4c177e83fc0794ecd6176f31f690c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 25 Nov 2025 08:57:48 -0800 Subject: [PATCH 06/13] `T::now()` is part of the basic checks. --- stl/inc/__msvc_chrono.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/__msvc_chrono.hpp b/stl/inc/__msvc_chrono.hpp index 55caba6382c..cdf2030242a 100644 --- a/stl/inc/__msvc_chrono.hpp +++ b/stl/inc/__msvc_chrono.hpp @@ -73,7 +73,7 @@ namespace chrono { typename _Clock::duration; typename _Clock::time_point; _Clock::is_steady; - _Clock::now; + _Clock::now(); // Additional stricter checks from N5014 [time.clock.req]/2 // "An arithmetic type or a class emulating an arithmetic type" is not checked From f4de01a8bb74c8d2d63619e2ce6c7fb31e90b056 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 25 Nov 2025 09:08:26 -0800 Subject: [PATCH 07/13] Remove unnecessary newlines. --- .../test.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index 2849b219271..a5c7619f68f 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -30,7 +30,6 @@ struct real_fake_clock { }; struct rep_missing { - using period = micro; using duration = microseconds; using time_point = time_point; @@ -57,8 +56,7 @@ struct rep_wrong_type { }; struct period_missing { - using rep = long long; - + using rep = long long; using duration = microseconds; using time_point = time_point; constexpr static bool is_steady = false; @@ -84,9 +82,8 @@ struct period_wrong_type { }; struct duration_missing { - using rep = long long; - using period = micro; - + using rep = long long; + using period = micro; using time_point = time_point; constexpr static bool is_steady = false; static time_point now(); @@ -129,10 +126,9 @@ struct duration_slightly_wrong_type2 { }; struct time_point_missing { - using rep = long long; - using period = micro; - using duration = microseconds; - + using rep = long long; + using period = micro; + using duration = microseconds; constexpr static bool is_steady = false; static time_point now(); }; @@ -178,7 +174,6 @@ struct is_steady_missing { using period = micro; using duration = microseconds; using time_point = time_point; - static time_point now(); }; @@ -287,7 +282,6 @@ STATIC_ASSERT(!is_clock_v); STATIC_ASSERT(!is_clock_v); STATIC_ASSERT(!is_clock_v); - void test_is_leap_second(const year_month_day& ymd) { const sys_days ls{ymd}; const auto& leap_seconds = get_tzdb().leap_seconds; From 62663570e49d73787f0606b81bc409809261c895 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 25 Nov 2025 09:15:02 -0800 Subject: [PATCH 08/13] Use terse `static_assert` in C++20. --- .../test.cpp | 80 +++++++++---------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index a5c7619f68f..dbb9367fa1c 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -15,8 +15,6 @@ #include #include -#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__); - using namespace std; using namespace std::chrono; @@ -240,47 +238,47 @@ struct now_wrong_type { }; // Check standard clocks -STATIC_ASSERT(is_clock::value); -STATIC_ASSERT(is_clock_v); -STATIC_ASSERT(is_clock_v); -STATIC_ASSERT(is_clock_v); -STATIC_ASSERT(is_clock_v); -STATIC_ASSERT(is_clock_v); -STATIC_ASSERT(is_clock_v); -STATIC_ASSERT(is_clock_v); +static_assert(is_clock::value); +static_assert(is_clock_v); +static_assert(is_clock_v); +static_assert(is_clock_v); +static_assert(is_clock_v); +static_assert(is_clock_v); +static_assert(is_clock_v); +static_assert(is_clock_v); // Check custom clocks -STATIC_ASSERT(is_clock_v); - -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); - -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); - -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); - -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(is_clock_v); - -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); - -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); -STATIC_ASSERT(!is_clock_v); +static_assert(is_clock_v); + +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); + +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); + +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); + +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(is_clock_v); + +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); + +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); +static_assert(!is_clock_v); void test_is_leap_second(const year_month_day& ymd) { const sys_days ls{ymd}; From e9b070dbf92b26f3c247c3d96367b1b8736afe5d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 25 Nov 2025 09:22:08 -0800 Subject: [PATCH 09/13] Include ``. --- tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index dbb9367fa1c..bb816ffa1a0 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include From dce37e0fcc07c1cbcac821b2e1bed11d4d540609 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 25 Nov 2025 09:24:19 -0800 Subject: [PATCH 10/13] `constexpr static` => `static constexpr` --- .../test.cpp | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index bb816ffa1a0..c1a44bd84f4 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -24,7 +24,7 @@ struct real_fake_clock { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -32,7 +32,7 @@ struct rep_missing { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -41,7 +41,7 @@ struct rep_not_type { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -50,7 +50,7 @@ struct rep_wrong_type { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -58,7 +58,7 @@ struct period_missing { using rep = long long; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -67,7 +67,7 @@ struct period_not_type { char period; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -76,7 +76,7 @@ struct period_wrong_type { using period = char; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -84,7 +84,7 @@ struct duration_missing { using rep = long long; using period = micro; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -93,7 +93,7 @@ struct duration_not_type { using period = micro; char duration; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -102,7 +102,7 @@ struct duration_wrong_type { using period = micro; using duration = int; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -111,7 +111,7 @@ struct duration_slightly_wrong_type { using period = micro; using duration = milliseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -120,7 +120,7 @@ struct duration_slightly_wrong_type2 { using period = micro; using duration = duration; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -128,7 +128,7 @@ struct time_point_missing { using rep = long long; using period = micro; using duration = microseconds; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -137,7 +137,7 @@ struct time_point_not_type { using period = micro; using duration = microseconds; char time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static chrono::time_point now(); }; @@ -146,7 +146,7 @@ struct time_point_wrong_type { using period = micro; using duration = microseconds; using time_point = int; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -155,7 +155,7 @@ struct time_point_wrong_type2 { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -164,7 +164,7 @@ struct time_point_different_clock_ok { using period = milli; using duration = milliseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now(); }; @@ -199,7 +199,7 @@ struct now_missing { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; }; struct now_type { @@ -207,7 +207,7 @@ struct now_type { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; using now = time_point; }; @@ -216,7 +216,7 @@ struct now_not_fun { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static time_point now; }; @@ -225,7 +225,7 @@ struct now_not_static { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; time_point now(); }; @@ -234,7 +234,7 @@ struct now_wrong_type { using period = micro; using duration = microseconds; using time_point = time_point; - constexpr static bool is_steady = false; + static constexpr bool is_steady = false; static duration now(); }; From 960d51c128402bda42572577f9ac622963202c11 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 25 Nov 2025 09:59:33 -0800 Subject: [PATCH 11/13] `is_steady_member` => `is_steady_not_static` --- .../tests/P0355R7_calendars_and_time_zones_clocks/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index c1a44bd84f4..beb21099553 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -185,7 +185,7 @@ struct is_steady_type { static time_point now(); }; -struct is_steady_member { +struct is_steady_not_static { using rep = long long; using period = micro; using duration = microseconds; @@ -273,7 +273,7 @@ static_assert(is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v); -static_assert(!is_clock_v); +static_assert(!is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v); From e350ce8bfad9ccdd55af079b6ab567095007db0d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 25 Nov 2025 10:09:00 -0800 Subject: [PATCH 12/13] Add `time_point_wrong_type3`, `is_steady_wrong_type`. --- .../test.cpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index beb21099553..3cc7ea83fa9 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -159,6 +159,15 @@ struct time_point_wrong_type2 { static time_point now(); }; +struct time_point_wrong_type3 { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + static constexpr bool is_steady = false; + static time_point now(); +}; + struct time_point_different_clock_ok { using rep = long long; using period = milli; @@ -194,6 +203,15 @@ struct is_steady_not_static { static time_point now(); }; +struct is_steady_wrong_type { + using rep = long long; + using period = micro; + using duration = microseconds; + using time_point = time_point; + static constexpr int is_steady = 0; + static time_point now(); +}; + struct now_missing { using rep = long long; using period = micro; @@ -269,11 +287,13 @@ static_assert(!is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v); +static_assert(!is_clock_v); static_assert(is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v); +static_assert(!is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v); From c5ba2a8fa8c2649b339ec08fa65a14ae03321feb Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 25 Nov 2025 10:51:33 -0800 Subject: [PATCH 13/13] Reported VSO-2649325 "C1XX incorrectly handles `requires { C::now(); }` when `now` is a type". --- .../std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp index 3cc7ea83fa9..8a2af4a0d1a 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_clocks/test.cpp @@ -296,7 +296,9 @@ static_assert(!is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v); +#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-2649325 static_assert(!is_clock_v); +#endif // ^^^ no workaround ^^^ static_assert(!is_clock_v); static_assert(!is_clock_v); static_assert(!is_clock_v);