Change all uses of round to detail::round_i

Fixes #613

detail::round_i is the same as round when the To::rep
is integral, and is just an implicit conversion when
To::rep is floating point.
This commit is contained in:
Howard Hinnant
2020-10-25 20:16:07 -04:00
parent 3cbfa4318f
commit 215cacff56

View File

@ -1358,6 +1358,47 @@ using std::chrono::abs;
#endif // HAS_CHRONO_ROUNDING #endif // HAS_CHRONO_ROUNDING
namespace detail
{
template <class To, class Rep, class Period>
CONSTCD14
inline
typename std::enable_if
<
!std::chrono::treat_as_floating_point<typename To::rep>::value,
To
>::type
round_i(const std::chrono::duration<Rep, Period>& d)
{
return round<To>(d);
}
template <class To, class Rep, class Period>
CONSTCD14
inline
typename std::enable_if
<
std::chrono::treat_as_floating_point<typename To::rep>::value,
To
>::type
round_i(const std::chrono::duration<Rep, Period>& d)
{
return d;
}
template <class To, class Clock, class FromDuration>
CONSTCD11
inline
std::chrono::time_point<Clock, To>
round_i(const std::chrono::time_point<Clock, FromDuration>& tp)
{
using std::chrono::time_point;
return time_point<Clock, To>{round_i<To>(tp.time_since_epoch())};
}
} // detail
// trunc towards zero // trunc towards zero
template <class To, class Clock, class FromDuration> template <class To, class Clock, class FromDuration>
CONSTCD11 CONSTCD11
@ -6315,6 +6356,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
using std::chrono::seconds; using std::chrono::seconds;
using std::chrono::minutes; using std::chrono::minutes;
using std::chrono::hours; using std::chrono::hours;
using detail::round_i;
typename std::basic_istream<CharT, Traits>::sentry ok{is, true}; typename std::basic_istream<CharT, Traits>::sentry ok{is, true};
if (ok) if (ok)
{ {
@ -6528,7 +6570,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
CharT{':'}, rld{S, 1, w}); CharT{':'}, rld{S, 1, w});
checked_set(H, tH, not_a_hour, is); checked_set(H, tH, not_a_hour, is);
checked_set(M, tM, not_a_minute, is); checked_set(M, tM, not_a_minute, is);
checked_set(s, round<Duration>(duration<long double>{S}), checked_set(s, round_i<Duration>(duration<long double>{S}),
not_a_second, is); not_a_second, is);
ws(is); ws(is);
int tY = not_a_year; int tY = not_a_year;
@ -6608,7 +6650,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
CharT{':'}, rld{S, 1, w}); CharT{':'}, rld{S, 1, w});
checked_set(H, tH, not_a_hour, is); checked_set(H, tH, not_a_hour, is);
checked_set(M, tM, not_a_minute, is); checked_set(M, tM, not_a_minute, is);
checked_set(s, round<Duration>(duration<long double>{S}), checked_set(s, round_i<Duration>(duration<long double>{S}),
not_a_second, is); not_a_second, is);
#endif #endif
} }
@ -6965,7 +7007,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
CharT{':'}, rld{S, 1, w}); CharT{':'}, rld{S, 1, w});
checked_set(I, tI, not_a_hour_12_value, is); checked_set(I, tI, not_a_hour_12_value, is);
checked_set(M, tM, not_a_minute, is); checked_set(M, tM, not_a_minute, is);
checked_set(s, round<Duration>(duration<long double>{S}), checked_set(s, round_i<Duration>(duration<long double>{S}),
not_a_second, is); not_a_second, is);
ws(is); ws(is);
auto nm = detail::ampm_names(); auto nm = detail::ampm_names();
@ -7016,7 +7058,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
long double S; long double S;
read(is, rld{S, 1, width == -1 ? w : static_cast<unsigned>(width)}); read(is, rld{S, 1, width == -1 ? w : static_cast<unsigned>(width)});
checked_set(s, round<Duration>(duration<long double>{S}), checked_set(s, round_i<Duration>(duration<long double>{S}),
not_a_second, is); not_a_second, is);
} }
#if !ONLY_C_LOCALE #if !ONLY_C_LOCALE
@ -7053,7 +7095,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
CharT{':'}, rld{S, 1, w}); CharT{':'}, rld{S, 1, w});
checked_set(H, tH, not_a_hour, is); checked_set(H, tH, not_a_hour, is);
checked_set(M, tM, not_a_minute, is); checked_set(M, tM, not_a_minute, is);
checked_set(s, round<Duration>(duration<long double>{S}), checked_set(s, round_i<Duration>(duration<long double>{S}),
not_a_second, is); not_a_second, is);
} }
else else
@ -7756,6 +7798,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
std::chrono::minutes* offset = nullptr) std::chrono::minutes* offset = nullptr)
{ {
using CT = typename std::common_type<Duration, std::chrono::seconds>::type; using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
using detail::round_i;
std::chrono::minutes offset_local{}; std::chrono::minutes offset_local{};
auto offptr = offset ? offset : &offset_local; auto offptr = offset ? offset : &offset_local;
fields<CT> fds{}; fields<CT> fds{};
@ -7764,7 +7807,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
is.setstate(std::ios::failbit); is.setstate(std::ios::failbit);
if (!is.fail()) if (!is.fail())
tp = round<Duration>(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); tp = round_i<Duration>(sys_days(fds.ymd) - *offptr + fds.tod.to_duration());
return is; return is;
} }
@ -7775,13 +7818,14 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
std::chrono::minutes* offset = nullptr) std::chrono::minutes* offset = nullptr)
{ {
using CT = typename std::common_type<Duration, std::chrono::seconds>::type; using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
using detail::round_i;
fields<CT> fds{}; fields<CT> fds{};
fds.has_tod = true; fds.has_tod = true;
from_stream(is, fmt, fds, abbrev, offset); from_stream(is, fmt, fds, abbrev, offset);
if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
is.setstate(std::ios::failbit); is.setstate(std::ios::failbit);
if (!is.fail()) if (!is.fail())
tp = round<Duration>(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration()); tp = round_i<Duration>(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration());
return is; return is;
} }