[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