From 97eae54083d5a0a29b9ea6f0d3c3c02802986958 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 11 May 2016 23:14:46 -0700 Subject: QDateTimePrivate refactor: static'fy access to d->m_status This commit changes most accesses to the d->m_status (including d->spec() and d->setSpec() uses) to use new static functions. This is done in preparation to the "Short QDateTime Optimization" as the status byte will be kept in the short data. Change-Id: I06bae9392f534e45b3f1ffff144dbd795d03227a Reviewed-by: Edward Welbourne Reviewed-by: Lars Knoll --- src/corelib/tools/qdatetime.cpp | 183 ++++++++++++++++++++++++---------------- src/corelib/tools/qdatetime_p.h | 15 ---- 2 files changed, 109 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 4beb5d8d1e..7030520612 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2480,6 +2480,52 @@ static qint64 localMSecsToEpochMSecs(qint64 localMsecs, } } +static Q_DECL_CONSTEXPR inline +QDateTimePrivate::StatusFlags mergeSpec(QDateTimePrivate::StatusFlags status, Qt::TimeSpec spec) +{ + return QDateTimePrivate::StatusFlags((status & ~QDateTimePrivate::TimeSpecMask) | + (int(spec) << QDateTimePrivate::TimeSpecShift)); +} + +static Q_DECL_CONSTEXPR inline Qt::TimeSpec extractSpec(QDateTimePrivate::StatusFlags status) +{ + return Qt::TimeSpec((status & QDateTimePrivate::TimeSpecMask) >> QDateTimePrivate::TimeSpecShift); +} + +// Set the Daylight Status if LocalTime set via msecs +static Q_DECL_RELAXED_CONSTEXPR inline QDateTimePrivate::StatusFlags +mergeDaylightStatus(QDateTimePrivate::StatusFlags sf, QDateTimePrivate::DaylightStatus status) +{ + sf &= ~QDateTimePrivate::DaylightMask; + if (status == QDateTimePrivate::DaylightTime) { + sf |= QDateTimePrivate::SetToDaylightTime; + } else if (status == QDateTimePrivate::StandardTime) { + sf |= QDateTimePrivate::SetToStandardTime; + } + return sf; +} + +// Get the DST Status if LocalTime set via msecs +static Q_DECL_RELAXED_CONSTEXPR inline +QDateTimePrivate::DaylightStatus extractDaylightStatus(QDateTimePrivate::StatusFlags status) +{ + if (status & QDateTimePrivate::SetToDaylightTime) + return QDateTimePrivate::DaylightTime; + if (status & QDateTimePrivate::SetToStandardTime) + return QDateTimePrivate::StandardTime; + return QDateTimePrivate::UnknownDaylightTime; +} + +static inline QDateTimePrivate::StatusFlags getStatus(const QDateTimePrivate *d) +{ + return d->m_status; +} + +static inline Qt::TimeSpec getSpec(const QDateTimePrivate *d) +{ + return extractSpec(getStatus(d)); +} + /***************************************************************************** QDateTimePrivate member functions *****************************************************************************/ @@ -2498,20 +2544,19 @@ QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt: #ifndef QT_BOOTSTRAPPED QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, const QTimeZone &toTimeZone) - : m_status(0), + : m_status(mergeSpec(0, Qt::TimeZone)), m_offsetFromUtc(0), ref(0), m_timeZone(toTimeZone) { - setSpec(Qt::TimeZone); setDateTime(toDate, toTime); } #endif // QT_BOOTSTRAPPED void QDateTimePrivate::setTimeSpec(Qt::TimeSpec spec, int offsetSeconds) { - clearValidDateTime(); - clearSetToDaylightStatus(); + auto status = m_status; + status &= ~(ValidDateTime | DaylightMask | TimeSpecMask); switch (spec) { case Qt::OffsetFromUTC: @@ -2528,7 +2573,8 @@ void QDateTimePrivate::setTimeSpec(Qt::TimeSpec spec, int offsetSeconds) break; } - setSpec(spec); + status = mergeSpec(status, spec); + m_status = status; m_offsetFromUtc = offsetSeconds; #ifndef QT_BOOTSTRAPPED m_timeZone = QTimeZone(); @@ -2570,49 +2616,33 @@ void QDateTimePrivate::setDateTime(const QDate &date, const QTime &time) QPair QDateTimePrivate::getDateTime() const { QPair result; - msecsToTime(m_msecs, &result.first, &result.second); + qint64 msecs = m_msecs; + auto status = m_status; + msecsToTime(msecs, &result.first, &result.second); - if (!isValidDate()) + if (!status.testFlag(ValidDate)) result.first = QDate(); - if (!isValidTime()) + if (!status.testFlag(ValidTime)) result.second = QTime(); return result; } -// Set the Daylight Status if LocalTime set via msecs -void QDateTimePrivate::setDaylightStatus(QDateTimePrivate::DaylightStatus status) -{ - clearSetToDaylightStatus(); - if (status == DaylightTime) { - m_status = m_status | SetToDaylightTime; - } else if (status == StandardTime) { - m_status = m_status | SetToStandardTime; - } -} - -// Get the DST Status if LocalTime set via msecs -QDateTimePrivate::DaylightStatus QDateTimePrivate::daylightStatus() const -{ - if ((m_status & SetToDaylightTime) == SetToDaylightTime) - return DaylightTime; - if ((m_status & SetToStandardTime) == SetToStandardTime) - return StandardTime; - return UnknownDaylightTime; -} - // Check the UTC / offsetFromUTC validity void QDateTimePrivate::checkValidDateTime() { - switch (spec()) { + auto status = m_status; + auto spec = extractSpec(status); + switch (spec) { case Qt::OffsetFromUTC: case Qt::UTC: // for these, a valid date and a valid time imply a valid QDateTime - if (isValidDate() && isValidTime()) - setValidDateTime(); + if ((status & ValidDate) && (status & ValidTime)) + status |= ValidDateTime; else - clearValidDateTime(); + status &= ~ValidDateTime; + m_status = status; break; case Qt::TimeZone: case Qt::LocalTime: @@ -2627,15 +2657,16 @@ void QDateTimePrivate::checkValidDateTime() void QDateTimePrivate::refreshDateTime() { auto status = m_status; + const auto spec = extractSpec(status); qint64 epochMSecs = 0; int offsetFromUtc = 0; QDate testDate; QTime testTime; - Q_ASSERT(spec() == Qt::TimeZone || spec() == Qt::LocalTime); + Q_ASSERT(spec == Qt::TimeZone || spec == Qt::LocalTime); #ifndef QT_BOOTSTRAPPED // If not valid time zone then is invalid - if (spec() == Qt::TimeZone) { + if (spec == Qt::TimeZone) { if (!m_timeZone.isValid()) status &= ~ValidDateTime; else @@ -2644,7 +2675,7 @@ void QDateTimePrivate::refreshDateTime() #endif // QT_BOOTSTRAPPED // If not valid date and time then is invalid - if (!(status & ValidDate) && !(status & ValidTime)) { + if (!(status & ValidDate) || !(status & ValidTime)) { status &= ~ValidDateTime; m_status = status; m_offsetFromUtc = 0; @@ -2654,9 +2685,9 @@ void QDateTimePrivate::refreshDateTime() // We have a valid date and time and a Qt::LocalTime or Qt::TimeZone that needs calculating // LocalTime and TimeZone might fall into a "missing" DST transition hour // Calling toEpochMSecs will adjust the returned date/time if it does - if (spec() == Qt::LocalTime) { - DaylightStatus status = daylightStatus(); - epochMSecs = localMSecsToEpochMSecs(m_msecs, &status, &testDate, &testTime); + if (spec == Qt::LocalTime) { + auto dstStatus = extractDaylightStatus(status); + epochMSecs = localMSecsToEpochMSecs(m_msecs, &dstStatus, &testDate, &testTime); } if (timeToMSecs(testDate, testTime) == m_msecs) { status |= ValidDateTime; @@ -2944,7 +2975,9 @@ QDateTime &QDateTime::operator=(const QDateTime &other) bool QDateTime::isNull() const { - return !d->isValidDate() && !d->isValidTime(); + auto status = getStatus(d); + return !status.testFlag(QDateTimePrivate::ValidDate) && + !status.testFlag(QDateTimePrivate::ValidTime); } /*! @@ -2961,7 +2994,8 @@ bool QDateTime::isNull() const bool QDateTime::isValid() const { - return (d->isValidDateTime()); + auto status = getStatus(d); + return status & QDateTimePrivate::ValidDateTime; } /*! @@ -2972,7 +3006,8 @@ bool QDateTime::isValid() const QDate QDateTime::date() const { - if (!d->isValidDate()) + auto status = getStatus(d); + if (!status.testFlag(QDateTimePrivate::ValidDate)) return QDate(); QDate dt; msecsToTime(d->m_msecs, &dt, 0); @@ -2987,7 +3022,8 @@ QDate QDateTime::date() const QTime QDateTime::time() const { - if (!d->isValidTime()) + auto status = getStatus(d); + if (!status.testFlag(QDateTimePrivate::ValidTime)) return QTime(); QTime tm; msecsToTime(d->m_msecs, 0, &tm); @@ -3002,7 +3038,7 @@ QTime QDateTime::time() const Qt::TimeSpec QDateTime::timeSpec() const { - return d->spec(); + return getSpec(d); } #ifndef QT_BOOTSTRAPPED @@ -3020,7 +3056,7 @@ Qt::TimeSpec QDateTime::timeSpec() const QTimeZone QDateTime::timeZone() const { - switch (d->spec()) { + switch (getSpec(d)) { case Qt::UTC: return QTimeZone::utc(); case Qt::OffsetFromUTC: @@ -3081,7 +3117,7 @@ int QDateTime::offsetFromUtc() const QString QDateTime::timeZoneAbbreviation() const { - switch (d->spec()) { + switch (getSpec(d)) { case Qt::UTC: return QTimeZonePrivate::utcQString(); case Qt::OffsetFromUTC: @@ -3094,7 +3130,7 @@ QString QDateTime::timeZoneAbbreviation() const #endif // QT_BOOTSTRAPPED case Qt::LocalTime: { QString abbrev; - QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + auto status = extractDaylightStatus(getStatus(d)); localMSecsToEpochMSecs(d->m_msecs, &status, 0, 0, &abbrev); return abbrev; } @@ -3115,7 +3151,7 @@ QString QDateTime::timeZoneAbbreviation() const bool QDateTime::isDaylightTime() const { - switch (d->spec()) { + switch (getSpec(d)) { case Qt::UTC: case Qt::OffsetFromUTC: return false; @@ -3126,7 +3162,7 @@ bool QDateTime::isDaylightTime() const return d->m_timeZone.d->isDaylightTime(toMSecsSinceEpoch()); #endif // QT_BOOTSTRAPPED case Qt::LocalTime: { - QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + auto status = extractDaylightStatus(getStatus(d)); if (status == QDateTimePrivate::UnknownDaylightTime) localMSecsToEpochMSecs(d->m_msecs, &status); return (status == QDateTimePrivate::DaylightTime); @@ -3225,7 +3261,7 @@ void QDateTime::setOffsetFromUtc(int offsetSeconds) void QDateTime::setTimeZone(const QTimeZone &toZone) { QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) - d->setSpec(Qt::TimeZone); + d->m_status = mergeSpec(d->m_status, Qt::TimeZone); d->m_offsetFromUtc = 0; d->m_timeZone = toZone; d->refreshDateTime(); @@ -3249,14 +3285,14 @@ void QDateTime::setTimeZone(const QTimeZone &toZone) */ qint64 QDateTime::toMSecsSinceEpoch() const { - switch (d->spec()) { - case Qt::OffsetFromUTC: + switch (getSpec(d)) { case Qt::UTC: - return (d->m_msecs - (d->m_offsetFromUtc * 1000)); + case Qt::OffsetFromUTC: + return d->m_msecs - (d->m_offsetFromUtc * 1000); case Qt::LocalTime: { // recalculate the local timezone - auto status = d->daylightStatus(); + auto status = extractDaylightStatus(getStatus(d)); return localMSecsToEpochMSecs(d->m_msecs, &status); } @@ -3320,8 +3356,8 @@ uint QDateTime::toTime_t() const void QDateTime::setMSecsSinceEpoch(qint64 msecs) { QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) - const auto spec = d->spec(); - auto status = d->m_status; + const auto spec = getSpec(d); + auto status = getStatus(d); status &= ~QDateTimePrivate::ValidityMask; switch (spec) { @@ -3359,9 +3395,8 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) QDateTimePrivate::DaylightStatus dstStatus; epochMSecsToLocalTime(msecs, &dt, &tm, &dstStatus); d->setDateTime(dt, tm); - d->setDaylightStatus(dstStatus); msecs = d->m_msecs; - status = d->m_status; + status = mergeDaylightStatus(getStatus(d), dstStatus); break; } } @@ -3474,7 +3509,7 @@ QString QDateTime::toString(Qt::DateFormat format) const .arg(dt.year()); if (timeSpec() != Qt::LocalTime) { buf += QStringLiteral(" GMT"); - if (d->spec() == Qt::OffsetFromUTC) + if (getSpec(d) == Qt::OffsetFromUTC) buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc); } return buf; @@ -3489,7 +3524,7 @@ QString QDateTime::toString(Qt::DateFormat format) const return QString(); // failed to convert buf += QLatin1Char('T'); buf += tm.toString(Qt::ISODate); - switch (d->spec()) { + switch (getSpec(d)) { case Qt::UTC: buf += QLatin1Char('Z'); break; @@ -3593,11 +3628,11 @@ static inline void massageAdjustedDateTime(const QDateTimePrivate *d, QDate *dat to its DST-ness); but for a time in spring's missing hour it'll adjust the time while picking a DST-ness. (Handling of autumn is trickier, as either DST-ness is valid, without adjusting the time. We might want to propagate - d->daylightStatus() in that case, but it's hard to do so without breaking + the daylight status in that case, but it's hard to do so without breaking (far more common) other cases; and it makes little difference, as the two answers do then differ only in DST-ness.) */ - auto spec = d->spec(); + auto spec = getSpec(d); if (spec == Qt::LocalTime) { QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime; localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time); @@ -3716,7 +3751,8 @@ QDateTime QDateTime::addMSecs(qint64 msecs) const return QDateTime(); QDateTime dt(*this); - if (d->spec() == Qt::LocalTime || d->spec() == Qt::TimeZone) + auto spec = getSpec(d); + if (spec == Qt::LocalTime || spec == Qt::TimeZone) // Convert to real UTC first in case crosses DST transition dt.setMSecsSinceEpoch(toMSecsSinceEpoch() + msecs); else @@ -3810,7 +3846,7 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const { - if (d->spec() == spec && (spec == Qt::UTC || spec == Qt::LocalTime)) + if (getSpec(d) == spec && (spec == Qt::UTC || spec == Qt::LocalTime)) return *this; if (!isValid()) { @@ -3837,7 +3873,8 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const { - if (d->spec() == Qt::OffsetFromUTC && d->m_offsetFromUtc == offsetSeconds) + if (getSpec(d) == Qt::OffsetFromUTC + && d->m_offsetFromUtc == offsetSeconds) return *this; if (!isValid()) { @@ -3860,7 +3897,7 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const { - if (d->spec() == Qt::TimeZone && d->m_timeZone == timeZone) + if (getSpec(d) == Qt::TimeZone && d->m_timeZone == timeZone) return *this; if (!isValid()) { @@ -3882,10 +3919,9 @@ QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const bool QDateTime::operator==(const QDateTime &other) const { - if (d->spec() == Qt::LocalTime - && other.d->spec() == Qt::LocalTime - && d->m_status == other.d->m_status) { - return (d->m_msecs == other.d->m_msecs); + if (getSpec(d) == Qt::LocalTime + && getStatus(d) == getStatus(other.d)) { + return d->m_msecs == other.d->m_msecs; } // Convert to UTC and compare return (toMSecsSinceEpoch() == other.toMSecsSinceEpoch()); @@ -3910,10 +3946,9 @@ bool QDateTime::operator==(const QDateTime &other) const bool QDateTime::operator<(const QDateTime &other) const { - if (d->spec() == Qt::LocalTime - && other.d->spec() == Qt::LocalTime - && d->m_status == other.d->m_status) { - return (d->m_msecs < other.d->m_msecs); + if (getSpec(d) == Qt::LocalTime + && getStatus(d) == getStatus(other.d)) { + return d->m_msecs < other.d->m_msecs; } // Convert to UTC and compare return (toMSecsSinceEpoch() < other.toMSecsSinceEpoch()); diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h index 3c6c2111af..1b7bfc4ad1 100644 --- a/src/corelib/tools/qdatetime_p.h +++ b/src/corelib/tools/qdatetime_p.h @@ -129,24 +129,9 @@ public: void setDateTime(const QDate &date, const QTime &time); QPair getDateTime() const; - void setDaylightStatus(DaylightStatus status); - DaylightStatus daylightStatus() const; - void checkValidDateTime(); void refreshDateTime(); - // Get/set date and time status - inline bool isValidDate() const { return m_status & ValidDate; } - inline bool isValidTime() const { return m_status & ValidTime; } - inline bool isValidDateTime() const { return m_status & ValidDateTime; } - inline void setValidDateTime() { m_status |= ValidDateTime; } - inline void clearValidDateTime() { m_status &= ~ValidDateTime; } - inline void clearSetToDaylightStatus() { m_status &= ~(SetToStandardTime | SetToDaylightTime); } - - inline Qt::TimeSpec spec() const { return Qt::TimeSpec((m_status & TimeSpecMask) >> TimeSpecShift); } - inline void setSpec(Qt::TimeSpec spec) - { m_status &= ~TimeSpecMask; m_status |= StatusFlag(uint(spec) << TimeSpecShift); } - #ifndef QT_BOOTSTRAPPED static qint64 zoneMSecsToEpochMSecs(qint64 msecs, const QTimeZone &zone, QDate *localDate = 0, QTime *localTime = 0); -- cgit v1.2.3