Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdeadlinetimer.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Intel Corporation.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qdeadlinetimer.h"
5#include "private/qnumeric_p.h"
6
8
10
11using namespace std::chrono;
12
13namespace {
14struct TimeReference : std::numeric_limits<qint64>
15{
16 static constexpr qint64 Min = min();
17 static constexpr qint64 Max = max();
18};
19}
20
21template <typename Duration1, typename... Durations>
22static qint64 add_saturate(qint64 t1, Duration1 dur, Durations... extra)
23{
24 qint64 v = dur.count();
25 qint64 saturated = std::numeric_limits<qint64>::max();
26 if (v < 0)
27 saturated = std::numeric_limits<qint64>::min();
28
29 // convert to nanoseconds with saturation
30 using Ratio = std::ratio_divide<typename Duration1::period, nanoseconds::period>;
31 static_assert(Ratio::den == 1, "sub-multiples of nanosecond are not supported");
32 if (qMulOverflow<Ratio::num>(v, &v))
33 return saturated;
34
35 qint64 r;
36 if (qAddOverflow(t1, v, &r))
37 return saturated;
38 if constexpr (sizeof...(Durations)) {
39 // chain more additions
40 return add_saturate(r, extra...);
41 }
42 return r;
43}
44
186{
187 setRemainingTime(msecs, type);
188}
189
267{
268 if (msecs < 0) {
269 *this = QDeadlineTimer(Forever, timerType);
270 } else if (msecs == 0) {
271 *this = QDeadlineTimer(timerType);
272 t1 = std::numeric_limits<qint64>::min();
273 } else {
274 *this = current(timerType);
275 milliseconds ms(msecs);
276 t1 = add_saturate(t1, ms);
277 }
278}
279
303{
304 if (secs < 0) {
305 *this = QDeadlineTimer(Forever, timerType);
306 } else if (secs == 0 && nsecs == 0) {
307 *this = QDeadlineTimer(timerType);
308 t1 = std::numeric_limits<qint64>::min();
309 } else {
310 *this = current(timerType);
311 t1 = add_saturate(t1, seconds{secs}, nanoseconds{nsecs});
312 }
313}
314
358bool QDeadlineTimer::hasExpired() const noexcept
359{
360 if (isForever())
361 return false;
362 if (t1 == std::numeric_limits<qint64>::min())
363 return true;
364 return *this <= current(timerType());
365}
366
387{
388 type = timerType;
389}
390
408{
409 if (isForever())
410 return -1;
411
412 nanoseconds nsecs(remainingTimeNSecs());
413 return ceil<milliseconds>(nsecs).count();
414}
415
425{
426 if (isForever())
427 return -1;
428 qint64 raw = rawRemainingTimeNSecs();
429 return raw < 0 ? 0 : raw;
430}
431
438qint64 QDeadlineTimer::rawRemainingTimeNSecs() const noexcept
439{
440 if (t1 == std::numeric_limits<qint64>::min())
441 return t1; // we'd saturate to this anyway
442
444 qint64 r;
445 if (qSubOverflow(t1, now.t1, &r))
446 return -1; // any negative number is fine
447 return r;
448}
449
471{
472 if (isForever())
473 return TimeReference::Max;
474 if (t1 == TimeReference::Min)
475 return t1;
476
477 nanoseconds ns(t1);
478 return duration_cast<milliseconds>(ns).count();
479}
480
503{
504 if (isForever())
505 return TimeReference::Max;
506
507 return t1;
508}
509
523void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) noexcept
524{
525 if (msecs == TimeReference::Max) {
526 *this = QDeadlineTimer(Forever, timerType);
527 return;
528 }
529
530 type = timerType;
531 t1 = add_saturate(0, milliseconds{msecs});
532}
533
547{
548 type = timerType;
549 t1 = add_saturate(0, seconds{secs}, nanoseconds{nsecs});
550}
551
561{
562 if (dt.isForever())
563 return dt;
564
565 dt.t1 = add_saturate(dt.t1, nanoseconds{nsecs});
566 return dt;
567}
568
579{
580 // ensure we get nanoseconds; this will work so long as steady_clock's
581 // time_point isn't of finer resolution (picoseconds)
582 std::chrono::nanoseconds ns = std::chrono::steady_clock::now().time_since_epoch();
583
585 result.t1 = ns.count();
586 result.type = timerType;
587 return result;
588}
589
679{
680 if (dt.isForever())
681 return dt;
682
683 dt.t1 = add_saturate(dt.t1, milliseconds{msecs});
684 return dt;
685}
686
\inmodule QtCore
static QDeadlineTimer current(Qt::TimerType timerType=Qt::CoarseTimer) noexcept
Returns a QDeadlineTimer that is expired but is guaranteed to contain the current time.
void setDeadline(qint64 msecs, Qt::TimerType timerType=Qt::CoarseTimer) noexcept
Sets the deadline for this QDeadlineTimer object to be the msecs absolute time point,...
void setRemainingTime(qint64 msecs, Qt::TimerType type=Qt::CoarseTimer) noexcept
Sets the remaining time for this QDeadlineTimer object to msecs milliseconds from now,...
static QDeadlineTimer addNSecs(QDeadlineTimer dt, qint64 nsecs) noexcept Q_DECL_PURE_FUNCTION
Returns a QDeadlineTimer object whose deadline is extended from dt's deadline by nsecs nanoseconds.
void setPreciseRemainingTime(qint64 secs, qint64 nsecs=0, Qt::TimerType type=Qt::CoarseTimer) noexcept
Sets the remaining time for this QDeadlineTimer object to secs seconds plus nsecs nanoseconds from no...
void setTimerType(Qt::TimerType type)
Changes the timer type for this object to timerType.
qint64 deadline() const noexcept Q_DECL_PURE_FUNCTION
Returns the absolute time point for the deadline stored in QDeadlineTimer object, calculated in milli...
bool hasExpired() const noexcept
Returns true if this QDeadlineTimer object has expired, false if there remains time left.
constexpr bool isForever() const noexcept
Returns true if this QDeadlineTimer object never expires, false otherwise.
qint64 remainingTimeNSecs() const noexcept
Returns the remaining time in this QDeadlineTimer object in nanoseconds.
qint64 remainingTime() const noexcept
Returns the remaining time in this QDeadlineTimer object in milliseconds.
Qt::TimerType timerType() const noexcept
Returns the timer type is active for this object.
qint64 deadlineNSecs() const noexcept Q_DECL_PURE_FUNCTION
Returns the absolute time point for the deadline stored in QDeadlineTimer object, calculated in nanos...
void setPreciseDeadline(qint64 secs, qint64 nsecs=0, Qt::TimerType type=Qt::CoarseTimer) noexcept
Sets the deadline for this QDeadlineTimer object to be secs seconds and nsecs nanoseconds since the r...
constexpr QDeadlineTimer(Qt::TimerType type_=Qt::CoarseTimer) noexcept
Constructs an expired QDeadlineTimer object.
Combined button and popup list for selecting options.
constexpr const T & min(const T &a, const T &b)
Definition qnumeric.h:366
TimerType
QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs)
static qint64 add_saturate(qint64 t1, Duration1 dur, Durations... extra)
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition qmetatype.h:1369
std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
Definition qnumeric.h:113
std::enable_if_t< std::is_unsigned_v< T >, bool > qSubOverflow(T v1, T v2, T *r)
Definition qnumeric.h:153
GLsizei const GLfloat * v
[13]
GLboolean r
[2]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
GLenum type
GLuint64EXT * result
[6]
long long qint64
Definition qtypes.h:55
deadline setRemainingTime(250ms)