[libcxx-commits] [libcxx] [libc++] Refactor some .fail.cpp tests and fix time_point_cast not SFINAEing away (PR #159288)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Sep 24 01:48:27 PDT 2025


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/159288

>From cd9454a6a31da0caa5eec65ed31a85b35e94e6d9 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 17 Sep 2025 10:57:41 +0200
Subject: [PATCH] [libc++] Refactor some .fail.cpp tests and fix
 time_point_cast not SFINAEing away

---
 libcxx/include/__chrono/time_point.h          |  2 +-
 libcxx/include/__cxx03/__chrono/time_point.h  |  2 +-
 .../time.duration.alg/abs.compile.fail.cpp    | 28 ------------------
 .../time.duration.alg/abs.pass.cpp            | 10 +++++++
 .../time.point.cast/ceil.compile.fail.cpp     | 27 -----------------
 .../time.point/time.point.cast/ceil.pass.cpp  |  9 ++++++
 .../time.point.cast/floor.compile.fail.cpp    | 27 -----------------
 .../time.point/time.point.cast/floor.pass.cpp |  9 ++++++
 .../time.point.cast/round.compile.fail.cpp    | 27 -----------------
 .../time.point/time.point.cast/round.pass.cpp |  9 ++++++
 .../time.point.cast/time_point_cast.pass.cpp  | 10 +++++++
 .../toduration.compile.fail.cpp               | 29 -------------------
 12 files changed, 49 insertions(+), 140 deletions(-)
 delete mode 100644 libcxx/test/std/time/time.duration/time.duration.alg/abs.compile.fail.cpp
 delete mode 100644 libcxx/test/std/time/time.point/time.point.cast/ceil.compile.fail.cpp
 delete mode 100644 libcxx/test/std/time/time.point/time.point.cast/floor.compile.fail.cpp
 delete mode 100644 libcxx/test/std/time/time.point/time.point.cast/round.compile.fail.cpp
 delete mode 100644 libcxx/test/std/time/time.point/time.point.cast/toduration.compile.fail.cpp

diff --git a/libcxx/include/__chrono/time_point.h b/libcxx/include/__chrono/time_point.h
index fc4408d23dbf1..bc2c7798a630b 100644
--- a/libcxx/include/__chrono/time_point.h
+++ b/libcxx/include/__chrono/time_point.h
@@ -95,7 +95,7 @@ struct common_type<chrono::time_point<_Clock, _Duration1>, chrono::time_point<_C
 
 namespace chrono {
 
-template <class _ToDuration, class _Clock, class _Duration>
+template <class _ToDuration, class _Clock, class _Duration, __enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration>
 time_point_cast(const time_point<_Clock, _Duration>& __t) {
   return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
diff --git a/libcxx/include/__cxx03/__chrono/time_point.h b/libcxx/include/__cxx03/__chrono/time_point.h
index 8ec687d837717..7f2a73af839ca 100644
--- a/libcxx/include/__cxx03/__chrono/time_point.h
+++ b/libcxx/include/__cxx03/__chrono/time_point.h
@@ -81,7 +81,7 @@ common_type<chrono::time_point<_Clock, _Duration1>, chrono::time_point<_Clock, _
 
 namespace chrono {
 
-template <class _ToDuration, class _Clock, class _Duration>
+template <class _ToDuration, class _Clock, class _Duration, __enable_if_t<__is_duration<_ToDuration>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI time_point<_Clock, _ToDuration> time_point_cast(const time_point<_Clock, _Duration>& __t) {
   return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
 }
diff --git a/libcxx/test/std/time/time.duration/time.duration.alg/abs.compile.fail.cpp b/libcxx/test/std/time/time.duration/time.duration.alg/abs.compile.fail.cpp
deleted file mode 100644
index 8d807c7a9b395..0000000000000
--- a/libcxx/test/std/time/time.duration/time.duration.alg/abs.compile.fail.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// <chrono>
-
-// ceil
-
-// template <class Rep, class Period>
-//   constexpr duration<Rep, Period> abs(duration<Rep, Period> d)
-
-// This function shall not participate in overload resolution unless numeric_limits<Rep>::is_signed is true.
-
-#include <chrono>
-
-typedef std::chrono::duration<unsigned> unsigned_secs;
-
-int main(int, char**)
-{
-    std::chrono::abs(unsigned_secs(0));
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.duration/time.duration.alg/abs.pass.cpp b/libcxx/test/std/time/time.duration/time.duration.alg/abs.pass.cpp
index f95d42b52638e..42f4323b5bd27 100644
--- a/libcxx/test/std/time/time.duration/time.duration.alg/abs.pass.cpp
+++ b/libcxx/test/std/time/time.duration/time.duration.alg/abs.pass.cpp
@@ -19,9 +19,19 @@
 #include <cassert>
 #include <ratio>
 #include <type_traits>
+#include <utility>
 
 #include "test_macros.h"
 
+template <class T, class = void>
+inline constexpr bool has_abs_v = false;
+
+template <class T>
+inline constexpr bool has_abs_v<T, decltype((void)std::chrono::abs(std::declval<T>()))> = true;
+
+static_assert(has_abs_v<std::chrono::milliseconds>);
+static_assert(!has_abs_v<std::chrono::duration<unsigned>>);
+
 template <class Duration>
 void
 test(const Duration& f, const Duration& d)
diff --git a/libcxx/test/std/time/time.point/time.point.cast/ceil.compile.fail.cpp b/libcxx/test/std/time/time.point/time.point.cast/ceil.compile.fail.cpp
deleted file mode 100644
index fb82fdffe4d2a..0000000000000
--- a/libcxx/test/std/time/time.point/time.point.cast/ceil.compile.fail.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// <chrono>
-
-// ceil
-
-// template <class ToDuration, class Clock, class Duration>
-//   time_point<Clock, ToDuration>
-//   ceil(const time_point<Clock, Duration>& t);
-
-// ToDuration shall be an instantiation of duration.
-
-#include <chrono>
-
-int main(int, char**)
-{
-    std::chrono::ceil<int>(std::chrono::system_clock::now());
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.point/time.point.cast/ceil.pass.cpp b/libcxx/test/std/time/time.point/time.point.cast/ceil.pass.cpp
index 58bcf73234f91..4e383ba923759 100644
--- a/libcxx/test/std/time/time.point/time.point.cast/ceil.pass.cpp
+++ b/libcxx/test/std/time/time.point/time.point.cast/ceil.pass.cpp
@@ -21,6 +21,15 @@
 
 #include "test_macros.h"
 
+template <class T, class = void>
+inline constexpr bool has_ceil_v = false;
+
+template <class T>
+inline constexpr bool has_ceil_v<T, decltype((void)std::chrono::ceil<T>(std::chrono::system_clock::now()))> = true;
+
+static_assert(has_ceil_v<std::chrono::seconds>);
+static_assert(!has_ceil_v<int>);
+
 template <class FromDuration, class ToDuration>
 void
 test(const FromDuration& df, const ToDuration& d)
diff --git a/libcxx/test/std/time/time.point/time.point.cast/floor.compile.fail.cpp b/libcxx/test/std/time/time.point/time.point.cast/floor.compile.fail.cpp
deleted file mode 100644
index 12b1dec9fd509..0000000000000
--- a/libcxx/test/std/time/time.point/time.point.cast/floor.compile.fail.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// <chrono>
-
-// floor
-
-// template <class ToDuration, class Clock, class Duration>
-//   time_point<Clock, ToDuration>
-//   floor(const time_point<Clock, Duration>& t);
-
-// ToDuration shall be an instantiation of duration.
-
-#include <chrono>
-
-int main(int, char**)
-{
-    std::chrono::floor<int>(std::chrono::system_clock::now());
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.point/time.point.cast/floor.pass.cpp b/libcxx/test/std/time/time.point/time.point.cast/floor.pass.cpp
index e53ce86869f7a..69e4d096b7441 100644
--- a/libcxx/test/std/time/time.point/time.point.cast/floor.pass.cpp
+++ b/libcxx/test/std/time/time.point/time.point.cast/floor.pass.cpp
@@ -21,6 +21,15 @@
 
 #include "test_macros.h"
 
+template <class T, class = void>
+inline constexpr bool has_floor_v = false;
+
+template <class T>
+inline constexpr bool has_floor_v<T, decltype((void)std::chrono::floor<T>(std::chrono::system_clock::now()))> = true;
+
+static_assert(has_floor_v<std::chrono::seconds>);
+static_assert(!has_floor_v<int>);
+
 template <class FromDuration, class ToDuration>
 void
 test(const FromDuration& df, const ToDuration& d)
diff --git a/libcxx/test/std/time/time.point/time.point.cast/round.compile.fail.cpp b/libcxx/test/std/time/time.point/time.point.cast/round.compile.fail.cpp
deleted file mode 100644
index a5436c684040d..0000000000000
--- a/libcxx/test/std/time/time.point/time.point.cast/round.compile.fail.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-// <chrono>
-
-// round
-
-// template <class ToDuration, class Clock, class Duration>
-//   time_point<Clock, ToDuration>
-//   round(const time_point<Clock, Duration>& t);
-
-// ToDuration shall be an instantiation of duration.
-
-#include <chrono>
-
-int main(int, char**)
-{
-    std::chrono::round<int>(std::chrono::system_clock::now());
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.point/time.point.cast/round.pass.cpp b/libcxx/test/std/time/time.point/time.point.cast/round.pass.cpp
index 4523abd27d035..74f05f72daf7c 100644
--- a/libcxx/test/std/time/time.point/time.point.cast/round.pass.cpp
+++ b/libcxx/test/std/time/time.point/time.point.cast/round.pass.cpp
@@ -21,6 +21,15 @@
 
 #include "test_macros.h"
 
+template <class T, class = void>
+inline constexpr bool has_round_v = false;
+
+template <class T>
+inline constexpr bool has_round_v<T, decltype((void)std::chrono::round<T>(std::chrono::system_clock::now()))> = true;
+
+static_assert(has_round_v<std::chrono::seconds>);
+static_assert(!has_round_v<int>);
+
 template <class FromDuration, class ToDuration>
 void
 test(const FromDuration& df, const ToDuration& d)
diff --git a/libcxx/test/std/time/time.point/time.point.cast/time_point_cast.pass.cpp b/libcxx/test/std/time/time.point/time.point.cast/time_point_cast.pass.cpp
index 0d82e2db8b7b7..d82cf42c145f9 100644
--- a/libcxx/test/std/time/time.point/time.point.cast/time_point_cast.pass.cpp
+++ b/libcxx/test/std/time/time.point/time.point.cast/time_point_cast.pass.cpp
@@ -21,6 +21,16 @@
 
 #include "test_macros.h"
 
+template <class T, class = void>
+struct has_time_point_cast : std::false_type {};
+
+template <class T>
+struct has_time_point_cast<T, decltype((void)std::chrono::time_point_cast<T>(std::chrono::system_clock::now()))>
+    : std::true_type {};
+
+static_assert(has_time_point_cast<std::chrono::seconds>::value, "");
+static_assert(!has_time_point_cast<int>::value, "");
+
 template <class FromDuration, class ToDuration>
 void
 test(const FromDuration& df, const ToDuration& d)
diff --git a/libcxx/test/std/time/time.point/time.point.cast/toduration.compile.fail.cpp b/libcxx/test/std/time/time.point/time.point.cast/toduration.compile.fail.cpp
deleted file mode 100644
index c16492f730a17..0000000000000
--- a/libcxx/test/std/time/time.point/time.point.cast/toduration.compile.fail.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <chrono>
-
-// time_point
-
-// template <class ToDuration, class Clock, class Duration>
-//   time_point<Clock, ToDuration>
-//   time_point_cast(const time_point<Clock, Duration>& t);
-
-// ToDuration shall be an instantiation of duration.
-
-#include <chrono>
-
-int main(int, char**)
-{
-    typedef std::chrono::system_clock Clock;
-    typedef std::chrono::time_point<Clock, std::chrono::milliseconds> FromTimePoint;
-    typedef std::chrono::time_point<Clock, std::chrono::minutes> ToTimePoint;
-    std::chrono::time_point_cast<ToTimePoint>(FromTimePoint(std::chrono::milliseconds(3)));
-
-  return 0;
-}



More information about the libcxx-commits mailing list