diff --git a/ChangeLog.rst b/ChangeLog.rst index d43d0699..26f2b0a6 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,3 +1,6 @@ +6.0.0 - TBD +----------- + 5.3.0 - 2018-12-28 ------------------ diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index f19a5e96..e2a47019 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -477,7 +477,10 @@ template ::value)> inline std::chrono::duration get_milliseconds( std::chrono::duration d) { - auto ms = mod(d.count() * Period::num / Period::den * 1000, 1000); + using common_type = typename std::common_type::type; + auto ms = mod(d.count() * static_cast(Period::num) / + static_cast(Period::den) * 1000, + 1000); return std::chrono::duration(static_cast(ms)); } diff --git a/include/fmt/safe-duration-cast.h b/include/fmt/safe-duration-cast.h index e69450f4..db2a340b 100644 --- a/include/fmt/safe-duration-cast.h +++ b/include/fmt/safe-duration-cast.h @@ -20,12 +20,10 @@ FMT_BEGIN_NAMESPACE namespace safe_duration_cast { -/** - * converts From to To, without loss. If the dynamic value of from - * can't be converted to To without loss, ec is set. - */ template ::value)> + FMT_ENABLE_IF(!std::is_same::value && + std::numeric_limits::is_signed == + std::numeric_limits::is_signed)> FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { ec = 0; using F = std::numeric_limits; @@ -33,19 +31,34 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { static_assert(F::is_integer, "From must be integral"); static_assert(T::is_integer, "To must be integral"); - if (F::is_signed == T::is_signed) { - // A and B are both signed, or both unsigned. - if (F::digits <= T::digits) { - // From fits in To without any problem - } else { - // From does not always fit in To, resort to a dynamic check. - if (from < T::min() || from > T::max()) { - // outside range. - ec = 1; - return {}; - } + // A and B are both signed, or both unsigned. + if (F::digits <= T::digits) { + // From fits in To without any problem. + } else { + // From does not always fit in To, resort to a dynamic check. + if (from < T::min() || from > T::max()) { + // outside range. + ec = 1; + return {}; } } + return static_cast(from); +} + +/** + * converts From to To, without loss. If the dynamic value of from + * can't be converted to To without loss, ec is set. + */ +template ::value && + std::numeric_limits::is_signed != + std::numeric_limits::is_signed)> +FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { + ec = 0; + using F = std::numeric_limits; + using T = std::numeric_limits; + static_assert(F::is_integer, "From must be integral"); + static_assert(T::is_integer, "To must be integral"); if (F::is_signed && !T::is_signed) { // From may be negative, not allowed! @@ -261,7 +274,8 @@ To safe_duration_cast(std::chrono::duration from, // this can't go wrong, right? den>0 is checked earlier. if (Factor::den != 1) { - count /= Factor::den; + using common_t = typename std::common_type::type; + count /= static_cast(Factor::den); } // convert to the to type, safely