[libcxx-commits] [libcxx] [libc++] Rewrite duration_cast to use if constexpr (PR #178385)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jan 28 01:27:46 PST 2026


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/178385

This simplifies the implementation quite a bit and makes compiling `duration_cast` faster to compile, since we avoid instantiating some unnecessary extra stuff.


>From b29f7a3566d9f30bd36f0496ea7acce084aaa813 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 28 Jan 2026 10:26:30 +0100
Subject: [PATCH] [libc++] Rewrite duration_cast to use if constexpr

---
 libcxx/include/__chrono/duration.h | 59 +++++++++---------------------
 1 file changed, 17 insertions(+), 42 deletions(-)

diff --git a/libcxx/include/__chrono/duration.h b/libcxx/include/__chrono/duration.h
index 9313fc797ecd5..8bf3c06035821 100644
--- a/libcxx/include/__chrono/duration.h
+++ b/libcxx/include/__chrono/duration.h
@@ -62,51 +62,26 @@ namespace chrono {
 
 // duration_cast
 
-template <class _FromDuration,
-          class _ToDuration,
-          class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type,
-          bool          = _Period::num == 1,
-          bool          = _Period::den == 1>
-struct __duration_cast;
-
-template <class _FromDuration, class _ToDuration, class _Period>
-struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> {
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const {
-    return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));
-  }
-};
-
-template <class _FromDuration, class _ToDuration, class _Period>
-struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> {
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const {
-    typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
-    return _ToDuration(
-        static_cast<typename _ToDuration::rep>(static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den)));
-  }
-};
-
-template <class _FromDuration, class _ToDuration, class _Period>
-struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> {
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const {
-    typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
-    return _ToDuration(
-        static_cast<typename _ToDuration::rep>(static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)));
-  }
-};
-
-template <class _FromDuration, class _ToDuration, class _Period>
-struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> {
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const {
-    typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
-    return _ToDuration(static_cast<typename _ToDuration::rep>(
-        static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) / static_cast<_Ct>(_Period::den)));
-  }
-};
-
 template <class _ToDuration, class _Rep, class _Period, __enable_if_t<__is_duration_v<_ToDuration>, int> = 0>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration
 duration_cast(const duration<_Rep, _Period>& __fd) {
-  return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
+  using _CommonPeriod = typename ratio_divide<_Period, typename _ToDuration::period>::type;
+  if _LIBCPP_CONSTEXPR (_CommonPeriod::num == 1 && _CommonPeriod::den == 1) {
+    return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));
+  } else {
+    using _Ct = typename common_type<typename _ToDuration::rep, _Rep, intmax_t>::type;
+    if _LIBCPP_CONSTEXPR (_CommonPeriod::num == 1) {
+      return _ToDuration(static_cast<typename _ToDuration::rep>(
+          static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_CommonPeriod::den)));
+    } else if _LIBCPP_CONSTEXPR (_CommonPeriod::den == 1) {
+      return _ToDuration(static_cast<typename _ToDuration::rep>(
+          static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_CommonPeriod::num)));
+    } else {
+      return _ToDuration(static_cast<typename _ToDuration::rep>(
+          static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_CommonPeriod::num) /
+          static_cast<_Ct>(_CommonPeriod::den)));
+    }
+  }
 }
 
 template <class _Rep>



More information about the libcxx-commits mailing list