Skip to content

Commit

Permalink
Fix bogus MSVC warnings (#1825)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Aug 26, 2020
1 parent 5dff01d commit 77b627b
Showing 1 changed file with 16 additions and 42 deletions.
58 changes: 16 additions & 42 deletions include/fmt/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,43 +72,27 @@ 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) {
if (detail::const_check(F::is_signed && !T::is_signed)) {
// From may be negative, not allowed!
if (fmt::detail::is_negative(from)) {
ec = 1;
return {};
}

// From is positive. Can it always fit in To?
if (F::digits <= T::digits) {
// yes, From always fits in To.
} else {
// from may not fit in To, we have to do a dynamic check
if (from > static_cast<From>((T::max)())) {
ec = 1;
return {};
}
if (F::digits > T::digits &&
from > static_cast<From>(detail::max_value<To>())) {
ec = 1;
return {};
}
}

if (!F::is_signed && T::is_signed) {
// can from be held in To?
if (F::digits < T::digits) {
// yes, From always fits in To.
} else {
// from may not fit in To, we have to do a dynamic check
if (from > static_cast<From>((T::max)())) {
// outside range.
ec = 1;
return {};
}
}
if (!F::is_signed && T::is_signed && F::digits >= T::digits &&
from > static_cast<From>(detail::max_value<To>())) {
ec = 1;
return {};
}

// reaching here means all is ok for lossless conversion.
return static_cast<To>(from);

} // function
return static_cast<To>(from); // Lossless conversion.
}

template <typename To, typename From,
FMT_ENABLE_IF(std::is_same<From, To>::value)>
Expand Down Expand Up @@ -190,11 +174,9 @@ To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
// safe conversion to IntermediateRep
IntermediateRep count =
lossless_integral_conversion<IntermediateRep>(from.count(), ec);
if (ec) {
return {};
}
if (ec) return {};
// multiply with Factor::num without overflow or underflow
if (Factor::num != 1) {
if (detail::const_check(Factor::num != 1)) {
const auto max1 = detail::max_value<IntermediateRep>() / Factor::num;
if (count > max1) {
ec = 1;
Expand All @@ -209,17 +191,9 @@ To safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
count *= Factor::num;
}

// this can't go wrong, right? den>0 is checked earlier.
if (Factor::den != 1) {
count /= Factor::den;
}
// convert to the to type, safely
using ToRep = typename To::rep;
const ToRep tocount = lossless_integral_conversion<ToRep>(count, ec);
if (ec) {
return {};
}
return To{tocount};
if (detail::const_check(Factor::den != 1)) count /= Factor::den;
auto tocount = lossless_integral_conversion<typename To::rep>(count, ec);
return ec ? To() : To(tocount);
}

/**
Expand Down

0 comments on commit 77b627b

Please sign in to comment.