From a3b3d7ed46a192e1a229e9df508d30b1029e537e Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 13 Sep 2025 11:02:51 -0700 Subject: [PATCH] Simplify duration cast --- include/fmt/chrono.h | 23 ++++++----------------- include/fmt/format.h | 1 + 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 0b5f3cc7..a788d3ec 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -38,6 +38,7 @@ FMT_BEGIN_NAMESPACE // Copyright Paul Dreik 2019 namespace safe_duration_cast { +// DEPRECATED! template ::value && std::numeric_limits::is_signed == @@ -161,17 +162,6 @@ auto safe_duration_cast(std::chrono::duration from, int& ec) -> To { using From = std::chrono::duration; ec = 0; - if (std::isnan(from.count())) { - // nan in, gives nan out. easy. - return To{std::numeric_limits::quiet_NaN()}; - } - // maybe we should also check if from is denormal, and decide what to do about - // it. - - // +-inf should be preserved. - if (std::isinf(from.count())) { - return To{from.count()}; - } // the basic idea is that we need to convert from count() in the from type // to count() in the To type, by multiplying it with this: @@ -441,11 +431,7 @@ auto duration_cast(std::chrono::duration from) -> To { using common_rep = typename std::common_type::type; - - int ec = 0; - auto count = safe_duration_cast::lossless_integral_conversion( - from.count(), ec); - if (ec) throw_duration_error(); + common_rep count = from.count(); // This conversion is lossless. // Multiply from.count() by factor and check for overflow. if (const_check(factor::num != 1)) { @@ -456,6 +442,7 @@ auto duration_cast(std::chrono::duration from) -> To { count *= factor::num; } if (const_check(factor::den != 1)) count /= factor::den; + int ec = 0; auto to = To(safe_duration_cast::lossless_integral_conversion( count, ec)); @@ -469,6 +456,8 @@ template ::value)> auto duration_cast(std::chrono::duration from) -> To { #if FMT_SAFE_DURATION_CAST + // Preserve infinity and NaN. + if (!isfinite(from.count())) return static_cast(from.count()); // Throwing version of safe_duration_cast is only available for // integer to integer or float to float casts. int ec; @@ -485,7 +474,7 @@ template ::value)> auto duration_cast(std::chrono::duration from) -> To { - // Mixed integer <-> float cast is not supported by safe_duration_cast. + // Mixed integer <-> float cast is not supported by safe duration_cast. return std::chrono::duration_cast(from); } diff --git a/include/fmt/format.h b/include/fmt/format.h index 8c1c070f..c3a1bda0 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3792,6 +3792,7 @@ template struct format_handler { FMT_NORETURN void on_error(const char* message) { report_error(message); } }; +// It is used in format-inl.h and os.cc. using format_func = void (*)(detail::buffer&, int, const char*); FMT_API void do_report_error(format_func func, int error_code, const char* message) noexcept;