QDeadlineTimer: use if constexpr instead of function specializations

You can't partially specialize a template function, so these
specializations for steady_clock only worked if the Duration parameter
was nanoseconds. This could have been solved with function overloads
instead, but I find the if constexpr code simpler to read.

Pick-to: 6.5
Change-Id: Ieec322d73c1e40ad95c8fffd17468bd73fc2fe24
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
bb10
Thiago Macieira 2023-02-23 12:07:29 -08:00
parent b498e1ae3a
commit 7ba76731ef
2 changed files with 26 additions and 17 deletions

View File

@ -91,16 +91,11 @@ public:
{ setDeadline(deadline_); return *this; }
template <class Clock, class Duration = typename Clock::duration>
void setDeadline(std::chrono::time_point<Clock, Duration> deadline_,
Qt::TimerType type_ = Qt::CoarseTimer)
{ setRemainingTime(deadline_ == deadline_.max() ? Duration::max() : deadline_ - Clock::now(), type_); }
void setDeadline(std::chrono::time_point<Clock, Duration> tp,
Qt::TimerType type_ = Qt::CoarseTimer);
template <class Clock, class Duration = typename Clock::duration>
std::chrono::time_point<Clock, Duration> deadline() const
{
auto val = std::chrono::nanoseconds(rawRemainingTimeNSecs()) + Clock::now();
return std::chrono::time_point_cast<Duration>(val);
}
std::chrono::time_point<Clock, Duration> deadline() const;
template <class Rep, class Period>
QDeadlineTimer(std::chrono::duration<Rep, Period> remaining, Qt::TimerType type_ = Qt::CoarseTimer)
@ -148,26 +143,32 @@ private:
qint64 rawRemainingTimeNSecs() const noexcept;
};
template <> inline std::chrono::steady_clock::time_point
QDeadlineTimer::deadline<std::chrono::steady_clock, std::chrono::steady_clock::duration>() const
template<class Clock, class Duration>
std::chrono::time_point<Clock, Duration> QDeadlineTimer::deadline() const
{
return std::chrono::steady_clock::time_point(std::chrono::nanoseconds(deadlineNSecs()));
using namespace std::chrono;
if constexpr (std::is_same_v<Clock, steady_clock>) {
auto val = duration_cast<Duration>(nanoseconds(deadlineNSecs()));
return time_point<Clock, Duration>(val);
} else {
auto val = nanoseconds(rawRemainingTimeNSecs()) + Clock::now();
return time_point_cast<Duration>(val);
}
}
template <> inline void
QDeadlineTimer::setDeadline<std::chrono::steady_clock, std::chrono::steady_clock::duration>(std::chrono::steady_clock::time_point tp, Qt::TimerType type_)
template<class Clock, class Duration>
void QDeadlineTimer::setDeadline(std::chrono::time_point<Clock, Duration> tp, Qt::TimerType type_)
{
using namespace std::chrono;
if (tp == tp.max()) {
*this = Forever;
type = type_;
} else if (type_ != Qt::PreciseTimer) {
// if we aren't using PreciseTimer, then we need to convert
setPreciseRemainingTime(0, duration_cast<nanoseconds>(tp - steady_clock::now()).count(), type_);
} else {
} else if constexpr (std::is_same_v<Clock, steady_clock>) {
setPreciseDeadline(0,
duration_cast<nanoseconds>(tp.time_since_epoch()).count(),
type_);
} else {
setPreciseRemainingTime(0, duration_cast<nanoseconds>(tp - Clock::now()).count(), type_);
}
}

View File

@ -679,6 +679,14 @@ void tst_QDeadlineTimer::stdchrono()
QCOMPARE_LT(deadline.deadline<steady_clock>(), (steady_clock::now() + 5ms * minResolution));
QCOMPARE_GT(deadline.deadline<system_clock>(), (system_clock::now() + 3ms * minResolution));
QCOMPARE_LT(deadline.deadline<system_clock>(), (system_clock::now() + 5ms * minResolution));
QCOMPARE_GT((deadline.deadline<steady_clock, milliseconds>()),
steady_clock::now() + 3ms * minResolution);
QCOMPARE_LT((deadline.deadline<steady_clock, milliseconds>()),
steady_clock::now() + 5ms * minResolution);
QCOMPARE_GT((deadline.deadline<system_clock, milliseconds>()),
system_clock::now() + 3ms * minResolution);
QCOMPARE_LT((deadline.deadline<system_clock, milliseconds>()),
system_clock::now() + 5ms * minResolution);
if (timerType == Qt::CoarseTimer) {
QCOMPARE_GT(deadline, now + 3ms * minResolution);
QCOMPARE_LT(deadline, now + 5ms * minResolution);