Skip to content

[libc++] Add missing C++20 [time.point.arithmetic] #143165

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 11, 2025
Merged

Conversation

maflcko
Copy link
Contributor

@maflcko maflcko commented Jun 6, 2025

This was part of https://wg21.link/p0355r7, but apparently never implemented.

@maflcko maflcko requested a review from a team as a code owner June 6, 2025 15:53
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jun 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 6, 2025

@llvm/pr-subscribers-libcxx

Author: None (maflcko)

Changes

This was part of https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r7.html, but apparently never implemented.


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

6 Files Affected:

  • (modified) libcxx/include/__chrono/time_point.h (+13)
  • (modified) libcxx/include/chrono (+5)
  • (added) libcxx/test/std/time/time.point/time.point.arithmetic/op_++.pass.cpp (+39)
  • (added) libcxx/test/std/time/time.point/time.point.arithmetic/op_++int.pass.cpp (+40)
  • (added) libcxx/test/std/time/time.point/time.point.arithmetic/op_--.pass.cpp (+39)
  • (added) libcxx/test/std/time/time.point/time.point.arithmetic/op_--int.pass.cpp (+40)
diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index 6b866b882f89a..36be0759b6b8c 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -58,6 +58,19 @@ class time_point {
 
   // arithmetic
 
+#if _LIBCPP_STD_VER >= 20
+  _LIBCPP_HIDE_FROM_ABI constexpr time_point& operator++() {
+    ++__d_;
+    return *this;
+  }
+  _LIBCPP_HIDE_FROM_ABI constexpr time_point operator++(int) { return time_point(__d_++); }
+  _LIBCPP_HIDE_FROM_ABI constexpr time_point& operator--() {
+    --__d_;
+    return *this;
+  }
+  _LIBCPP_HIDE_FROM_ABI constexpr time_point operator--(int) { return time_point(__d_--); }
+#endif // _LIBCPP_STD_VER >= 20
+
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) {
     __d_ += __d;
     return *this;
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index cd9b98872083e..82e99a31bcc9f 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -132,6 +132,11 @@ public:
 
     // arithmetic
 
+    constexpr time_point& operator++();    // C++20
+    constexpr time_point  operator++(int); // C++20
+    constexpr time_point& operator--();    // C++20
+    constexpr time_point  operator--(int); // C++20
+
     time_point& operator+=(const duration& d); // constexpr in C++17
     time_point& operator-=(const duration& d); // constexpr in C++17
 
diff --git a/libcxx/test/std/time/time.point/time.point.arithmetic/op_++.pass.cpp b/libcxx/test/std/time/time.point/time.point.arithmetic/op_++.pass.cpp
new file mode 100644
index 0000000000000..dad50d09ed8b0
--- /dev/null
+++ b/libcxx/test/std/time/time.point/time.point.arithmetic/op_++.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// time_point
+
+// constexpr time_point& operator++();
+
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool constexpr_test() {
+  typedef std::chrono::system_clock Clock;
+  typedef std::chrono::milliseconds Duration;
+  std::chrono::time_point<Clock, Duration> t(Duration(5));
+  return (++t).time_since_epoch() == Duration(6);
+}
+
+int main(int, char**) {
+  typedef std::chrono::system_clock Clock;
+  typedef std::chrono::milliseconds Duration;
+  std::chrono::time_point<Clock, Duration> t(Duration(3));
+  std::chrono::time_point<Clock, Duration>& tref = ++t;
+  assert(&tref == &t);
+  assert(t.time_since_epoch() == Duration(4));
+
+  static_assert(constexpr_test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/time/time.point/time.point.arithmetic/op_++int.pass.cpp b/libcxx/test/std/time/time.point/time.point.arithmetic/op_++int.pass.cpp
new file mode 100644
index 0000000000000..c517ff9516bdc
--- /dev/null
+++ b/libcxx/test/std/time/time.point/time.point.arithmetic/op_++int.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// time_point
+
+// constexpr time_point operator++(int);
+
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool test_constexpr() {
+  typedef std::chrono::system_clock Clock;
+  typedef std::chrono::milliseconds Duration;
+  std::chrono::time_point<Clock, Duration> t1(Duration(3));
+  std::chrono::time_point<Clock, Duration> t2 = t1++;
+  return t1.time_since_epoch() == Duration(4) && t2.time_since_epoch() == Duration(3);
+}
+
+int main(int, char**) {
+  typedef std::chrono::system_clock Clock;
+  typedef std::chrono::milliseconds Duration;
+  std::chrono::time_point<Clock, Duration> t1(Duration(3));
+  std::chrono::time_point<Clock, Duration> t2 = t1++;
+  assert(t1.time_since_epoch() == Duration(4));
+  assert(t2.time_since_epoch() == Duration(3));
+
+  static_assert(test_constexpr());
+
+  return 0;
+}
diff --git a/libcxx/test/std/time/time.point/time.point.arithmetic/op_--.pass.cpp b/libcxx/test/std/time/time.point/time.point.arithmetic/op_--.pass.cpp
new file mode 100644
index 0000000000000..7b55f747d06c7
--- /dev/null
+++ b/libcxx/test/std/time/time.point/time.point.arithmetic/op_--.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// time_point
+
+// constexpr time_point& operator--();
+
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool constexpr_test() {
+  typedef std::chrono::system_clock Clock;
+  typedef std::chrono::milliseconds Duration;
+  std::chrono::time_point<Clock, Duration> t(Duration(5));
+  return (--t).time_since_epoch() == Duration(4);
+}
+
+int main(int, char**) {
+  typedef std::chrono::system_clock Clock;
+  typedef std::chrono::milliseconds Duration;
+  std::chrono::time_point<Clock, Duration> t(Duration(3));
+  std::chrono::time_point<Clock, Duration>& tref = --t;
+  assert(&tref == &t);
+  assert(t.time_since_epoch() == Duration(2));
+
+  static_assert(constexpr_test());
+
+  return 0;
+}
diff --git a/libcxx/test/std/time/time.point/time.point.arithmetic/op_--int.pass.cpp b/libcxx/test/std/time/time.point/time.point.arithmetic/op_--int.pass.cpp
new file mode 100644
index 0000000000000..6dfa03c154f57
--- /dev/null
+++ b/libcxx/test/std/time/time.point/time.point.arithmetic/op_--int.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <chrono>
+
+// time_point
+
+// constexpr time_point operator--(int);
+
+#include <chrono>
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool test_constexpr() {
+  typedef std::chrono::system_clock Clock;
+  typedef std::chrono::milliseconds Duration;
+  std::chrono::time_point<Clock, Duration> t1(Duration(3));
+  std::chrono::time_point<Clock, Duration> t2 = t1--;
+  return t1.time_since_epoch() == Duration(2) && t2.time_since_epoch() == Duration(3);
+}
+
+int main(int, char**) {
+  typedef std::chrono::system_clock Clock;
+  typedef std::chrono::milliseconds Duration;
+  std::chrono::time_point<Clock, Duration> t1(Duration(3));
+  std::chrono::time_point<Clock, Duration> t2 = t1--;
+  assert(t1.time_since_epoch() == Duration(2));
+  assert(t2.time_since_epoch() == Duration(3));
+
+  static_assert(test_constexpr());
+
+  return 0;
+}

@maflcko
Copy link
Contributor Author

maflcko commented Jun 6, 2025

Copy link
Contributor

@Zingam Zingam left a comment

Choose a reason for hiding this comment

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

LGTM with the remaining comments, which I think should be addressed.

Copy link
Contributor

@Zingam Zingam left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you.
Let's wait for a library maintainer to approve (and merge) the PR.

@maflcko maflcko merged commit a17e97e into llvm:main Jun 11, 2025
76 of 79 checks passed
rorth pushed a commit to rorth/llvm-project that referenced this pull request Jun 11, 2025
This was part of https://wg21.link/p0355r7, but apparently never
implemented.

---------

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^[email protected]>
Co-authored-by: Hristo Hristov <[email protected]>
tomtor pushed a commit to tomtor/llvm-project that referenced this pull request Jun 14, 2025
This was part of https://wg21.link/p0355r7, but apparently never
implemented.

---------

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^[email protected]>
Co-authored-by: Hristo Hristov <[email protected]>
akuhlens pushed a commit to akuhlens/llvm-project that referenced this pull request Jun 24, 2025
This was part of https://wg21.link/p0355r7, but apparently never
implemented.

---------

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^[email protected]>
Co-authored-by: Hristo Hristov <[email protected]>
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.

4 participants