[libcxx-commits] [libcxx] [libcxx] Implement C++20 std::chrono::is_clock, std::chrono::is_clock_v (PR #160607)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Thu Sep 25 18:04:21 PDT 2025


================
@@ -0,0 +1,242 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+
+#include <chrono>
+#include <ratio>
+
+struct EmptyStruct {};
+
+// Test structs missing required members
+struct MissingRep {
+  using period                    = std::ratio<1>;
+  using duration                  = std::chrono::seconds;
+  using time_point                = std::chrono::time_point<MissingRep>;
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+struct MissingPeriod {
+  using rep                       = long;
+  using duration                  = std::chrono::seconds;
+  using time_point                = std::chrono::time_point<MissingPeriod>;
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+struct MissingDuration {
+  using rep                       = long;
+  using time_point                = long;
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+struct MissingTimePoint {
+  using rep                       = long;
+  using period                    = std::ratio<1>;
+  using duration                  = std::chrono::seconds;
+  static constexpr bool is_steady = false;
+  static std::chrono::time_point<MissingTimePoint> now();
+};
+
+struct MissingIsSteady {
+  using rep        = long;
+  using period     = std::ratio<1>;
+  using duration   = std::chrono::seconds;
+  using time_point = std::chrono::time_point<MissingIsSteady>;
+  static time_point now();
+};
+
+struct MissingNow {
+  using rep                       = long;
+  using period                    = std::ratio<1>;
+  using duration                  = std::chrono::seconds;
+  using time_point                = std::chrono::time_point<MissingNow>;
+  static constexpr bool is_steady = false;
+};
+
+// Valid clock types
+struct ValidSteadyClock {
+  using rep                       = long long;
+  using period                    = std::nano;
+  using duration                  = std::chrono::nanoseconds;
+  using time_point                = std::chrono::time_point<ValidSteadyClock>;
+  static constexpr bool is_steady = true;
+  static time_point now();
+};
+
+struct ValidSystemClock {
+  using rep                       = long long;
+  using period                    = std::micro;
+  using duration                  = std::chrono::microseconds;
+  using time_point                = std::chrono::time_point<ValidSystemClock>;
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+// Test clocks with invalid is_steady type
+struct WrongIsSteadyType {
+  using rep        = long;
+  using period     = std::ratio<1>;
+  using duration   = std::chrono::seconds;
+  using time_point = std::chrono::time_point<WrongIsSteadyType>;
+  static bool is_steady; // Not const bool
+  static time_point now();
+};
+
+struct WrongIsSteadyNonBool {
+  using rep                      = long;
+  using period                   = std::ratio<1>;
+  using duration                 = std::chrono::seconds;
+  using time_point               = std::chrono::time_point<WrongIsSteadyNonBool>;
+  static constexpr int is_steady = 1; // Not bool
+  static time_point now();
+};
+
+// Test clocks with invalid now() return type
+struct WrongNowReturnType {
+  using rep                       = long;
+  using period                    = std::ratio<1>;
+  using duration                  = std::chrono::seconds;
+  using time_point                = std::chrono::time_point<WrongNowReturnType>;
+  static constexpr bool is_steady = false;
+  static int now(); // Wrong return type
+};
+
+// Test clocks with invalid period type
+struct WrongPeriodType {
+  using rep                       = long;
+  using period                    = int; // Not a ratio
+  using duration                  = std::chrono::seconds;
+  using time_point                = std::chrono::time_point<WrongPeriodType>;
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+// Test clocks with invalid rep type (neither arithmetic nor numeric_limits specialized)
+struct InvalidRepType {
+  using rep                       = EmptyStruct; // Not arithmetic, no numeric_limits specialization
+  using period                    = std::ratio<1>;
+  using duration                  = std::chrono::duration<EmptyStruct>;
+  using time_point                = std::chrono::time_point<InvalidRepType, duration>;
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+// Test clocks with wrong duration type
+struct WrongDurationType {
+  using rep                       = long;
+  using period                    = std::ratio<1>;
+  using duration                  = std::chrono::milliseconds; // Should be duration<long, ratio<1>>
+  using time_point                = std::chrono::time_point<WrongDurationType>;
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+// Test clocks with wrong time_point type
+struct WrongTimePointType {
+  using rep                       = long;
+  using period                    = std::ratio<1>;
+  using duration                  = std::chrono::duration<long, std::ratio<1>>;
+  using time_point                = int; // Not a time_point
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+struct WrongTimePointClock {
+  using rep                       = long;
+  using period                    = std::ratio<1>;
+  using duration                  = std::chrono::duration<long, std::ratio<1>>;
+  using time_point                = std::chrono::time_point<ValidSystemClock>; // Wrong clock type
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+// Valid clock with time_point that has matching duration instead of matching clock
+struct ValidClockWithDurationMatch {
+  using rep                       = int;
+  using period                    = std::milli;
+  using duration                  = std::chrono::duration<int, std::milli>;
+  using time_point                = std::chrono::time_point<ValidSystemClock, duration>; // Valid: matches duration
+  static constexpr bool is_steady = false;
+  static time_point now();
+};
+
+int main(int, char**) {
----------------
frederick-vs-ja wrote:

Given you've turned the test file into a `.compile.pass.cpp`, it's probably better to remove the `main` function and put the static assertions in the global namespace scope.

https://github.com/llvm/llvm-project/pull/160607


More information about the libcxx-commits mailing list