diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-08-31 01:01:42 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-08-31 01:01:53 +0200 |
commit | d795272af5434bdcc794e80e077323a0d1140ab2 (patch) | |
tree | 5888fed53d5b747e122ade9517ce750ffba23eca /src/corelib | |
parent | a5ba29b79d4793a3c18aaf64f24582d93c0fe4e8 (diff) | |
parent | a2a4c3a5ff50dc68f6931917c8f017f9b4d69b6b (diff) |
Merge "Merge remote-tracking branch 'origin/5.14' into dev"
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qfileinfo.cpp | 93 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.h | 19 | ||||
-rw-r--r-- | src/corelib/text/qlocale_win.cpp | 8 | ||||
-rw-r--r-- | src/corelib/time/qcalendar.cpp | 2 | ||||
-rw-r--r-- | src/corelib/time/qdatetime.cpp | 107 | ||||
-rw-r--r-- | src/corelib/time/qdatetime.h | 16 | ||||
-rw-r--r-- | src/corelib/time/qdatetimeparser.cpp | 9 | ||||
-rw-r--r-- | src/corelib/time/qgregoriancalendar.cpp | 39 | ||||
-rw-r--r-- | src/corelib/time/qgregoriancalendar_p.h | 8 |
9 files changed, 187 insertions, 114 deletions
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index b720966d8f..a6f8b45ea3 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -311,19 +311,6 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) */ /*! - \enum QFileInfo::FileType - - This enum is returned by type() to describe the type of the file system - entity described by the QFileInfo object. - - \value Unknown The object refers to an unknown item. - \value Regular The object refers to a regular file. - \value Directory The object refers to a directory. - \value SymbolicLink The object refers to a symbolic link. - \value Shortcut The object refers to a shortcut. -*/ - -/*! \fn QFileInfo &QFileInfo::operator=(QFileInfo &&other) Move-assigns \a other to this QFileInfo instance. @@ -1008,7 +995,11 @@ bool QFileInfo::isNativePath() const */ bool QFileInfo::isFile() const { - return (type() & FileTypeMask) == Regular; + Q_D(const QFileInfo); + return d->checkAttribute<bool>( + QFileSystemMetaData::FileType, + [d]() { return d->metaData.isFile(); }, + [d]() { return d->getFileFlags(QAbstractFileEngine::FileType); }); } /*! @@ -1019,7 +1010,11 @@ bool QFileInfo::isFile() const */ bool QFileInfo::isDir() const { - return (type() & FileTypeMask) == Directory; + Q_D(const QFileInfo); + return d->checkAttribute<bool>( + QFileSystemMetaData::DirectoryType, + [d]() { return d->metaData.isDirectory(); }, + [d]() { return d->getFileFlags(QAbstractFileEngine::DirectoryType); }); } @@ -1070,8 +1065,6 @@ bool QFileInfo::isSymLink() const } /*! - \fn bool QFileInfo::isSymbolicLink() const - Returns \c true if this object points to a symbolic link; otherwise returns \c false. @@ -1091,9 +1084,16 @@ bool QFileInfo::isSymLink() const \sa isFile(), isDir(), isShortcut(), symLinkTarget() */ -/*! - \fn bool QFileInfo::isShortcut() const +bool QFileInfo::isSymbolicLink() const +{ + Q_D(const QFileInfo); + return d->checkAttribute<bool>( + QFileSystemMetaData::LegacyLinkType, + [d]() { return d->metaData.isLink(); }, + [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); }); +} +/*! Returns \c true if this object points to a shortcut; otherwise returns \c false. @@ -1110,6 +1110,14 @@ bool QFileInfo::isSymLink() const \sa isFile(), isDir(), isSymbolicLink(), symLinkTarget() */ +bool QFileInfo::isShortcut() const +{ + Q_D(const QFileInfo); + return d->checkAttribute<bool>( + QFileSystemMetaData::LegacyLinkType, + [d]() { return d->metaData.isLnkFile(); }, + [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); }); +} /*! Returns \c true if the object points to a directory or to a symbolic @@ -1314,53 +1322,6 @@ qint64 QFileInfo::size() const }); } -/*! - Returns the QFileInfo::FileTypes. - - QFileInfo::FileTypes combines with an indirection flag (link type) and a - base type it refers to. - - For example, \c SymbolicLink combines with \c Regular meaning a symlink to - a regular file. - - In addition, FileTypeMask and LinkTypeMask are used to extract the base - type and link type respectively. - - \sa isFile(), isDir(), isShortcut(), isSymbolicLink() -*/ -QFileInfo::FileTypes QFileInfo::type() const -{ - Q_D(const QFileInfo); - - QFileInfo::FileTypes type = QFileInfo::Unknown; - if (d->checkAttribute<bool>( - QFileSystemMetaData::LegacyLinkType, - [d]() { return d->metaData.isLnkFile(); }, - [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); })) { - type = QFileInfo::Shortcut; - } else if (d->checkAttribute<bool>( - QFileSystemMetaData::LegacyLinkType, - [d]() { return d->metaData.isLink(); }, - [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); })) { - type = QFileInfo::SymbolicLink; - } - - if (d->checkAttribute<bool>( - QFileSystemMetaData::DirectoryType, - [d]() { return d->metaData.isDirectory(); }, - [d]() { return d->getFileFlags(QAbstractFileEngine::DirectoryType); })) { - return type | QFileInfo::Directory; - } - - if (d->checkAttribute<bool>( - QFileSystemMetaData::FileType, - [d]() { return d->metaData.isFile(); }, - [d]() { return d->getFileFlags(QAbstractFileEngine::FileType); })) { - return type | QFileInfo::Regular; - } - return type; -} - #if QT_DEPRECATED_SINCE(5, 10) /*! \deprecated diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 1cbeafdd4a..3ac028085a 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -66,20 +66,6 @@ public: QFileInfo(const QFileInfo &fileinfo); ~QFileInfo(); - enum FileType { - Unknown, - // base type - Regular, - Directory, - // indirection flag - SymbolicLink = 0x10, - Shortcut = 0x20, - // mask - FileTypeMask = 0x0f, - LinkTypeMask = 0xf0 - }; - Q_DECLARE_FLAGS(FileTypes, FileType) - QFileInfo &operator=(const QFileInfo &fileinfo); QFileInfo &operator=(QFileInfo &&other) noexcept { swap(other); return *this; } @@ -125,8 +111,8 @@ public: bool isFile() const; bool isDir() const; bool isSymLink() const; - inline bool isSymbolicLink() const { return type() & SymbolicLink; } - inline bool isShortcut() const { return type() & Shortcut; } + bool isSymbolicLink() const; + bool isShortcut() const; bool isRoot() const; bool isBundle() const; @@ -145,7 +131,6 @@ public: QFile::Permissions permissions() const; qint64 size() const; - FileTypes type() const; // ### Qt6: inline these functions #if QT_DEPRECATED_SINCE(5, 10) diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index dc904ad02d..79ea67f966 100644 --- a/src/corelib/text/qlocale_win.cpp +++ b/src/corelib/text/qlocale_win.cpp @@ -116,8 +116,8 @@ struct QSystemLocalePrivate QVariant dateTimeFormat(QLocale::FormatType); QVariant dayName(int, QLocale::FormatType); QVariant monthName(int, QLocale::FormatType); - QVariant toString(const QDate &, QLocale::FormatType); - QVariant toString(const QTime &, QLocale::FormatType); + QVariant toString(QDate, QLocale::FormatType); + QVariant toString(QTime, QLocale::FormatType); QVariant toString(const QDateTime &, QLocale::FormatType); QVariant measurementSystem(); QVariant collation(); @@ -394,7 +394,7 @@ QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type) return getLocaleInfo(lctype); } -QVariant QSystemLocalePrivate::toString(const QDate &date, QLocale::FormatType type) +QVariant QSystemLocalePrivate::toString(QDate date, QLocale::FormatType type) { SYSTEMTIME st; memset(&st, 0, sizeof(SYSTEMTIME)); @@ -413,7 +413,7 @@ QVariant QSystemLocalePrivate::toString(const QDate &date, QLocale::FormatType t return QString(); } -QVariant QSystemLocalePrivate::toString(const QTime &time, QLocale::FormatType type) +QVariant QSystemLocalePrivate::toString(QTime time, QLocale::FormatType type) { SYSTEMTIME st; memset(&st, 0, sizeof(SYSTEMTIME)); diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp index f6bb242788..b569a6834c 100644 --- a/src/corelib/time/qcalendar.cpp +++ b/src/corelib/time/qcalendar.cpp @@ -810,7 +810,7 @@ bool QCalendar::isLuniSolar() const /*! Returns \c true if this calendar is solar. - A solar calendar is based primaril on the Sun's varying position in the sky, + A solar calendar is based primarily on the Sun's varying position in the sky, relative to the fixed stars. */ bool QCalendar::isSolar() const diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 020eac6dec..a9fc47e053 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -74,6 +74,7 @@ #endif #include "qcalendar.h" +#include "qgregoriancalendar_p.h" QT_BEGIN_NAMESPACE @@ -105,6 +106,17 @@ static inline QDate fixedDate(QCalendar::YearMonthDay &&parts, QCalendar cal) return cal.dateFromParts(parts); } +static inline QDate fixedDate(QCalendar::YearMonthDay &&parts) +{ + if (parts.year) { + parts.day = qMin(parts.day, QGregorianCalendar::monthLength(parts.month, parts.year)); + qint64 jd; + if (QGregorianCalendar::julianFromParts(parts.year, parts.month, parts.day, &jd)) + return QDate::fromJulianDay(jd); + } + return QDate(); +} + /***************************************************************************** Date/Time formatting helper functions *****************************************************************************/ @@ -340,7 +352,8 @@ static int fromOffsetString(const QStringRef &offsetString, bool *valid) noexcep QDate::QDate(int y, int m, int d) { - *this = QCalendar().dateFromParts(y, m, d); + if (!QGregorianCalendar::julianFromParts(y, m, d, &jd)) + jd = nullJd(); } QDate::QDate(int y, int m, int d, QCalendar cal) @@ -405,7 +418,12 @@ int QDate::year(QCalendar cal) const int QDate::year() const { - return year(QCalendar()); + if (isValid()) { + const auto parts = QGregorianCalendar::partsFromJulian(jd); + if (parts.isValid()) + return parts.year; + } + return 0; } /*! @@ -452,7 +470,12 @@ int QDate::month(QCalendar cal) const int QDate::month() const { - return month(QCalendar()); + if (isValid()) { + const auto parts = QGregorianCalendar::partsFromJulian(jd); + if (parts.isValid()) + return parts.month; + } + return 0; } /*! @@ -480,7 +503,12 @@ int QDate::day(QCalendar cal) const int QDate::day() const { - return day(QCalendar()); + if (isValid()) { + const auto parts = QGregorianCalendar::partsFromJulian(jd); + if (parts.isValid()) + return parts.day; + } + return 0; } /*! @@ -507,7 +535,7 @@ int QDate::dayOfWeek(QCalendar cal) const int QDate::dayOfWeek() const { - return dayOfWeek(QCalendar()); + return isValid() ? QGregorianCalendar::weekDayOfJulian(jd) : 0; } /*! @@ -535,7 +563,12 @@ int QDate::dayOfYear(QCalendar cal) const int QDate::dayOfYear() const { - return dayOfYear(QCalendar()); + if (isValid()) { + qint64 first; + if (QGregorianCalendar::julianFromParts(year(), 1, 1, &first)) + return jd - first + 1; + } + return 0; } /*! @@ -563,7 +596,12 @@ int QDate::daysInMonth(QCalendar cal) const int QDate::daysInMonth() const { - return daysInMonth(QCalendar()); + if (isValid()) { + const auto parts = QGregorianCalendar::partsFromJulian(jd); + if (parts.isValid()) + return QGregorianCalendar::monthLength(parts.month, parts.year); + } + return 0; } /*! @@ -589,7 +627,7 @@ int QDate::daysInYear(QCalendar cal) const int QDate::daysInYear() const { - return daysInYear(QCalendar()); + return isValid() ? QGregorianCalendar::leapTest(year()) ? 366 : 365 : 0; } /*! @@ -1303,7 +1341,11 @@ QString QDate::toString(const QString &format, QCalendar cal) const */ bool QDate::setDate(int year, int month, int day) { - return setDate(year, month, day, QCalendar()); + if (QGregorianCalendar::julianFromParts(year, month, day, &jd)) + return true; + + jd = nullJd(); + return false; } /*! @@ -1339,7 +1381,7 @@ void QDate::getDate(int *year, int *month, int *day) const { QCalendar::YearMonthDay parts; // invalid by default if (isValid()) - parts = QCalendar().partsFromDate(*this); + parts = QGregorianCalendar::partsFromJulian(jd); const bool ok = parts.isValid(); if (year) @@ -1428,7 +1470,30 @@ QDate QDate::addMonths(int nmonths, QCalendar cal) const QDate QDate::addMonths(int nmonths) const { - return addMonths(nmonths, QCalendar()); + if (isNull()) + return QDate(); + + if (nmonths == 0) + return *this; + + auto parts = QGregorianCalendar::partsFromJulian(jd); + + if (!parts.isValid()) + return QDate(); + Q_ASSERT(parts.year); + + parts.month += nmonths; + while (parts.month <= 0) { + if (--parts.year) // skip over year 0 + parts.month += 12; + } + while (parts.month > 12) { + parts.month -= 12; + if (!++parts.year) // skip over year 0 + ++parts.year; + } + + return fixedDate(std::move(parts)); } /*! @@ -1470,7 +1535,21 @@ QDate QDate::addYears(int nyears, QCalendar cal) const QDate QDate::addYears(int nyears) const { - return addYears(nyears, QCalendar()); + if (isNull()) + return QDate(); + + auto parts = QGregorianCalendar::partsFromJulian(jd); + if (!parts.isValid()) + return QDate(); + + int old_y = parts.year; + parts.year += nyears; + + // If we just crossed (or hit) a missing year zero, adjust year by +/- 1: + if ((old_y > 0) != (parts.year > 0) || !parts.year) + parts.year += nyears > 0 ? +1 : -1; + + return fixedDate(std::move(parts)); } /*! @@ -1719,7 +1798,7 @@ QDate QDate::fromString(const QString &string, const QString &format) bool QDate::isValid(int year, int month, int day) { - return QCalendar().isDateValid(year, month, day); + return QGregorianCalendar::validParts(year, month, day); } /*! @@ -1733,7 +1812,7 @@ bool QDate::isValid(int year, int month, int day) bool QDate::isLeapYear(int y) { - return QCalendar().isLeapYear(y); + return QGregorianCalendar::leapTest(y); } /*! \fn static QDate QDate::fromJulianDay(qint64 jd) diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h index e1909b85e3..3eae8ebf64 100644 --- a/src/corelib/time/qdatetime.h +++ b/src/corelib/time/qdatetime.h @@ -58,7 +58,7 @@ class QCalendar; class QTimeZone; class QDateTime; -class Q_CORE_EXPORT QDate +class Q_CORE_EXPORT QDate // ### Qt 6: change to be used by value, not const & { public: enum MonthNameType { // ### Qt 6: remove, along with methods using it @@ -138,7 +138,7 @@ public: Q_REQUIRED_RESULT QDate addYears(int years) const; Q_REQUIRED_RESULT QDate addMonths(int months, QCalendar cal) const; Q_REQUIRED_RESULT QDate addYears(int years, QCalendar cal) const; - qint64 daysTo(const QDate &) const; + qint64 daysTo(const QDate &) const; // ### Qt 6: QDate Q_DECL_CONSTEXPR bool operator==(const QDate &other) const { return jd == other.jd; } Q_DECL_CONSTEXPR bool operator!=(const QDate &other) const { return jd != other.jd; } @@ -177,7 +177,7 @@ private: }; Q_DECLARE_TYPEINFO(QDate, Q_MOVABLE_TYPE); -class Q_CORE_EXPORT QTime +class Q_CORE_EXPORT QTime // ### Qt 6: change to be used by value, not const & { explicit Q_DECL_CONSTEXPR QTime(int ms) : mds(ms) {} @@ -203,9 +203,9 @@ public: bool setHMS(int h, int m, int s, int ms = 0); Q_REQUIRED_RESULT QTime addSecs(int secs) const; - int secsTo(const QTime &) const; + int secsTo(const QTime &) const; // ### Qt 6: plain QTime Q_REQUIRED_RESULT QTime addMSecs(int ms) const; - int msecsTo(const QTime &) const; + int msecsTo(const QTime &) const; // ### Qt 6: plain QTime Q_DECL_CONSTEXPR bool operator==(const QTime &other) const { return mds == other.mds; } Q_DECL_CONSTEXPR bool operator!=(const QTime &other) const { return mds != other.mds; } @@ -236,7 +236,7 @@ private: friend class QDateTime; friend class QDateTimePrivate; -#ifndef QT_NO_DATASTREAM +#ifndef QT_NO_DATASTREAM // ### Qt 6: plain QTime friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QTime &); friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &); #endif @@ -287,7 +287,7 @@ class Q_CORE_EXPORT QDateTime public: QDateTime() noexcept(Data::CanBeSmall); - explicit QDateTime(const QDate &); + explicit QDateTime(const QDate &); // ### Qt 6: plain QDate, QTime QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime); // ### Qt 6: Merge with above with default offsetSeconds = 0 QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds); @@ -319,7 +319,7 @@ public: qint64 toMSecsSinceEpoch() const; qint64 toSecsSinceEpoch() const; - void setDate(const QDate &date); + void setDate(const QDate &date); // ### Qt 6: plain QDate void setTime(const QTime &time); void setTimeSpec(Qt::TimeSpec spec); void setOffsetFromUtc(int offsetSeconds); diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index 3c54a259a4..d0f34358b9 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -60,6 +60,9 @@ QT_BEGIN_NAMESPACE +template <typename T> +using ShortVector = QVarLengthArray<T, 13>; // enough for month (incl. leap) and day-of-week names + QDateTimeParser::~QDateTimeParser() { } @@ -1538,7 +1541,7 @@ QDateTimeParser::parse(QString input, int position, const QDateTime &defaultValu length of overlap in *used (if \a used is non-NULL) and the first entry that overlapped this much in *usedText (if \a usedText is non-NULL). */ -static int findTextEntry(const QString &text, const QVector<QString> &entries, QString *usedText, int *used) +static int findTextEntry(const QString &text, const ShortVector<QString> &entries, QString *usedText, int *used) { if (text.isEmpty()) return -1; @@ -1586,7 +1589,7 @@ int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionI QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat; QLocale l = locale(); - QVector<QString> monthNames; + ShortVector<QString> monthNames; monthNames.reserve(13 - startMonth); for (int month = startMonth; month <= 12; ++month) monthNames.append(calendar.monthName(l, month, year, type)); @@ -1605,7 +1608,7 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex QLocale::FormatType type = sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat; QLocale l = locale(); - QVector<QString> daysOfWeek; + ShortVector<QString> daysOfWeek; daysOfWeek.reserve(8 - startDay); for (int day = startDay; day <= 7; ++day) daysOfWeek.append(l.dayName(day, type)); diff --git a/src/corelib/time/qgregoriancalendar.cpp b/src/corelib/time/qgregoriancalendar.cpp index d3db572aa7..447185d124 100644 --- a/src/corelib/time/qgregoriancalendar.cpp +++ b/src/corelib/time/qgregoriancalendar.cpp @@ -78,6 +78,11 @@ QCalendar::System QGregorianCalendar::calendarSystem() const bool QGregorianCalendar::isLeapYear(int year) const { + return leapTest(year); +} + +bool QGregorianCalendar::leapTest(int year) +{ if (year == QCalendar::Unspecified) return false; @@ -88,10 +93,37 @@ bool QGregorianCalendar::isLeapYear(int year) const return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } +// Duplicating code from QRomanCalendar, but inlining isLeapYear() as leapTest(): +int QGregorianCalendar::monthLength(int month, int year) +{ + if (month < 1 || month > 12) + return 0; + + if (month == 2) + return leapTest(year) ? 29 : 28; + + return 30 | ((month & 1) ^ (month >> 3)); +} + +bool QGregorianCalendar::validParts(int year, int month, int day) +{ + return year && 0 < day && day <= monthLength(month, year); +} + +int QGregorianCalendar::weekDayOfJulian(qint64 jd) +{ + return qMod(jd, 7) + 1; +} + bool QGregorianCalendar::dateToJulianDay(int year, int month, int day, qint64 *jd) const { + return julianFromParts(year, month, day, jd); +} + +bool QGregorianCalendar::julianFromParts(int year, int month, int day, qint64 *jd) +{ Q_ASSERT(jd); - if (!isDateValid(year, month, day)) + if (!validParts(year, month, day)) return false; if (year < 0) @@ -112,6 +144,11 @@ bool QGregorianCalendar::dateToJulianDay(int year, int month, int day, qint64 *j QCalendar::YearMonthDay QGregorianCalendar::julianDayToDate(qint64 jd) const { + return partsFromJulian(jd); +} + +QCalendar::YearMonthDay QGregorianCalendar::partsFromJulian(qint64 jd) +{ /* * Math from The Calendar FAQ at http://www.tondering.dk/claus/cal/julperiod.php * This formula is correct for all julian days, when using mathematical integer diff --git a/src/corelib/time/qgregoriancalendar_p.h b/src/corelib/time/qgregoriancalendar_p.h index 4e6c42ef76..191f9c127b 100644 --- a/src/corelib/time/qgregoriancalendar_p.h +++ b/src/corelib/time/qgregoriancalendar_p.h @@ -75,6 +75,14 @@ public: QLocale::FormatType format) const override; QString standaloneMonthName(const QLocale &locale, int month, int year, QLocale::FormatType format) const override; + + // Static optimized versions for the benefit of QDate: + static int weekDayOfJulian(qint64 jd); + static bool leapTest(int year); + static int monthLength(int month, int year); + static bool validParts(int year, int month, int day); + static QCalendar::YearMonthDay partsFromJulian(qint64 jd); + static bool julianFromParts(int year, int month, int day, qint64 *jd); }; QT_END_NAMESPACE |