Skip to content

Conversation

yuxuanchen1997
Copy link
Member

@yuxuanchen1997 yuxuanchen1997 commented Sep 24, 2025

Implemented [time.traits.is.clock] from P0355R7.

This patch implements the C++20 feature is_clock and is_clock_v based on the documentation on cppreference

It doesn't seem like we track this particular feature in #99982, but it's necessary to implement.

@yuxuanchen1997 yuxuanchen1997 requested a review from a team as a code owner September 24, 2025 21:32
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Sep 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 24, 2025

@llvm/pr-subscribers-libcxx

Author: Yuxuan Chen (yuxuanchen1997)

Changes

Implemented [time.traits.is.clock] from P0355.


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

5 Files Affected:

  • (modified) libcxx/include/CMakeLists.txt (+1)
  • (added) libcxx/include/__chrono/is_clock.h (+45)
  • (modified) libcxx/include/chrono (+1)
  • (modified) libcxx/modules/std/chrono.inc (+2-2)
  • (added) libcxx/test/std/time/time.traits.is.clock/trait.is.clock.pass.cpp (+22)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index e050362abb658..210ea8be4a69d 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -261,6 +261,7 @@ set(files
   __chrono/formatter.h
   __chrono/gps_clock.h
   __chrono/hh_mm_ss.h
+  __chrono/is_clock.h
   __chrono/high_resolution_clock.h
   __chrono/leap_second.h
   __chrono/literals.h
diff --git a/libcxx/include/__chrono/is_clock.h b/libcxx/include/__chrono/is_clock.h
new file mode 100644
index 0000000000000..dc64c9eacd80b
--- /dev/null
+++ b/libcxx/include/__chrono/is_clock.h
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___CHRONO_IS_CLOCK_H
+#define _LIBCPP___CHRONO_IS_CLOCK_H
+
+#include <__config>
+
+#if _LIBCPP_STD_VER >= 20
+
+#  include <__type_traits/integral_constant.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono {
+
+template <class>
+struct is_clock : std::false_type {};
+
+template <class _Tp>
+  requires requires {
+    typename _Tp::rep;
+    typename _Tp::period;
+    typename _Tp::duration;
+    typename _Tp::time_point;
+    _Tp::is_steady;
+    _Tp::now();
+  }
+struct is_clock<_Tp> : std::true_type {};
+
+template <class _Tp>
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_clock_v = is_clock<_Tp>::value;
+
+} // namespace chrono
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER
+#endif // _LIBCPP___CHRONO_IS_CLOCK_H
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 82e99a31bcc9f..f3bb08ef386c9 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -1057,6 +1057,7 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 #    include <__chrono/day.h>
 #    include <__chrono/exception.h>
 #    include <__chrono/hh_mm_ss.h>
+#    include <__chrono/is_clock.h>
 #    include <__chrono/literals.h>
 #    include <__chrono/local_info.h>
 #    include <__chrono/month.h>
diff --git a/libcxx/modules/std/chrono.inc b/libcxx/modules/std/chrono.inc
index 66eccd8d290ad..db405d482bf9e 100644
--- a/libcxx/modules/std/chrono.inc
+++ b/libcxx/modules/std/chrono.inc
@@ -25,8 +25,8 @@ export namespace std {
 
     using std::chrono::duration_values;
 
-    // using std::chrono::is_clock;
-    // using std::chrono::is_clock_v;
+    using std::chrono::is_clock;
+    using std::chrono::is_clock_v;
 
     // [time.duration.nonmember], duration arithmetic
     using std::chrono::operator+;
diff --git a/libcxx/test/std/time/time.traits.is.clock/trait.is.clock.pass.cpp b/libcxx/test/std/time/time.traits.is.clock/trait.is.clock.pass.cpp
new file mode 100644
index 0000000000000..b15e91c48b0be
--- /dev/null
+++ b/libcxx/test/std/time/time.traits.is.clock/trait.is.clock.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+struct NotAClock {};
+
+int main(int, char**) {
+  static_assert(!std::chrono::is_clock_v<NotAClock>, "should not be treated as a clock");
+
+  static_assert(std::chrono::is_clock_v<std::chrono::system_clock>);
+  static_assert(std::chrono::is_clock_v<std::chrono::steady_clock>);
+  static_assert(std::chrono::is_clock_v<std::chrono::high_resolution_clock>);
+  return 0;
+}

@yuxuanchen1997 yuxuanchen1997 force-pushed the users/yuxuanchen1997/libcxx-is-clock branch from d25ec00 to ec64186 Compare September 24, 2025 21:35
@yuxuanchen1997 yuxuanchen1997 self-assigned this Sep 24, 2025
@yuxuanchen1997 yuxuanchen1997 force-pushed the users/yuxuanchen1997/libcxx-is-clock branch from ec64186 to 977db81 Compare September 24, 2025 22:25
@yuxuanchen1997 yuxuanchen1997 force-pushed the users/yuxuanchen1997/libcxx-is-clock branch from 977db81 to 74f494a Compare September 24, 2025 22:58
Co-authored-by: A. Jiang <de34@live.cn>
@H-G-Hristov
Copy link
Contributor

Implemented [time.traits.is.clock] from P0355R7.

This patch implements the C++20 feature is_clock and is_clock_v based on the documentation on cppreference

It doesn't seem like we track this particular feature in #99982, but it's necessary to implement.

Would it make sense to create a sub-task to track this item in #99982?

Copy link

github-actions bot commented Sep 25, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@yuxuanchen1997
Copy link
Member Author

After some feedback, we decided to implement more checks based on the Cpp17Clock requirement. The standard underspecifies what checks need to be done.

For the purposes of the specification of this trait, the extent to which an implementation determines that a type cannot meet the Cpp17Clock requirements is unspecified

The set of requirements for is_clock_v has updated as a result.

@yuxuanchen1997 yuxuanchen1997 force-pushed the users/yuxuanchen1997/libcxx-is-clock branch from 8a6adc0 to bd7ca12 Compare September 25, 2025 22:36

template <class _Clock, class _Duration, class _ClockType>
constexpr bool __is_valid_clock_time_point_v<time_point<_Clock, _Duration>, _ClockType> =
_IsSame<time_point<_Clock, _Duration>, time_point<_ClockType>>::value ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can manually add the template argument here:

Suggested change
_IsSame<time_point<_Clock, _Duration>, time_point<_ClockType>>::value ||
_IsSame<time_point<_Clock, _Duration>, time_point<_ClockType, typename _ClockType::duration>>::value ||

However, it seems simpler to check the relationship between _Tp::time_point and _Tp::duration. I.e. _Tp::time_point must be of form time_point<_Clock, typename _Tp::duration>.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just change it to

requires _IsSame<typename _Tp::time_point::duration, typename _Tp::duration>::value;

?

I think it's the same. Just taking advantage the member type alias.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. They're not the same IIUC. We should also check that _Tp::time_point is a std::chrono::time_point specialization.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. They're not the same IIUC. We should also check that _Tp::time_point is a std::chrono::time_point specialization.

I have updated the patch to incorporate your suggestion "_Tp::time_point must be of form time_point<_Clock, typename _Tp::duration>."

This seems both correct and concise to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants