diff options
Diffstat (limited to 'src/corelib/tools')
35 files changed, 1468 insertions, 1202 deletions
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index 4f704d6764..6e68bc7eb1 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -142,15 +142,9 @@ QT_DEPRECATED_X("Use std::count") inline void qCount(const Container &container, } #ifdef Q_QDOC -template <typename T> -LessThan qLess() -{ -} - -template <typename T> -LessThan qGreater() -{ -} +typedef void* LessThan; +template <typename T> LessThan qLess(); +template <typename T> LessThan qGreater(); #else template <typename T> class QT_DEPRECATED_X("Use std::less") qLess @@ -522,20 +516,148 @@ QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessItera #endif // QT_DEPRECATED_SINCE(5, 2) -} //namespace QAlgorithmsPrivate - +// Clang had a bug where __builtin_ctz/clz/popcount were not marked as constexpr. +#if !defined Q_CC_CLANG || (defined __apple_build_version__ && __clang_major__ >= 7) \ + || (Q_CC_CLANG >= 307) +# define QT_HAS_CONSTEXPR_BUILTINS +#endif -// Use __builtin_popcount on gcc. Clang claims to be gcc -// but has a bug where __builtin_popcount is not marked as -// constexpr. -#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) +#if defined QT_HAS_CONSTEXPR_BUILTINS +#if defined(Q_CC_GNU) +# define QT_HAS_BUILTIN_CTZS +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) Q_DECL_NOTHROW +{ +# if QT_HAS_BUILTIN(__builtin_ctzs) || defined(__BMI__) + return __builtin_ctzs(v); +# else + return __builtin_ctz(v); +# endif +} +#define QT_HAS_BUILTIN_CLZS +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) Q_DECL_NOTHROW +{ +# if QT_HAS_BUILTIN(__builtin_clzs) || defined(__BMI__) + return __builtin_clzs(v); +# else + return __builtin_clz(v) - 16U; +# endif +} +#define QT_HAS_BUILTIN_CTZ +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctz(quint32 v) Q_DECL_NOTHROW +{ + return __builtin_ctz(v); +} +#define QT_HAS_BUILTIN_CLZ +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_clz(quint32 v) Q_DECL_NOTHROW +{ + return __builtin_clz(v); +} +#define QT_HAS_BUILTIN_CTZLL +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzll(quint64 v) Q_DECL_NOTHROW +{ + return __builtin_ctzll(v); +} +#define QT_HAS_BUILTIN_CLZLL +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_clzll(quint64 v) Q_DECL_NOTHROW +{ + return __builtin_clzll(v); +} #define QALGORITHMS_USE_BUILTIN_POPCOUNT -#endif +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_popcount(quint32 v) Q_DECL_NOTHROW +{ + return __builtin_popcount(v); +} +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_popcount(quint8 v) Q_DECL_NOTHROW +{ + return __builtin_popcount(v); +} +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_popcount(quint16 v) Q_DECL_NOTHROW +{ + return __builtin_popcount(v); +} +#define QALGORITHMS_USE_BUILTIN_POPCOUNTLL +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_popcountll(quint64 v) Q_DECL_NOTHROW +{ + return __builtin_popcountll(v); +} +#elif defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_PROCESSOR_ARM) +#define QT_HAS_BUILTIN_CTZ +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE unsigned long qt_builtin_ctz(quint32 val) +{ + unsigned long result; + _BitScanForward(&result, val); + return result; +} +#define QT_HAS_BUILTIN_CLZ +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE unsigned long qt_builtin_clz(quint32 val) +{ + unsigned long result; + _BitScanReverse(&result, val); + // Now Invert the result: clz will count *down* from the msb to the lsb, so the msb index is 31 + // and the lsb index is 0. The result for the index when counting up: msb index is 0 (because it + // starts there), and the lsb index is 31. + result ^= sizeof(quint32) * 8 - 1; + return result; +} +#if Q_PROCESSOR_WORDSIZE == 8 +// These are only defined for 64bit builds. +#define QT_HAS_BUILTIN_CTZLL +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE unsigned long qt_builtin_ctzll(quint64 val) +{ + unsigned long result; + _BitScanForward64(&result, val); + return result; +} +// MSVC calls it _BitScanReverse and returns the carry flag, which we don't need +#define QT_HAS_BUILTIN_CLZLL +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE unsigned long qt_builtin_clzll(quint64 val) +{ + unsigned long result; + _BitScanReverse64(&result, val); + // see qt_builtin_clz + result ^= sizeof(quint64) * 8 - 1; + return result; +} +#endif // MSVC 64bit +# define QT_HAS_BUILTIN_CTZS +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) Q_DECL_NOTHROW +{ + return qt_builtin_ctz(v); +} +#define QT_HAS_BUILTIN_CLZS +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) Q_DECL_NOTHROW +{ + return qt_builtin_clz(v) - 16U; +} +#define QALGORITHMS_USE_BUILTIN_POPCOUNT +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_popcount(quint32 v) Q_DECL_NOTHROW +{ + return __popcnt(v); +} +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_popcount(quint8 v) Q_DECL_NOTHROW +{ + return __popcnt16(v); +} +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_popcount(quint16 v) Q_DECL_NOTHROW +{ + return __popcnt16(v); +} +#if Q_PROCESSOR_WORDSIZE == 8 +#define QALGORITHMS_USE_BUILTIN_POPCOUNTLL +Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_popcountll(quint64 v) Q_DECL_NOTHROW +{ + return __popcnt64(v); +} +#endif // MSVC 64bit +#endif // MSVC +#endif // QT_HAS_CONSTEXPR_BUILTINS + +} //namespace QAlgorithmsPrivate Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(quint32 v) Q_DECL_NOTHROW { #ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT - return __builtin_popcount(v); + return QAlgorithmsPrivate::qt_builtin_popcount(v); #else // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel return @@ -548,7 +670,7 @@ Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(quint32 v) Q Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(quint8 v) Q_DECL_NOTHROW { #ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT - return __builtin_popcount(v); + return QAlgorithmsPrivate::qt_builtin_popcount(v); #else return (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f; @@ -558,7 +680,7 @@ Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(quint8 v) Q_ Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(quint16 v) Q_DECL_NOTHROW { #ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT - return __builtin_popcount(v); + return QAlgorithmsPrivate::qt_builtin_popcount(v); #else return (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + @@ -568,8 +690,8 @@ Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(quint16 v) Q Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(quint64 v) Q_DECL_NOTHROW { -#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNT - return __builtin_popcountll(v); +#ifdef QALGORITHMS_USE_BUILTIN_POPCOUNTLL + return QAlgorithmsPrivate::qt_builtin_popcountll(v); #else return (((v ) & 0xfff) * Q_UINT64_C(0x1001001001001) & Q_UINT64_C(0x84210842108421)) % 0x1f + @@ -592,8 +714,8 @@ Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(long unsigne Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint32 v) Q_DECL_NOTHROW { -#if defined(Q_CC_GNU) - return v ? __builtin_ctz(v) : 32U; +#if defined(QT_HAS_BUILTIN_CTZ) + return v ? QAlgorithmsPrivate::qt_builtin_ctz(v) : 32U; #else // see http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightParallel unsigned int c = 32; // c will be the number of zero bits on the right @@ -610,8 +732,8 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint32 v) Q_DECL_NO Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint8 v) Q_DECL_NOTHROW { -#if defined(Q_CC_GNU) - return v ? __builtin_ctz(v) : 8U; +#if defined(QT_HAS_BUILTIN_CTZ) + return v ? QAlgorithmsPrivate::qt_builtin_ctz(v) : 8U; #else unsigned int c = 8; // c will be the number of zero bits on the right v &= -signed(v); @@ -625,12 +747,8 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint8 v) Q_DECL_NOT Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint16 v) Q_DECL_NOTHROW { -#if defined(Q_CC_GNU) -# if QT_HAS_BUILTIN(__builtin_ctzs) || (defined(__LZCNT__) && defined(__BMI__)) - return v ? __builtin_ctzs(v) : 16U; -# else - return v ? __builtin_ctz(v) : 16U; -# endif +#if defined(QT_HAS_BUILTIN_CTZS) + return v ? QAlgorithmsPrivate::qt_builtin_ctzs(v) : 16U; #else unsigned int c = 16; // c will be the number of zero bits on the right v &= -signed(v); @@ -645,8 +763,8 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint16 v) Q_DECL_NO Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint64 v) Q_DECL_NOTHROW { -#if defined(Q_CC_GNU) - return v ? __builtin_ctzll(v) : 64; +#if defined(QT_HAS_BUILTIN_CTZLL) + return v ? QAlgorithmsPrivate::qt_builtin_ctzll(v) : 64; #else quint32 x = static_cast<quint32>(v); return x ? qCountTrailingZeroBits(x) @@ -661,8 +779,8 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(unsigned long v) Q_D Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint32 v) Q_DECL_NOTHROW { -#if defined(Q_CC_GNU) - return v ? __builtin_clz(v) : 32U; +#if defined(QT_HAS_BUILTIN_CLZ) + return v ? QAlgorithmsPrivate::qt_builtin_clz(v) : 32U; #else // Hacker's Delight, 2nd ed. Fig 5-16, p. 102 v = v | (v >> 1); @@ -676,8 +794,8 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint32 v) Q_DECL_NOT Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint8 v) Q_DECL_NOTHROW { -#if defined(Q_CC_GNU) - return v ? __builtin_clz(v)-24U : 8U; +#if defined(QT_HAS_BUILTIN_CLZ) + return v ? QAlgorithmsPrivate::qt_builtin_clz(v)-24U : 8U; #else v = v | (v >> 1); v = v | (v >> 2); @@ -688,12 +806,8 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint8 v) Q_DECL_NOTH Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint16 v) Q_DECL_NOTHROW { -#if defined(Q_CC_GNU) -# if QT_HAS_BUILTIN(__builtin_clzs) || (defined(__LZCNT__) && defined(__BMI__)) - return v ? __builtin_clzs(v) : 16U; -# else - return v ? __builtin_clz(v)-16U : 16U; -# endif +#if defined(QT_HAS_BUILTIN_CLZS) + return v ? QAlgorithmsPrivate::qt_builtin_clzs(v) : 16U; #else v = v | (v >> 1); v = v | (v >> 2); @@ -705,8 +819,8 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint16 v) Q_DECL_NOT Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint64 v) Q_DECL_NOTHROW { -#if defined(Q_CC_GNU) - return v ? __builtin_clzll(v) : 64U; +#if defined(QT_HAS_BUILTIN_CLZLL) + return v ? QAlgorithmsPrivate::qt_builtin_clzll(v) : 64U; #else v = v | (v >> 1); v = v | (v >> 2); diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index c9d6f4e411..266c2e9b57 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -4467,91 +4467,6 @@ QByteArray QByteArray::fromPercentEncoding(const QByteArray &input, char percent \sa fromStdString(), QString::toStdString() */ -/*! \fn QByteArray QByteArray::fromCFData(CFDataRef data) - \since 5.3 - - Constructs a new QByteArray containing a copy of the CFData \a data. - - \sa fromRawCFData(), fromRawData(), toRawCFData(), toCFData() -*/ - -/*! \fn QByteArray QByteArray::fromRawCFData(CFDataRef data) - \since 5.3 - - Constructs a QByteArray that uses the bytes of the CFData \a data. - - The \a data's bytes are not copied. - - The caller guarantees that the CFData will not be deleted - or modified as long as this QByteArray object exists. - - \sa fromCFData(), fromRawData(), toRawCFData(), toCFData() -*/ - -/*! \fn CFDataRef QByteArray::toCFData() const - \since 5.3 - - Creates a CFData from a QByteArray. The caller owns the CFData object - and is responsible for releasing it. - - \sa toRawCFData(), fromCFData(), fromRawCFData(), fromRawData() -*/ - -/*! \fn CFDataRef QByteArray::toRawCFData() const - \since 5.3 - - Constructs a CFData that uses the bytes of the QByteArray. - - The QByteArray's bytes are not copied. - - The caller guarantees that the QByteArray will not be deleted - or modified as long as this CFData object exists. - - \sa toCFData(), fromRawCFData(), fromCFData(), fromRawData() -*/ - -/*! \fn QByteArray QByteArray::fromNSData(const NSData *data) - \since 5.3 - - Constructs a new QByteArray containing a copy of the NSData \a data. - - \sa fromRawNSData(), fromRawData(), toNSData(), toRawNSData() -*/ - -/*! \fn QByteArray QByteArray::fromRawNSData(const NSData *data) - \since 5.3 - - Constructs a QByteArray that uses the bytes of the NSData \a data. - - The \a data's bytes are not copied. - - The caller guarantees that the NSData will not be deleted - or modified as long as this QByteArray object exists. - - \sa fromNSData(), fromRawData(), toRawNSData(), toNSData() -*/ - -/*! \fn NSData QByteArray::toNSData() const - \since 5.3 - - Creates a NSData from a QByteArray. The NSData object is autoreleased. - - \sa fromNSData(), fromRawNSData(), fromRawData(), toRawNSData() -*/ - -/*! \fn NSData QByteArray::toRawNSData() const - \since 5.3 - - Constructs a NSData that uses the bytes of the QByteArray. - - The QByteArray's bytes are not copied. - - The caller guarantees that the QByteArray will not be deleted - or modified as long as this NSData object exists. - - \sa fromRawNSData(), fromNSData(), fromRawData(), toNSData() -*/ - static inline bool q_strchr(const char str[], char chr) { if (!str) return false; diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index d334bb43c5..477402d6de 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -56,11 +56,9 @@ #error qbytearray.h must be included before any header file that defines truncate #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_DARWIN) || defined(Q_QDOC) Q_FORWARD_DECLARE_CF_TYPE(CFData); -# ifdef __OBJC__ Q_FORWARD_DECLARE_OBJC_CLASS(NSData); -# endif #endif QT_BEGIN_NAMESPACE @@ -384,17 +382,15 @@ public: static QByteArray fromHex(const QByteArray &hexEncoded) Q_REQUIRED_RESULT; static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%') Q_REQUIRED_RESULT; -#if defined(Q_OS_MAC) || defined(Q_QDOC) +#if defined(Q_OS_DARWIN) || defined(Q_QDOC) static QByteArray fromCFData(CFDataRef data); static QByteArray fromRawCFData(CFDataRef data); CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED; CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED; -# if defined(__OBJC__) || defined(Q_QDOC) static QByteArray fromNSData(const NSData *data); static QByteArray fromRawNSData(const NSData *data); NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED; NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED; -# endif #endif typedef char *iterator; diff --git a/src/corelib/tools/qbytearray_mac.mm b/src/corelib/tools/qbytearray_mac.mm deleted file mode 100644 index 9386a966f0..0000000000 --- a/src/corelib/tools/qbytearray_mac.mm +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch> -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbytearray.h" - -#import <Foundation/Foundation.h> - -QT_BEGIN_NAMESPACE - -QByteArray QByteArray::fromCFData(CFDataRef data) -{ - if (!data) - return QByteArray(); - - return QByteArray(reinterpret_cast<const char *>(CFDataGetBytePtr(data)), CFDataGetLength(data)); -} - -QByteArray QByteArray::fromRawCFData(CFDataRef data) -{ - if (!data) - return QByteArray(); - - return QByteArray::fromRawData(reinterpret_cast<const char *>(CFDataGetBytePtr(data)), CFDataGetLength(data)); -} - -CFDataRef QByteArray::toCFData() const -{ - return CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data()), length()); -} - -CFDataRef QByteArray::toRawCFData() const -{ - return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data()), - length(), kCFAllocatorNull); -} - -QByteArray QByteArray::fromNSData(const NSData *data) -{ - if (!data) - return QByteArray(); - return QByteArray(reinterpret_cast<const char *>([data bytes]), [data length]); -} - -QByteArray QByteArray::fromRawNSData(const NSData *data) -{ - if (!data) - return QByteArray(); - return QByteArray::fromRawData(reinterpret_cast<const char *>([data bytes]), [data length]); -} - -NSData *QByteArray::toNSData() const -{ - return [NSData dataWithBytes:constData() length:size()]; -} - -NSData *QByteArray::toRawNSData() const -{ - // const_cast is fine here because NSData is immutable thus will never modify bytes we're giving it - return [NSData dataWithBytesNoCopy:const_cast<char *>(constData()) length:size() freeWhenDone:NO]; -} - -QT_END_NAMESPACE diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h index bc8b08b380..501bb2e0d5 100644 --- a/src/corelib/tools/qbytearraylist.h +++ b/src/corelib/tools/qbytearraylist.h @@ -50,11 +50,13 @@ QT_BEGIN_NAMESPACE typedef QListIterator<QByteArray> QByteArrayListIterator; typedef QMutableListIterator<QByteArray> QMutableByteArrayListIterator; +#ifndef Q_QDOC typedef QList<QByteArray> QByteArrayList; namespace QtPrivate { QByteArray Q_CORE_EXPORT QByteArrayList_join(const QByteArrayList *that, const char *separator, int separatorLength); } +#endif #ifdef Q_QDOC class QByteArrayList : public QList<QByteArray> diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h index f01fbc109c..a83e5e6f98 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -578,6 +578,18 @@ Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) Q_DECL_NOTHROW { ret Q_DECL_CONSTEXPR inline bool operator> (QChar c1, QChar c2) Q_DECL_NOTHROW { return operator< (c2, c1); } Q_DECL_CONSTEXPR inline bool operator<=(QChar c1, QChar c2) Q_DECL_NOTHROW { return !operator< (c2, c1); } +// disambiguate QChar == int (but only that, so constrain template to exactly 'int'): +template <typename T> +Q_DECL_DEPRECATED_X("don't compare ints to QChars, compare them to QChar::unicode() instead") +Q_DECL_CONSTEXPR inline +typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, int>::value, bool>::type +operator==(QChar lhs, T rhs) Q_DECL_NOEXCEPT { return lhs == QChar(rhs); } +template <typename T> +Q_DECL_DEPRECATED_X("don't compare ints to QChars, compare them to QChar::unicode() instead") +Q_DECL_CONSTEXPR inline +typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, int>::value, bool>::type +operator!=(QChar lhs, T rhs) Q_DECL_NOEXCEPT { return lhs != QChar(rhs); } + #ifndef QT_NO_DATASTREAM Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QChar); Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QChar &); diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp index 64cabcc304..1f7f9cc33b 100644 --- a/src/corelib/tools/qcommandlineoption.cpp +++ b/src/corelib/tools/qcommandlineoption.cpp @@ -49,14 +49,12 @@ class QCommandLineOptionPrivate : public QSharedData public: Q_NEVER_INLINE explicit QCommandLineOptionPrivate(const QString &name) - : names(removeInvalidNames(QStringList(name))), - hidden(false) + : names(removeInvalidNames(QStringList(name))) { } Q_NEVER_INLINE explicit QCommandLineOptionPrivate(const QStringList &names) - : names(removeInvalidNames(names)), - hidden(false) + : names(removeInvalidNames(names)) { } static QStringList removeInvalidNames(QStringList nameList); @@ -74,8 +72,7 @@ public: //! The list of default values used for this option. QStringList defaultValues; - //! Show or hide in --help - bool hidden; + QCommandLineOption::Flags flags; }; /*! @@ -394,6 +391,7 @@ QStringList QCommandLineOption::defaultValues() const return d->defaultValues; } +#if QT_DEPRECATED_SINCE(5, 8) /*! Sets whether to hide this option in the user-visible help output. @@ -401,11 +399,12 @@ QStringList QCommandLineOption::defaultValues() const a particular option makes it internal, i.e. not listed in the help output. \since 5.6 + \obsolete Use setFlags(QCommandLineOption::HiddenFromHelp), QCommandLineOption::HiddenFromHelp \sa isHidden */ void QCommandLineOption::setHidden(bool hide) { - d->hidden = hide; + d->flags.setFlag(HiddenFromHelp, hide); } /*! @@ -413,11 +412,52 @@ void QCommandLineOption::setHidden(bool hide) false if the option is listed. \since 5.6 - \sa setHidden() + \obsolete Use flags() & QCommandLineOption::HiddenFromHelp + \sa setHidden(), QCommandLineOption::HiddenFromHelp */ bool QCommandLineOption::isHidden() const { - return d->hidden; + return d->flags & HiddenFromHelp; } +#endif + +/*! + Returns a set of flags that affect this command-line option. + + \since 5.8 + \sa setFlags(), QCommandLineOption::Flags + */ +QCommandLineOption::Flags QCommandLineOption::flags() const +{ + return d->flags; +} + +/*! + Set the set of flags that affect this command-line option. + + \since 5.8 + \sa flags(), QCommandLineOption::Flags + */ +void QCommandLineOption::setFlags(Flags flags) +{ + d->flags = flags; +} + +/*! + \enum QCommandLineOption::Flag + + \value HiddenFromHelp Hide this option in the user-visible help output. All + options are visible by default. Setting this flag for a particular + option makes it internal, i.e. not listed in the help output. + + \value ShortOptionStyle The option will always be understood as a short + option, regardless of what was set by + QCommandLineParser::setSingleDashWordOptionMode. + This allows flags such as \c{-DDEFINE=VALUE} or \c{-I/include/path} to be + interpreted as short flags even when the parser is in + QCommandLineParser::ParseAsLongOptions mode. + + \sa QCommandLineOption::setFlags(), QCommandLineOption::flags() +*/ QT_END_NAMESPACE diff --git a/src/corelib/tools/qcommandlineoption.h b/src/corelib/tools/qcommandlineoption.h index a7747f9fb2..6ebaab3d48 100644 --- a/src/corelib/tools/qcommandlineoption.h +++ b/src/corelib/tools/qcommandlineoption.h @@ -50,6 +50,12 @@ class QCommandLineOptionPrivate; class Q_CORE_EXPORT QCommandLineOption { public: + enum Flag { + HiddenFromHelp = 0x1, + ShortOptionStyle = 0x2 + }; + Q_DECLARE_FLAGS(Flags, Flag) + explicit QCommandLineOption(const QString &name); explicit QCommandLineOption(const QStringList &names); /*implicit*/ QCommandLineOption(const QString &name, const QString &description, @@ -82,14 +88,24 @@ public: void setDefaultValues(const QStringList &defaultValues); QStringList defaultValues() const; + Flags flags() const; + void setFlags(Flags aflags); + +#if QT_DEPRECATED_SINCE(5, 8) + QT_DEPRECATED_X("Use setFlags() with HiddenFromHelp)") void setHidden(bool hidden); + QT_DEPRECATED_X("Use flags() and HiddenFromHelp") bool isHidden() const; +#endif + private: QSharedDataPointer<QCommandLineOptionPrivate> d; }; Q_DECLARE_SHARED(QCommandLineOption) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCommandLineOption::Flags) + QT_END_NAMESPACE diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index a7ab8b9e70..2450484ce9 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -44,7 +44,7 @@ #include <qhash.h> #include <qvector.h> #include <qdebug.h> -#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINRT) # include <qt_windows.h> #endif #include <stdio.h> @@ -295,7 +295,9 @@ QCommandLineParser::~QCommandLineParser() i.e. as the long option named \c{abc}. This is how Qt's own tools (uic, rcc...) have always been parsing arguments. This mode should be used for preserving compatibility in applications that were parsing - arguments in such a way. + arguments in such a way. There is an exception if the \c{a} option has the + QCommandLineOption::ShortOptionStyle flag set, in which case it is still + interpreted as \c{-a bc}. \sa setSingleDashWordOptionMode() */ @@ -530,7 +532,7 @@ QString QCommandLineParser::errorText() const enum MessageType { UsageMessage, ErrorMessage }; -#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINRT) // Return whether to use a message box. Use handles if a console can be obtained // or we are run with redirected handles (for example, by QProcess). static inline bool displayMessageBox() @@ -552,7 +554,7 @@ static void showParserMessage(const QString &message, MessageType type) else qCritical(qPrintable(message)); return; -#elif defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) +#elif defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) if (displayMessageBox()) { const UINT flags = MB_OK | MB_TOPMOST | MB_SETFOREGROUND | (type == UsageMessage ? MB_ICONINFORMATION : MB_ICONERROR); @@ -565,7 +567,7 @@ static void showParserMessage(const QString &message, MessageType type) reinterpret_cast<const wchar_t *>(title.utf16()), flags); return; } -#endif // Q_OS_WIN && !QT_BOOTSTRAPPED && !Q_OS_WINCE +#endif // Q_OS_WIN && !QT_BOOTSTRAPPED fputs(qPrintable(message), type == UsageMessage ? stdout : stderr); } @@ -762,6 +764,18 @@ bool QCommandLineParserPrivate::parse(const QStringList &args) } case QCommandLineParser::ParseAsLongOptions: { + if (argument.size() > 2) { + const QString possibleShortOptionStyleName = argument.mid(1, 1); + const auto shortOptionIt = nameHash.constFind(possibleShortOptionStyleName); + if (shortOptionIt != nameHash.constEnd()) { + const auto &arg = commandLineOptionList.at(*shortOptionIt); + if (arg.flags() & QCommandLineOption::ShortOptionStyle) { + registerFoundOption(possibleShortOptionStyleName); + optionValuesHash[*shortOptionIt].append(argument.mid(2)); + break; + } + } + } const QString optionName = argument.mid(1).section(assignChar, 0, 0); if (registerFoundOption(optionName)) { if (!parseOptionValue(optionName, argument, &argumentIterator, args.end())) @@ -1098,7 +1112,7 @@ QString QCommandLineParserPrivate::helpText() const optionNameList.reserve(commandLineOptionList.size()); int longestOptionNameString = 0; for (const QCommandLineOption &option : commandLineOptionList) { - if (option.isHidden()) + if (option.flags() & QCommandLineOption::HiddenFromHelp) continue; const QStringList optionNames = option.names(); QString optionNamesString; @@ -1117,7 +1131,7 @@ QString QCommandLineParserPrivate::helpText() const ++longestOptionNameString; auto optionNameIterator = optionNameList.cbegin(); for (const QCommandLineOption &option : commandLineOptionList) { - if (option.isHidden()) + if (option.flags() & QCommandLineOption::HiddenFromHelp) continue; text += wrapText(*optionNameIterator, longestOptionNameString, option.description()); ++optionNameIterator; diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h index a19c734768..0f17baa036 100644 --- a/src/corelib/tools/qcryptographichash.h +++ b/src/corelib/tools/qcryptographichash.h @@ -42,6 +42,7 @@ #define QCRYPTOGRAPHICHASH_H #include <QtCore/qbytearray.h> +#include <QtCore/qobjectdefs.h> QT_BEGIN_NAMESPACE @@ -51,6 +52,7 @@ class QIODevice; class Q_CORE_EXPORT QCryptographicHash { + Q_GADGET public: enum Algorithm { #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 @@ -69,6 +71,7 @@ public: Sha3_512 #endif }; + Q_ENUM(Algorithm) explicit QCryptographicHash(Algorithm method); ~QCryptographicHash(); diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 6750925853..2ebf7c7977 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -57,9 +57,6 @@ #include <time.h> #ifdef Q_OS_WIN # include <qt_windows.h> -# ifdef Q_OS_WINCE -# include "qfunctions_wince.h" -# endif # ifdef Q_OS_WINRT # include "qfunctions_winrt.h" # endif @@ -71,8 +68,6 @@ QT_BEGIN_NAMESPACE -Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QDateTimePrivate>, defaultDateTimePrivate, (new QDateTimePrivate())) - /***************************************************************************** Date/Time Constants *****************************************************************************/ @@ -1685,9 +1680,6 @@ QString QTime::toString(const QString& format) const bool QTime::setHMS(int h, int m, int s, int ms) { -#if defined(Q_OS_WINCE) - startTick = NullTime; -#endif if (!isValid(h,m,s,ms)) { mds = NullTime; // make this invalid return false; @@ -1767,10 +1759,6 @@ QTime QTime::addMSecs(int ms) const t.mds = (ds() + ms) % MSECS_PER_DAY; } } -#if defined(Q_OS_WINCE) - if (startTick > NullTime) - t.startTick = (startTick + ms) % MSECS_PER_DAY; -#endif return t; } @@ -1792,13 +1780,7 @@ int QTime::msecsTo(const QTime &t) const { if (!isValid() || !t.isValid()) return 0; -#if defined(Q_OS_WINCE) - // GetLocalTime() for Windows CE has no milliseconds resolution - if (t.startTick > NullTime && startTick > NullTime) - return t.startTick - startTick; - else -#endif - return t.ds() - ds(); + return t.ds() - ds(); } @@ -2137,13 +2119,14 @@ int QTime::elapsed() const QDateTime static helper functions *****************************************************************************/ +// get the types from QDateTime (through QDateTimePrivate) +typedef QDateTimePrivate::QDateTimeShortData ShortData; +typedef QDateTimePrivate::QDateTimeData QDateTimeData; + // Calls the platform variant of tzset static void qt_tzset() { -#if defined(Q_OS_WINCE) - // WinCE doesn't use tzset - return; -#elif defined(Q_OS_WIN) +#if defined(Q_OS_WIN) _tzset(); #else tzset(); @@ -2157,12 +2140,7 @@ static void qt_tzset() // Relies on tzset, mktime, or localtime having been called to populate timezone static int qt_timezone() { -#if defined(Q_OS_WINCE) - TIME_ZONE_INFORMATION tzi; - GetTimeZoneInformation(&tzi); - // Expressed in minutes, convert to seconds - return (tzi.Bias + tzi.StandardBias) * 60; -#elif defined(_MSC_VER) && _MSC_VER >= 1400 +#if defined(_MSC_VER) long offset; _get_timezone(&offset); return offset; @@ -2191,16 +2169,6 @@ static int qt_timezone() // Returns the tzname, assume tzset has been called already static QString qt_tzname(QDateTimePrivate::DaylightStatus daylightStatus) { -#if defined(Q_OS_WINCE) - TIME_ZONE_INFORMATION tzi; - DWORD res = GetTimeZoneInformation(&tzi); - if (res == TIME_ZONE_ID_UNKNOWN) - return QString(); - else if (daylightStatus == QDateTimePrivate::DaylightTime) - return QString::fromWCharArray(tzi.DaylightName); - else - return QString::fromWCharArray(tzi.StandardName); -#else int isDst = (daylightStatus == QDateTimePrivate::DaylightTime) ? 1 : 0; #if defined(_MSC_VER) && _MSC_VER >= 1400 size_t s = 0; @@ -2211,7 +2179,6 @@ static QString qt_tzname(QDateTimePrivate::DaylightStatus daylightStatus) #else return QString::fromLocal8Bit(tzname[isDst]); #endif // Q_OS_WIN -#endif // Q_OS_WINCE } // Calls the platform variant of mktime for the given date, time and daylightStatus, @@ -2226,48 +2193,6 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat int yy, mm, dd; date->getDate(&yy, &mm, &dd); -#if defined(Q_OS_WINCE) - // WinCE doesn't provide standard C library time functions - SYSTEMTIME st; - memset(&st, 0, sizeof(SYSTEMTIME)); - st.wSecond = time->second(); - st.wMinute = time->minute(); - st.wHour = time->hour(); - st.wDay = dd; - st.wMonth = mm; - st.wYear = yy; - FILETIME lft; - bool valid = SystemTimeToFileTime(&st, &lft); - FILETIME ft; - if (valid) - valid = LocalFileTimeToFileTime(&lft, &ft); - const time_t secsSinceEpoch = ftToTime_t(ft); - const time_t localSecs = ftToTime_t(lft); - TIME_ZONE_INFORMATION tzi; - GetTimeZoneInformation(&tzi); - bool isDaylight = false; - // Check for overflow - qint64 localDiff = qAbs(localSecs - secsSinceEpoch); - int daylightOffset = qAbs(tzi.Bias + tzi.DaylightBias) * 60; - if (localDiff > daylightOffset) - valid = false; - else - isDaylight = (localDiff == daylightOffset); - if (daylightStatus) { - if (isDaylight) - *daylightStatus = QDateTimePrivate::DaylightTime; - else - *daylightStatus = QDateTimePrivate::StandardTime; - } - if (abbreviation) { - if (isDaylight) - *abbreviation = QString::fromWCharArray(tzi.DaylightName); - else - *abbreviation = QString::fromWCharArray(tzi.StandardName); - } - if (ok) - *ok = valid; -#else // All other platforms provide standard C library time functions tm local; memset(&local, 0, sizeof(local)); // tm_[wy]day plus any non-standard fields @@ -2329,7 +2254,6 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat if (ok) *ok = false; } -#endif // Q_OS_WINCE return ((qint64)secsSinceEpoch * 1000) + msec; } @@ -2345,23 +2269,7 @@ static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localT tm local; bool valid = false; -#if defined(Q_OS_WINCE) - FILETIME utcTime = time_tToFt(secsSinceEpoch); - FILETIME resultTime; - valid = FileTimeToLocalFileTime(&utcTime , &resultTime); - SYSTEMTIME sysTime; - if (valid) - valid = FileTimeToSystemTime(&resultTime , &sysTime); - - if (valid) { - local.tm_sec = sysTime.wSecond; - local.tm_min = sysTime.wMinute; - local.tm_hour = sysTime.wHour; - local.tm_mday = sysTime.wDay; - local.tm_mon = sysTime.wMonth - 1; - local.tm_year = sysTime.wYear - 1900; - } -#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // localtime() is required to work as if tzset() was called before it. // localtime_r() does not have this requirement, so make an explicit call. qt_tzset(); @@ -2574,240 +2482,403 @@ static qint64 localMSecsToEpochMSecs(qint64 localMsecs, } } -/***************************************************************************** - QDateTimePrivate member functions - *****************************************************************************/ +static inline bool specCanBeSmall(Qt::TimeSpec spec) +{ + return spec == Qt::LocalTime || spec == Qt::UTC; +} -QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec, - int offsetSeconds) - : m_msecs(0), - m_spec(Qt::LocalTime), - m_offsetFromUtc(0), - m_status(0) +static Q_DECL_CONSTEXPR inline +QDateTimePrivate::StatusFlags mergeSpec(QDateTimePrivate::StatusFlags status, Qt::TimeSpec spec) { - setTimeSpec(toSpec, offsetSeconds); - setDateTime(toDate, toTime); + return QDateTimePrivate::StatusFlags((status & ~QDateTimePrivate::TimeSpecMask) | + (int(spec) << QDateTimePrivate::TimeSpecShift)); } -#ifndef QT_BOOTSTRAPPED -QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, - const QTimeZone &toTimeZone) - : m_spec(Qt::TimeZone), - m_offsetFromUtc(0), - m_timeZone(toTimeZone), - m_status(0) +static Q_DECL_CONSTEXPR inline Qt::TimeSpec extractSpec(QDateTimePrivate::StatusFlags status) { - setDateTime(toDate, toTime); + return Qt::TimeSpec((status & QDateTimePrivate::TimeSpecMask) >> QDateTimePrivate::TimeSpecShift); } -#endif // QT_BOOTSTRAPPED -void QDateTimePrivate::setTimeSpec(Qt::TimeSpec spec, int offsetSeconds) +// 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) { - clearValidDateTime(); - clearSetToDaylightStatus(); + if (status & QDateTimePrivate::SetToDaylightTime) + return QDateTimePrivate::DaylightTime; + if (status & QDateTimePrivate::SetToStandardTime) + return QDateTimePrivate::StandardTime; + return QDateTimePrivate::UnknownDaylightTime; +} + +static inline qint64 getMSecs(const QDateTimeData &d) +{ + if (d.isShort()) { + // same as, but producing better code + //return d.data.msecs; + return qintptr(d.d) >> 8; + } + return d->m_msecs; +} + +static inline QDateTimePrivate::StatusFlags getStatus(const QDateTimeData &d) +{ + if (d.isShort()) { + // same as, but producing better code + //return StatusFlag(d.data.status); + return QDateTimePrivate::StatusFlag(qintptr(d.d) & 0xFF); + } + return d->m_status; +} + +static inline Qt::TimeSpec getSpec(const QDateTimeData &d) +{ + return extractSpec(getStatus(d)); +} + +// Refresh the LocalTime validity and offset +static void refreshDateTime(QDateTimeData &d) +{ + auto status = getStatus(d); + const auto spec = extractSpec(status); + const qint64 msecs = getMSecs(d); + qint64 epochMSecs = 0; + int offsetFromUtc = 0; + QDate testDate; + QTime testTime; + Q_ASSERT(spec == Qt::TimeZone || spec == Qt::LocalTime); #ifndef QT_BOOTSTRAPPED - m_timeZone = QTimeZone(); + // If not valid time zone then is invalid + if (spec == Qt::TimeZone) { + if (!d->m_timeZone.isValid()) + status &= ~QDateTimePrivate::ValidDateTime; + else + epochMSecs = QDateTimePrivate::zoneMSecsToEpochMSecs(msecs, d->m_timeZone, &testDate, &testTime); + } #endif // QT_BOOTSTRAPPED - switch (spec) { - case Qt::OffsetFromUTC: - if (offsetSeconds == 0) { - m_spec = Qt::UTC; - m_offsetFromUtc = 0; + // If not valid date and time then is invalid + if (!(status & QDateTimePrivate::ValidDate) || !(status & QDateTimePrivate::ValidTime)) { + status &= ~QDateTimePrivate::ValidDateTime; + if (status & QDateTimePrivate::ShortData) { + d.data.status = status; } else { - m_spec = Qt::OffsetFromUTC; - m_offsetFromUtc = offsetSeconds; + d->m_status = status; + d->m_offsetFromUtc = 0; } + return; + } + + // 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) { + auto dstStatus = extractDaylightStatus(status); + epochMSecs = localMSecsToEpochMSecs(msecs, &dstStatus, &testDate, &testTime); + } + if (timeToMSecs(testDate, testTime) == msecs) { + status |= QDateTimePrivate::ValidDateTime; + // Cache the offset to use in offsetFromUtc() + offsetFromUtc = (msecs - epochMSecs) / 1000; + } else { + status &= ~QDateTimePrivate::ValidDateTime; + } + + if (status & QDateTimePrivate::ShortData) { + d.data.status = status; + } else { + d->m_status = status; + d->m_offsetFromUtc = offsetFromUtc; + } +} + +// Check the UTC / offsetFromUTC validity +static void checkValidDateTime(QDateTimeData &d) +{ + auto status = getStatus(d); + 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 ((status & QDateTimePrivate::ValidDate) && (status & QDateTimePrivate::ValidTime)) + status |= QDateTimePrivate::ValidDateTime; + else + status &= ~QDateTimePrivate::ValidDateTime; + if (status & QDateTimePrivate::ShortData) + d.data.status = status; + else + d->m_status = status; break; case Qt::TimeZone: - // Use system time zone instead - m_spec = Qt::LocalTime; - m_offsetFromUtc = 0; + case Qt::LocalTime: + // for these, we need to check whether the timezone is valid and whether + // the time is valid in that timezone. Expensive, but no other option. + refreshDateTime(d); break; + } +} + +static void setTimeSpec(QDateTimeData &d, Qt::TimeSpec spec, int offsetSeconds) +{ + auto status = getStatus(d); + status &= ~(QDateTimePrivate::ValidDateTime | QDateTimePrivate::DaylightMask | + QDateTimePrivate::TimeSpecMask); + + switch (spec) { + case Qt::OffsetFromUTC: + if (offsetSeconds == 0) + spec = Qt::UTC; + break; + case Qt::TimeZone: + // Use system time zone instead + spec = Qt::LocalTime; + // fallthrough case Qt::UTC: case Qt::LocalTime: - m_spec = spec; - m_offsetFromUtc = 0; + offsetSeconds = 0; break; } + + status = mergeSpec(status, spec); + if (d.isShort() && offsetSeconds == 0) { + d.data.status = status; + } else { + d.detach(); + d->m_status = status & ~QDateTimePrivate::ShortData; + d->m_offsetFromUtc = offsetSeconds; +#ifndef QT_BOOTSTRAPPED + d->m_timeZone = QTimeZone(); +#endif // QT_BOOTSTRAPPED + } } -void QDateTimePrivate::setDateTime(const QDate &date, const QTime &time) +static void setDateTime(QDateTimeData &d, const QDate &date, const QTime &time) { // If the date is valid and the time is not we set time to 00:00:00 QTime useTime = time; if (!useTime.isValid() && date.isValid()) useTime = QTime::fromMSecsSinceStartOfDay(0); - StatusFlags newStatus; + QDateTimePrivate::StatusFlags newStatus = 0; // Set date value and status qint64 days = 0; if (date.isValid()) { days = date.toJulianDay() - JULIAN_DAY_FOR_EPOCH; - newStatus = ValidDate; - } else if (date.isNull()) { - newStatus = NullDate; + newStatus = QDateTimePrivate::ValidDate; } // Set time value and status int ds = 0; if (useTime.isValid()) { ds = useTime.msecsSinceStartOfDay(); - newStatus |= ValidTime; - } else if (time.isNull()) { - newStatus |= NullTime; + newStatus |= QDateTimePrivate::ValidTime; } // Set msecs serial value - m_msecs = (days * MSECS_PER_DAY) + ds; - m_status = newStatus; + qint64 msecs = (days * MSECS_PER_DAY) + ds; + if (d.isShort()) { + // let's see if we can keep this short + d.data.msecs = qintptr(msecs); + if (d.data.msecs == msecs) { + // yes, we can + d.data.status &= ~(QDateTimePrivate::ValidityMask | QDateTimePrivate::DaylightMask); + d.data.status |= newStatus; + } else { + // nope... + d.detach(); + } + } + if (!d.isShort()) { + d.detach(); + d->m_msecs = msecs; + d->m_status &= ~(QDateTimePrivate::ValidityMask | QDateTimePrivate::DaylightMask); + d->m_status |= newStatus; + } // Set if date and time are valid - checkValidDateTime(); + checkValidDateTime(d); } -QPair<QDate, QTime> QDateTimePrivate::getDateTime() const +static QPair<QDate, QTime> getDateTime(const QDateTimeData &d) { QPair<QDate, QTime> result; - msecsToTime(m_msecs, &result.first, &result.second); + qint64 msecs = getMSecs(d); + auto status = getStatus(d); + msecsToTime(msecs, &result.first, &result.second); - if (isNullDate()) + if (!status.testFlag(QDateTimePrivate::ValidDate)) result.first = QDate(); - if (isNullTime()) + if (!status.testFlag(QDateTimePrivate::ValidTime)) result.second = QTime(); return result; } -// Set the Daylight Status if LocalTime set via msecs -void QDateTimePrivate::setDaylightStatus(QDateTimePrivate::DaylightStatus status) -{ - if (status == DaylightTime) { - m_status = m_status & ~SetToStandardTime; - m_status = m_status | SetToDaylightTime; - } else if (status == StandardTime) { - m_status = m_status & ~SetToDaylightTime; - m_status = m_status | SetToStandardTime; +/***************************************************************************** + QDateTime::Data member functions + *****************************************************************************/ + +inline QDateTime::Data::Data(Qt::TimeSpec spec) +{ + if (CanBeSmall && Q_LIKELY(specCanBeSmall(spec))) { + d = reinterpret_cast<QDateTimePrivate *>(int(mergeSpec(QDateTimePrivate::ShortData, spec))); } else { - clearSetToDaylightStatus(); + // the structure is too small, we need to detach + d = new QDateTimePrivate; + d->ref.ref(); + d->m_status = mergeSpec(0, spec); } } -// Get the DST Status if LocalTime set via msecs -QDateTimePrivate::DaylightStatus QDateTimePrivate::daylightStatus() const +inline QDateTime::Data::Data(const Data &other) + : d(other.d) { - if ((m_status & SetToDaylightTime) == SetToDaylightTime) - return DaylightTime; - if ((m_status & SetToStandardTime) == SetToStandardTime) - return StandardTime; - return UnknownDaylightTime; + if (!isShort()) { + // check if we could shrink + ShortData sd; + sd.msecs = qintptr(d->m_msecs); + if (CanBeSmall && specCanBeSmall(extractSpec(d->m_status)) && sd.msecs == d->m_msecs) { + sd.status = d->m_status | QDateTimePrivate::ShortData; + data = sd; + } else { + // no, have to keep it big + d->ref.ref(); + } + } } -qint64 QDateTimePrivate::toMSecsSinceEpoch() const +inline QDateTime::Data::Data(Data &&other) + : d(other.d) { - switch (m_spec) { - case Qt::OffsetFromUTC: - case Qt::UTC: - return (m_msecs - (m_offsetFromUtc * 1000)); - - case Qt::LocalTime: { - // recalculate the local timezone - DaylightStatus status = daylightStatus(); - return localMSecsToEpochMSecs(m_msecs, &status); + // reset the other to a short state, if we can + if (CanBeSmall) { + Data dummy(Qt::LocalTime); + Q_ASSERT(dummy.isShort()); + other.d = dummy.d; + } else if (!isShort()) { + // can't be small, so do implicit sharing + d->ref.ref(); } +} - case Qt::TimeZone: -#ifdef QT_BOOTSTRAPPED - break; -#else - return zoneMSecsToEpochMSecs(m_msecs, m_timeZone); -#endif +inline QDateTime::Data &QDateTime::Data::operator=(const Data &other) +{ + if (d == other.d) + return *this; + + auto x = d; + d = other.d; + if (!other.isShort()) { + // check if we could shrink + ShortData sd; + sd.msecs = qintptr(other.d->m_msecs); + if (CanBeSmall && specCanBeSmall(extractSpec(other.d->m_status)) && sd.msecs == other.d->m_msecs) { + sd.status = other.d->m_status | QDateTimePrivate::ShortData; + data = sd; + } else { + // no, have to keep it big + other.d->ref.ref(); + } } - Q_UNREACHABLE(); - return 0; + + if (!(CanBeSmall && quintptr(x) & QDateTimePrivate::ShortData) && !x->ref.deref()) + delete x; + return *this; } -// Check the UTC / offsetFromUTC validity -void QDateTimePrivate::checkValidDateTime() +inline QDateTime::Data::~Data() { - switch (m_spec) { - case Qt::OffsetFromUTC: - case Qt::UTC: - // for these, a valid date and a valid time imply a valid QDateTime - if (isValidDate() && isValidTime()) - setValidDateTime(); - else - clearValidDateTime(); - break; - case Qt::TimeZone: - case Qt::LocalTime: - // for these, we need to check whether the timezone is valid and whether - // the time is valid in that timezone. Expensive, but no other option. - refreshDateTime(); - break; - } + if (!isShort() && !d->ref.deref()) + delete d; } -// Refresh the LocalTime validity and offset -void QDateTimePrivate::refreshDateTime() +inline bool QDateTime::Data::isShort() const { - switch (m_spec) { - case Qt::OffsetFromUTC: - case Qt::UTC: - // Always set by setDateTime so just return - return; - case Qt::TimeZone: - case Qt::LocalTime: - break; - } + return CanBeSmall && quintptr(d) & QDateTimePrivate::ShortData; +} - // If not valid date and time then is invalid - if (!isValidDate() || !isValidTime()) { - clearValidDateTime(); - m_offsetFromUtc = 0; - return; - } +inline void QDateTime::Data::detach() +{ + QDateTimePrivate *x; + bool wasShort = isShort(); + if (wasShort) { + // force enlarging + x = new QDateTimePrivate; + x->m_status = QDateTimePrivate::StatusFlag(data.status & ~QDateTimePrivate::ShortData); + x->m_msecs = data.msecs; + } else { + if (d->ref.load() == 1) + return; -#ifndef QT_BOOTSTRAPPED - // If not valid time zone then is invalid - if (m_spec == Qt::TimeZone && !m_timeZone.isValid()) { - clearValidDateTime(); - m_offsetFromUtc = 0; - return; + x = new QDateTimePrivate(*d); } -#endif // QT_BOOTSTRAPPED - // 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 - QDate testDate; - QTime testTime; - qint64 epochMSecs = 0; - if (m_spec == Qt::LocalTime) { - DaylightStatus status = daylightStatus(); - epochMSecs = localMSecsToEpochMSecs(m_msecs, &status, &testDate, &testTime); -#ifndef QT_BOOTSTRAPPED - } else { - epochMSecs = zoneMSecsToEpochMSecs(m_msecs, m_timeZone, &testDate, &testTime); -#endif // QT_BOOTSTRAPPED - } - if (timeToMSecs(testDate, testTime) == m_msecs) { - setValidDateTime(); - // Cache the offset to use in toMSecsSinceEpoch() - m_offsetFromUtc = (m_msecs - epochMSecs) / 1000; - } else { - clearValidDateTime(); - m_offsetFromUtc = 0; - } + x->ref.store(1); + if (!wasShort && !d->ref.deref()) + delete d; + d = x; +} + +inline const QDateTimePrivate *QDateTime::Data::operator->() const +{ + Q_ASSERT(!isShort()); + return d; +} + +inline QDateTimePrivate *QDateTime::Data::operator->() +{ + // should we attempt to detach here? + Q_ASSERT(!isShort()); + Q_ASSERT(d->ref.load() == 1); + return d; +} + +/***************************************************************************** + QDateTimePrivate member functions + *****************************************************************************/ + +Q_NEVER_INLINE +QDateTime::Data QDateTimePrivate::create(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec, + int offsetSeconds) +{ + QDateTime::Data result(toSpec); + setTimeSpec(result, toSpec, offsetSeconds); + setDateTime(result, toDate, toTime); + return result; } #ifndef QT_BOOTSTRAPPED +inline QDateTime::Data QDateTimePrivate::create(const QDate &toDate, const QTime &toTime, + const QTimeZone &toTimeZone) +{ + QDateTime::Data result(Qt::TimeZone); + Q_ASSERT(!result.isShort()); + + result.d->m_status = mergeSpec(result.d->m_status, Qt::TimeZone); + result.d->m_timeZone = toTimeZone; + setDateTime(result, toDate, toTime); + return result; +} + // Convert a TimeZone time expressed in zone msecs encoding into a UTC epoch msecs -qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone &zone, - QDate *localDate, QTime *localTime) +inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone &zone, + QDate *localDate, QTime *localTime) { // Get the effective data from QTimeZone QTimeZonePrivate::Data data = zone.d->dataForLocalTime(zoneMSecs); @@ -2958,8 +3029,8 @@ qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone \sa isValid() */ -QDateTime::QDateTime() - : d(*defaultDateTimePrivate()) +QDateTime::QDateTime() Q_DECL_NOEXCEPT_EXPR(Data::CanBeSmall) + : d(Qt::LocalTime) { } @@ -2970,7 +3041,7 @@ QDateTime::QDateTime() */ QDateTime::QDateTime(const QDate &date) - : d(new QDateTimePrivate(date, QTime(0, 0, 0), Qt::LocalTime, 0)) + : d(QDateTimePrivate::create(date, QTime(0, 0, 0), Qt::LocalTime, 0)) { } @@ -2990,7 +3061,7 @@ QDateTime::QDateTime(const QDate &date) */ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec) - : d(new QDateTimePrivate(date, time, spec, 0)) + : d(QDateTimePrivate::create(date, time, spec, 0)) { } @@ -3013,7 +3084,7 @@ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec) */ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds) - : d(new QDateTimePrivate(date, time, spec, offsetSeconds)) + : d(QDateTimePrivate::create(date, time, spec, offsetSeconds)) { } @@ -3030,7 +3101,7 @@ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, in */ QDateTime::QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone) - : d(new QDateTimePrivate(date, time, timeZone)) + : d(QDateTimePrivate::create(date, time, timeZone)) { } #endif // QT_BOOTSTRAPPED @@ -3038,13 +3109,22 @@ QDateTime::QDateTime(const QDate &date, const QTime &time, const QTimeZone &time /*! Constructs a copy of the \a other datetime. */ - -QDateTime::QDateTime(const QDateTime &other) +QDateTime::QDateTime(const QDateTime &other) Q_DECL_NOTHROW : d(other.d) { } /*! + \since 5.8 + Moves the content of the temporary \a other datetime to this object and + leaves \a other in an unspecified (but proper) state. +*/ +QDateTime::QDateTime(QDateTime &&other) Q_DECL_NOTHROW + : d(std::move(other.d)) +{ +} + +/*! Destroys the datetime. */ QDateTime::~QDateTime() @@ -3056,7 +3136,7 @@ QDateTime::~QDateTime() copy. */ -QDateTime &QDateTime::operator=(const QDateTime &other) +QDateTime &QDateTime::operator=(const QDateTime &other) Q_DECL_NOTHROW { d = other.d; return *this; @@ -3078,7 +3158,9 @@ QDateTime &QDateTime::operator=(const QDateTime &other) bool QDateTime::isNull() const { - return d->isNullDate() && d->isNullTime(); + auto status = getStatus(d); + return !status.testFlag(QDateTimePrivate::ValidDate) && + !status.testFlag(QDateTimePrivate::ValidTime); } /*! @@ -3095,7 +3177,8 @@ bool QDateTime::isNull() const bool QDateTime::isValid() const { - return (d->isValidDateTime()); + auto status = getStatus(d); + return status & QDateTimePrivate::ValidDateTime; } /*! @@ -3106,10 +3189,11 @@ bool QDateTime::isValid() const QDate QDateTime::date() const { - if (d->isNullDate()) + auto status = getStatus(d); + if (!status.testFlag(QDateTimePrivate::ValidDate)) return QDate(); QDate dt; - msecsToTime(d->m_msecs, &dt, 0); + msecsToTime(getMSecs(d), &dt, 0); return dt; } @@ -3121,10 +3205,11 @@ QDate QDateTime::date() const QTime QDateTime::time() const { - if (d->isNullTime()) + auto status = getStatus(d); + if (!status.testFlag(QDateTimePrivate::ValidTime)) return QTime(); QTime tm; - msecsToTime(d->m_msecs, 0, &tm); + msecsToTime(getMSecs(d), 0, &tm); return tm; } @@ -3136,7 +3221,7 @@ QTime QDateTime::time() const Qt::TimeSpec QDateTime::timeSpec() const { - return d->m_spec; + return getSpec(d); } #ifndef QT_BOOTSTRAPPED @@ -3154,7 +3239,7 @@ Qt::TimeSpec QDateTime::timeSpec() const QTimeZone QDateTime::timeZone() const { - switch (d->m_spec) { + switch (getSpec(d)) { case Qt::UTC: return QTimeZone::utc(); case Qt::OffsetFromUTC: @@ -3189,7 +3274,20 @@ QTimeZone QDateTime::timeZone() const int QDateTime::offsetFromUtc() const { - return d->m_offsetFromUtc; + if (!d.isShort()) + return d->m_offsetFromUtc; + if (!isValid()) + return 0; + + auto spec = getSpec(d); + if (spec == Qt::LocalTime) { + // we didn't cache the value, so we need to calculate it now... + qint64 msecs = getMSecs(d); + return (msecs - toMSecsSinceEpoch()) / 1000; + } + + Q_ASSERT(spec == Qt::UTC); + return 0; } /*! @@ -3215,7 +3313,7 @@ int QDateTime::offsetFromUtc() const QString QDateTime::timeZoneAbbreviation() const { - switch (d->m_spec) { + switch (getSpec(d)) { case Qt::UTC: return QTimeZonePrivate::utcQString(); case Qt::OffsetFromUTC: @@ -3224,12 +3322,12 @@ QString QDateTime::timeZoneAbbreviation() const #ifdef QT_BOOTSTRAPPED break; #else - return d->m_timeZone.d->abbreviation(d->toMSecsSinceEpoch()); + return d->m_timeZone.d->abbreviation(toMSecsSinceEpoch()); #endif // QT_BOOTSTRAPPED case Qt::LocalTime: { QString abbrev; - QDateTimePrivate::DaylightStatus status = d->daylightStatus(); - localMSecsToEpochMSecs(d->m_msecs, &status, 0, 0, &abbrev); + auto status = extractDaylightStatus(getStatus(d)); + localMSecsToEpochMSecs(getMSecs(d), &status, 0, 0, &abbrev); return abbrev; } } @@ -3249,7 +3347,7 @@ QString QDateTime::timeZoneAbbreviation() const bool QDateTime::isDaylightTime() const { - switch (d->m_spec) { + switch (getSpec(d)) { case Qt::UTC: case Qt::OffsetFromUTC: return false; @@ -3260,9 +3358,9 @@ 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); + localMSecsToEpochMSecs(getMSecs(d), &status); return (status == QDateTimePrivate::DaylightTime); } } @@ -3278,7 +3376,7 @@ bool QDateTime::isDaylightTime() const void QDateTime::setDate(const QDate &date) { - d->setDateTime(date, time()); + setDateTime(d, date, time()); } /*! @@ -3296,7 +3394,7 @@ void QDateTime::setDate(const QDate &date) void QDateTime::setTime(const QTime &time) { - d->setDateTime(date(), time); + setDateTime(d, date(), time); } /*! @@ -3317,9 +3415,8 @@ void QDateTime::setTime(const QTime &time) void QDateTime::setTimeSpec(Qt::TimeSpec spec) { - QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) - d->setTimeSpec(spec, 0); - d->checkValidDateTime(); + QT_PREPEND_NAMESPACE(setTimeSpec(d, spec, 0)); + checkValidDateTime(d); } /*! @@ -3339,9 +3436,8 @@ void QDateTime::setTimeSpec(Qt::TimeSpec spec) void QDateTime::setOffsetFromUtc(int offsetSeconds) { - QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) - d->setTimeSpec(Qt::OffsetFromUTC, offsetSeconds); - d->checkValidDateTime(); + QT_PREPEND_NAMESPACE(setTimeSpec(d, Qt::OffsetFromUTC, offsetSeconds)); + checkValidDateTime(d); } #ifndef QT_BOOTSTRAPPED @@ -3358,11 +3454,11 @@ void QDateTime::setOffsetFromUtc(int offsetSeconds) void QDateTime::setTimeZone(const QTimeZone &toZone) { - QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) - d->m_spec = Qt::TimeZone; + d.detach(); // always detach + d->m_status = mergeSpec(d->m_status, Qt::TimeZone); d->m_offsetFromUtc = 0; d->m_timeZone = toZone; - d->refreshDateTime(); + refreshDateTime(d); } #endif // QT_BOOTSTRAPPED @@ -3383,7 +3479,28 @@ void QDateTime::setTimeZone(const QTimeZone &toZone) */ qint64 QDateTime::toMSecsSinceEpoch() const { - return d->toMSecsSinceEpoch(); + switch (getSpec(d)) { + case Qt::UTC: + return getMSecs(d); + + case Qt::OffsetFromUTC: + return d->m_msecs - (d->m_offsetFromUtc * 1000); + + case Qt::LocalTime: { + // recalculate the local timezone + auto status = extractDaylightStatus(getStatus(d)); + return localMSecsToEpochMSecs(getMSecs(d), &status); + } + + case Qt::TimeZone: +#ifdef QT_BOOTSTRAPPED + break; +#else + return QDateTimePrivate::zoneMSecsToEpochMSecs(d->m_msecs, d->m_timeZone); +#endif + } + Q_UNREACHABLE(); + return 0; } /*! @@ -3412,7 +3529,7 @@ uint QDateTime::toTime_t() const { if (!isValid()) return uint(-1); - qint64 retval = d->toMSecsSinceEpoch() / 1000; + qint64 retval = toMSecsSinceEpoch() / 1000; if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF)) return uint(-1); return uint(retval); @@ -3434,51 +3551,67 @@ uint QDateTime::toTime_t() const */ void QDateTime::setMSecsSinceEpoch(qint64 msecs) { - QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) + const auto spec = getSpec(d); + auto status = getStatus(d); - d->m_status = 0; - switch (d->m_spec) { + status &= ~QDateTimePrivate::ValidityMask; + switch (spec) { case Qt::UTC: - d->m_msecs = msecs; - d->m_status = d->m_status + status = status | QDateTimePrivate::ValidDate | QDateTimePrivate::ValidTime | QDateTimePrivate::ValidDateTime; break; case Qt::OffsetFromUTC: - d->m_msecs = msecs + (d->m_offsetFromUtc * 1000); - d->m_status = d->m_status + msecs = msecs + (d->m_offsetFromUtc * 1000); + status = status | QDateTimePrivate::ValidDate | QDateTimePrivate::ValidTime | QDateTimePrivate::ValidDateTime; break; case Qt::TimeZone: + Q_ASSERT(!d.isShort()); #ifndef QT_BOOTSTRAPPED // Docs state any LocalTime before 1970-01-01 will *not* have any DST applied // but all affected times afterwards will have DST applied. + d.detach(); if (msecs >= 0) d->m_offsetFromUtc = d->m_timeZone.d->offsetFromUtc(msecs); else d->m_offsetFromUtc = d->m_timeZone.d->standardTimeOffset(msecs); - d->m_msecs = msecs + (d->m_offsetFromUtc * 1000); - d->m_status = d->m_status + msecs = msecs + (d->m_offsetFromUtc * 1000); + status = status | QDateTimePrivate::ValidDate | QDateTimePrivate::ValidTime | QDateTimePrivate::ValidDateTime; - d->refreshDateTime(); #endif // QT_BOOTSTRAPPED break; case Qt::LocalTime: { QDate dt; QTime tm; - QDateTimePrivate::DaylightStatus status; - epochMSecsToLocalTime(msecs, &dt, &tm, &status); - d->setDateTime(dt, tm); - d->setDaylightStatus(status); - d->refreshDateTime(); + QDateTimePrivate::DaylightStatus dstStatus; + epochMSecsToLocalTime(msecs, &dt, &tm, &dstStatus); + setDateTime(d, dt, tm); + msecs = getMSecs(d); + status = mergeDaylightStatus(getStatus(d), dstStatus); break; } } + + ShortData sd; + sd.msecs = msecs; + if (d.isShort() && sd.msecs == msecs) { + // we can keep short + sd.status = status; + d.data = sd; + } else { + d.detach(); + d->m_status = status; + d->m_msecs = msecs; + } + + if (spec == Qt::LocalTime || spec == Qt::TimeZone) + refreshDateTime(d); } /*! @@ -3565,13 +3698,13 @@ QString QDateTime::toString(Qt::DateFormat format) const return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: { buf = QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy hh:mm:ss ")); - buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc); + buf += toOffsetString(Qt::TextDate, offsetFromUtc()); return buf; } default: #ifndef QT_NO_TEXTDATE case Qt::TextDate: { - const QPair<QDate, QTime> p = d->getDateTime(); + const QPair<QDate, QTime> p = getDateTime(d); const QDate &dt = p.first; const QTime &tm = p.second; //We cant use date.toString(Qt::TextDate) as we need to insert the time before the year @@ -3582,14 +3715,14 @@ QString QDateTime::toString(Qt::DateFormat format) const .arg(dt.year()); if (timeSpec() != Qt::LocalTime) { buf += QStringLiteral(" GMT"); - if (d->m_spec == Qt::OffsetFromUTC) - buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc); + if (getSpec(d) == Qt::OffsetFromUTC) + buf += toOffsetString(Qt::TextDate, offsetFromUtc()); } return buf; } #endif case Qt::ISODate: { - const QPair<QDate, QTime> p = d->getDateTime(); + const QPair<QDate, QTime> p = getDateTime(d); const QDate &dt = p.first; const QTime &tm = p.second; buf = dt.toString(Qt::ISODate); @@ -3597,12 +3730,12 @@ QString QDateTime::toString(Qt::DateFormat format) const return QString(); // failed to convert buf += QLatin1Char('T'); buf += tm.toString(Qt::ISODate); - switch (d->m_spec) { + switch (getSpec(d)) { case Qt::UTC: buf += QLatin1Char('Z'); break; case Qt::OffsetFromUTC: - buf += toOffsetString(Qt::ISODate, d->m_offsetFromUtc); + buf += toOffsetString(Qt::ISODate, offsetFromUtc()); break; default: break; @@ -3691,12 +3824,7 @@ QString QDateTime::toString(const QString& format) const } #endif //QT_NO_DATESTRING -static void massageAdjustedDateTime(Qt::TimeSpec spec, -#ifndef QT_BOOTSTRAPPED - const QTimeZone &zone, -#endif // QT_BOOTSTRAPPED - QDate *date, - QTime *time) +static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date, QTime *time) { /* If we have just adjusted to a day with a DST transition, our given time @@ -3706,24 +3834,20 @@ static void massageAdjustedDateTime(Qt::TimeSpec spec, 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 = getSpec(d); if (spec == Qt::LocalTime) { QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime; localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time); #ifndef QT_BOOTSTRAPPED } else if (spec == Qt::TimeZone) { - QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time), zone, date, time); + QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time), d->m_timeZone, date, time); #endif // QT_BOOTSTRAPPED } } -#ifdef QT_BOOTSTRAPPED // Avoid duplicate #if-ery in uses. -#define MASSAGEADJUSTEDDATETIME(s, z, d, t) massageAdjustedDateTime(s, d, t) -#else -#define MASSAGEADJUSTEDDATETIME(s, z, d, t) massageAdjustedDateTime(s, z, d, t) -#endif // QT_BOOTSTRAPPED /*! Returns a QDateTime object containing a datetime \a ndays days @@ -3742,12 +3866,12 @@ static void massageAdjustedDateTime(Qt::TimeSpec spec, QDateTime QDateTime::addDays(qint64 ndays) const { QDateTime dt(*this); - QPair<QDate, QTime> p = d->getDateTime(); + QPair<QDate, QTime> p = getDateTime(d); QDate &date = p.first; QTime &time = p.second; date = date.addDays(ndays); - MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time); - dt.d->setDateTime(date, time); + massageAdjustedDateTime(dt.d, &date, &time); + setDateTime(dt.d, date, time); return dt; } @@ -3768,12 +3892,12 @@ QDateTime QDateTime::addDays(qint64 ndays) const QDateTime QDateTime::addMonths(int nmonths) const { QDateTime dt(*this); - QPair<QDate, QTime> p = d->getDateTime(); + QPair<QDate, QTime> p = getDateTime(d); QDate &date = p.first; QTime &time = p.second; date = date.addMonths(nmonths); - MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time); - dt.d->setDateTime(date, time); + massageAdjustedDateTime(dt.d, &date, &time); + setDateTime(dt.d, date, time); return dt; } @@ -3794,15 +3918,14 @@ QDateTime QDateTime::addMonths(int nmonths) const QDateTime QDateTime::addYears(int nyears) const { QDateTime dt(*this); - QPair<QDate, QTime> p = d->getDateTime(); + QPair<QDate, QTime> p = getDateTime(d); QDate &date = p.first; QTime &time = p.second; date = date.addYears(nyears); - MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time); - dt.d->setDateTime(date, time); + massageAdjustedDateTime(dt.d, &date, &time); + setDateTime(dt.d, date, time); return dt; } -#undef MASSAGEADJUSTEDDATETIME /*! Returns a QDateTime object containing a datetime \a s seconds @@ -3834,12 +3957,25 @@ QDateTime QDateTime::addMSecs(qint64 msecs) const return QDateTime(); QDateTime dt(*this); - if (d->m_spec == Qt::LocalTime || d->m_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(d->toMSecsSinceEpoch() + msecs); - else + dt.setMSecsSinceEpoch(toMSecsSinceEpoch() + msecs); + } else { // No need to convert, just add on - dt.d->m_msecs = dt.d->m_msecs + msecs; + if (d.isShort()) { + // need to check if we need to enlarge first + msecs += dt.d.data.msecs; + dt.d.data.msecs = qintptr(msecs); + if (dt.d.data.msecs != msecs) { + dt.d.detach(); + dt.d->m_msecs = msecs; + } + } else { + dt.d.detach(); + dt.d->m_msecs += msecs; + } + } return dt; } @@ -3905,7 +4041,7 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const if (!isValid() || !other.isValid()) return 0; - return other.d->toMSecsSinceEpoch() - d->toMSecsSinceEpoch(); + return other.toMSecsSinceEpoch() - toMSecsSinceEpoch(); } /*! @@ -3928,7 +4064,7 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const { - if (d->m_spec == spec && (spec == Qt::UTC || spec == Qt::LocalTime)) + if (getSpec(d) == spec && (spec == Qt::UTC || spec == Qt::LocalTime)) return *this; if (!isValid()) { @@ -3937,7 +4073,7 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const return ret; } - return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), spec, 0); + return fromMSecsSinceEpoch(toMSecsSinceEpoch(), spec, 0); } /*! @@ -3955,7 +4091,8 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const { - if (d->m_spec == Qt::OffsetFromUTC && d->m_offsetFromUtc == offsetSeconds) + if (getSpec(d) == Qt::OffsetFromUTC + && d->m_offsetFromUtc == offsetSeconds) return *this; if (!isValid()) { @@ -3964,7 +4101,7 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const return ret; } - return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds); + return fromMSecsSinceEpoch(toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds); } #ifndef QT_BOOTSTRAPPED @@ -3978,7 +4115,7 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const { - if (d->m_spec == Qt::TimeZone && d->m_timeZone == timeZone) + if (getSpec(d) == Qt::TimeZone && d->m_timeZone == timeZone) return *this; if (!isValid()) { @@ -3987,7 +4124,7 @@ QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const return ret; } - return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), timeZone); + return fromMSecsSinceEpoch(toMSecsSinceEpoch(), timeZone); } #endif // QT_BOOTSTRAPPED @@ -4000,10 +4137,9 @@ QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const bool QDateTime::operator==(const QDateTime &other) const { - if (d->m_spec == Qt::LocalTime - && other.d->m_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 getMSecs(d) == getMSecs(other.d); } // Convert to UTC and compare return (toMSecsSinceEpoch() == other.toMSecsSinceEpoch()); @@ -4028,10 +4164,9 @@ bool QDateTime::operator==(const QDateTime &other) const bool QDateTime::operator<(const QDateTime &other) const { - if (d->m_spec == Qt::LocalTime - && other.d->m_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 getMSecs(d) < getMSecs(other.d); } // Convert to UTC and compare return (toMSecsSinceEpoch() < other.toMSecsSinceEpoch()); @@ -4109,9 +4244,6 @@ QTime QTime::currentTime() memset(&st, 0, sizeof(SYSTEMTIME)); GetLocalTime(&st); ct.setHMS(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); -#if defined(Q_OS_WINCE) - ct.startTick = GetTickCount() % MSECS_PER_DAY; -#endif return ct; } @@ -4186,39 +4318,6 @@ qint64 QDateTime::currentMSecsSinceEpoch() Q_DECL_NOTHROW #error "What system is this?" #endif -/*! \fn QDateTime QDateTime::fromCFDate(CFDateRef date) - \since 5.5 - - Constructs a new QDateTime containing a copy of the CFDate \a date. - - \sa toCFDate() -*/ - -/*! \fn CFDateRef QDateTime::toCFDate() const - \since 5.5 - - Creates a CFDate from a QDateTime. The caller owns the CFDate object - and is responsible for releasing it. - - \sa fromCFDate() -*/ - -/*! \fn QDateTime QDateTime::fromNSDate(const NSDate *date) - \since 5.5 - - Constructs a new QDateTime containing a copy of the NSDate \a date. - - \sa toNSDate() -*/ - -/*! \fn NSDate QDateTime::toNSDate() const - \since 5.5 - - Creates an NSDate from a QDateTime. The NSDate object is autoreleased. - - \sa fromNSDate() -*/ - /*! \since 4.2 @@ -4310,7 +4409,7 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs) QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetSeconds) { QDateTime dt; - dt.d->setTimeSpec(spec, offsetSeconds); + QT_PREPEND_NAMESPACE(setTimeSpec(dt.d, spec, offsetSeconds)); dt.setMSecsSinceEpoch(msecs); return dt; } @@ -4817,7 +4916,7 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) if (out.version() >= QDataStream::Qt_5_2) { // In 5.2 we switched to using Qt::TimeSpec and added offset support - dateAndTime = dateTime.d->getDateTime(); + dateAndTime = getDateTime(dateTime.d); out << dateAndTime << qint8(dateTime.timeSpec()); if (dateTime.timeSpec() == Qt::OffsetFromUTC) out << qint32(dateTime.offsetFromUtc()); @@ -4832,13 +4931,13 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) // This approach is wrong and should not be used again; it breaks // the guarantee that a deserialised local datetime is the same time // of day, regardless of which timezone it was serialised in. - dateAndTime = (dateTime.isValid() ? dateTime.toUTC() : dateTime).d->getDateTime(); + dateAndTime = getDateTime((dateTime.isValid() ? dateTime.toUTC() : dateTime).d); out << dateAndTime << qint8(dateTime.timeSpec()); } else if (out.version() >= QDataStream::Qt_4_0) { // From 4.0 to 5.1 (except 5.0) we used QDateTimePrivate::Spec - dateAndTime = dateTime.d->getDateTime(); + dateAndTime = getDateTime(dateTime.d); out << dateAndTime; switch (dateTime.timeSpec()) { case Qt::UTC: @@ -4858,7 +4957,7 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) } else { // version < QDataStream::Qt_4_0 // Before 4.0 there was no TimeSpec, only Qt::LocalTime was supported - dateAndTime = dateTime.d->getDateTime(); + dateAndTime = getDateTime(dateTime.d); out << dateAndTime; } diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index ee3be5553b..0af13dd45f 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -46,11 +47,9 @@ #include <limits> -#ifdef Q_OS_MAC +#if defined(Q_OS_DARWIN) || defined(Q_QDOC) Q_FORWARD_DECLARE_CF_TYPE(CFDate); -# ifdef __OBJC__ Q_FORWARD_DECLARE_OBJC_CLASS(NSDate); -# endif #endif QT_BEGIN_NAMESPACE @@ -148,15 +147,9 @@ Q_DECLARE_TYPEINFO(QDate, Q_MOVABLE_TYPE); class Q_CORE_EXPORT QTime { explicit Q_DECL_CONSTEXPR QTime(int ms) : mds(ms) -#if defined(Q_OS_WINCE) - , startTick(NullTime) -#endif {} public: Q_DECL_CONSTEXPR QTime(): mds(NullTime) -#if defined(Q_OS_WINCE) - , startTick(NullTime) -#endif {} QTime(int h, int m, int s = 0, int ms = 0); @@ -202,9 +195,6 @@ private: enum TimeFlag { NullTime = -1 }; Q_DECL_CONSTEXPR inline int ds() const { return mds == -1 ? 0 : mds; } int mds; -#if defined(Q_OS_WINCE) - int startTick; -#endif friend class QDateTime; friend class QDateTimePrivate; @@ -219,8 +209,45 @@ class QDateTimePrivate; class Q_CORE_EXPORT QDateTime { + // ### Qt 6: revisit the optimization + struct ShortData { +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + quintptr status : 8; +#endif + // note: this is only 24 bits on 32-bit systems... + qintptr msecs : sizeof(void *) * 8 - 8; + +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + quintptr status : 8; +#endif + }; + + union Data { + enum { + // To be of any use, we need at least 60 years around 1970, which + // is 1,893,456,000,000 ms. That requires 41 bits to store, plus + // the sign bit. With the status byte, the minimum size is 50 bits. + CanBeSmall = sizeof(ShortData) * 8 > 50 + }; + + Data(Qt::TimeSpec); + Data(const Data &other); + Data(Data &&other); + Data &operator=(const Data &other); + ~Data(); + + bool isShort() const; + void detach(); + + const QDateTimePrivate *operator->() const; + QDateTimePrivate *operator->(); + + QDateTimePrivate *d; + ShortData data; + }; + public: - QDateTime(); + QDateTime() Q_DECL_NOEXCEPT_EXPR(Data::CanBeSmall); explicit QDateTime(const QDate &); QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime); // ### Qt 6: Merge with above with default offsetSeconds = 0 @@ -228,15 +255,16 @@ public: #ifndef QT_BOOTSTRAPPED QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone); #endif // QT_BOOTSTRAPPED - QDateTime(const QDateTime &other); + QDateTime(const QDateTime &other) Q_DECL_NOTHROW; + QDateTime(QDateTime &&other) Q_DECL_NOTHROW; ~QDateTime(); #ifdef Q_COMPILER_RVALUE_REFS QDateTime &operator=(QDateTime &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif - QDateTime &operator=(const QDateTime &other); + QDateTime &operator=(const QDateTime &other) Q_DECL_NOTHROW; - void swap(QDateTime &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + void swap(QDateTime &other) Q_DECL_NOTHROW { qSwap(d.d, other.d.d); } bool isNull() const; bool isValid() const; @@ -322,22 +350,17 @@ public: #endif static qint64 currentMSecsSinceEpoch() Q_DECL_NOTHROW; -#if defined(Q_OS_MAC) || defined(Q_QDOC) +#if defined(Q_OS_DARWIN) || defined(Q_QDOC) static QDateTime fromCFDate(CFDateRef date); CFDateRef toCFDate() const Q_DECL_CF_RETURNS_RETAINED; -# if defined(__OBJC__) || defined(Q_QDOC) static QDateTime fromNSDate(const NSDate *date); NSDate *toNSDate() const Q_DECL_NS_RETURNS_AUTORELEASED; -# endif #endif private: friend class QDateTimePrivate; - // ### Qt6: Using a private here has high impact on runtime - // on users such as QFileInfo. In Qt 6, the data members - // should be inlined. - QSharedDataPointer<QDateTimePrivate> d; + Data d; #ifndef QT_NO_DATASTREAM friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &); diff --git a/src/corelib/tools/qdatetime_mac.mm b/src/corelib/tools/qdatetime_mac.mm deleted file mode 100644 index d61ea28636..0000000000 --- a/src/corelib/tools/qdatetime_mac.mm +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2014 Petroules Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdatetime.h" - -#import <Foundation/Foundation.h> - -QT_BEGIN_NAMESPACE - -QDateTime QDateTime::fromCFDate(CFDateRef date) -{ - if (!date) - return QDateTime(); - return QDateTime::fromMSecsSinceEpoch(static_cast<qint64>((CFDateGetAbsoluteTime(date) - + kCFAbsoluteTimeIntervalSince1970) * 1000)); -} - -CFDateRef QDateTime::toCFDate() const -{ - return CFDateCreate(kCFAllocatorDefault, (static_cast<CFAbsoluteTime>(toMSecsSinceEpoch()) - / 1000) - kCFAbsoluteTimeIntervalSince1970); -} - -QDateTime QDateTime::fromNSDate(const NSDate *date) -{ - if (!date) - return QDateTime(); - return QDateTime::fromMSecsSinceEpoch(static_cast<qint64>([date timeIntervalSince1970] * 1000)); -} - -NSDate *QDateTime::toNSDate() const -{ - return [NSDate - dateWithTimeIntervalSince1970:static_cast<NSTimeInterval>(toMSecsSinceEpoch()) / 1000]; -} - -QT_END_NAMESPACE diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h index 104cbccbd4..c4d00c99f9 100644 --- a/src/corelib/tools/qdatetime_p.h +++ b/src/corelib/tools/qdatetime_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -60,9 +61,13 @@ QT_BEGIN_NAMESPACE -class QDateTimePrivate : public QSharedData +class QDateTimePrivate { public: + // forward the declarations from QDateTime (this makes them public) + typedef QDateTime::ShortData QDateTimeShortData; + typedef QDateTime::Data QDateTimeData; + // Never change or delete this enum, it is required for backwards compatible // serialization of QDateTime before 5.2, so is essentially public API enum Spec { @@ -76,7 +81,6 @@ public: // Daylight Time Status enum DaylightStatus { - NoDaylightTime = -2, UnknownDaylightTime = -1, StandardTime = 0, DaylightTime = 1 @@ -84,62 +88,46 @@ public: // Status of date/time enum StatusFlag { - NullDate = 0x01, - NullTime = 0x02, - ValidDate = 0x04, // just the date field - ValidTime = 0x08, // just the time field - ValidDateTime = 0x10, // the whole object (including timezone) + ShortData = 0x01, + + ValidDate = 0x02, + ValidTime = 0x04, + ValidDateTime = 0x08, + + TimeSpecMask = 0x30, + SetToStandardTime = 0x40, SetToDaylightTime = 0x80 }; Q_DECLARE_FLAGS(StatusFlags, StatusFlag) + enum { + TimeSpecShift = 4, + ValidityMask = ValidDate | ValidTime | ValidDateTime, + DaylightMask = SetToStandardTime | SetToDaylightTime + }; + QDateTimePrivate() : m_msecs(0), - m_spec(Qt::LocalTime), + m_status(StatusFlag(Qt::LocalTime << TimeSpecShift)), m_offsetFromUtc(0), - m_status(NullDate | NullTime) - {} + ref(0) + { + } - QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec, - int offsetSeconds); + static QDateTime::Data create(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec, + int offsetSeconds); #ifndef QT_BOOTSTRAPPED - QDateTimePrivate(const QDate &toDate, const QTime &toTime, const QTimeZone & timeZone); + static QDateTime::Data create(const QDate &toDate, const QTime &toTime, const QTimeZone & timeZone); #endif // QT_BOOTSTRAPPED - // ### XXX: when the tooling situation improves, look at fixing the padding. - // 4 bytes padding - qint64 m_msecs; - Qt::TimeSpec m_spec; + StatusFlags m_status; int m_offsetFromUtc; + mutable QAtomicInt ref; #ifndef QT_BOOTSTRAPPED QTimeZone m_timeZone; #endif // QT_BOOTSTRAPPED - StatusFlags m_status; - - void setTimeSpec(Qt::TimeSpec spec, int offsetSeconds); - void setDateTime(const QDate &date, const QTime &time); - QPair<QDate, QTime> getDateTime() const; - - void setDaylightStatus(DaylightStatus status); - DaylightStatus daylightStatus() const; - - // Returns msecs since epoch, assumes offset value is current - inline qint64 toMSecsSinceEpoch() const; - - void checkValidDateTime(); - void refreshDateTime(); - - // Get/set date and time status - inline bool isNullDate() const { return m_status & NullDate; } - inline bool isNullTime() const { return m_status & NullTime; } - 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); } #ifndef QT_BOOTSTRAPPED static qint64 zoneMSecsToEpochMSecs(qint64 msecs, const QTimeZone &zone, diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp index 734aaf80f2..520126d262 100644 --- a/src/corelib/tools/qelapsedtimer_win.cpp +++ b/src/corelib/tools/qelapsedtimer_win.cpp @@ -40,35 +40,21 @@ #include "qelapsedtimer.h" #include <qt_windows.h> -typedef ULONGLONG (WINAPI *PtrGetTickCount64)(void); -#if defined(Q_OS_WINRT) - static const PtrGetTickCount64 ptrGetTickCount64 = &GetTickCount64; -#else - static PtrGetTickCount64 ptrGetTickCount64 = 0; -#endif - QT_BEGIN_NAMESPACE // Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable static quint64 counterFrequency = 0; -static void resolveLibs() +static void resolveCounterFrequency() { static bool done = false; if (done) return; -#if !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) - // try to get GetTickCount64 from the system - HMODULE kernel32 = GetModuleHandleW(L"kernel32"); - if (!kernel32) - return; - ptrGetTickCount64 = (PtrGetTickCount64)GetProcAddress(kernel32, "GetTickCount64"); -#endif // !Q_OS_WINRT && !Q_OS_WINCE - // Retrieve the number of high-resolution performance counter ticks per second LARGE_INTEGER frequency; if (!QueryPerformanceFrequency(&frequency)) { + qFatal("QueryPerformanceFrequency failed, even though Microsoft documentation promises it wouldn't."); counterFrequency = 0; } else { counterFrequency = frequency.QuadPart; @@ -92,35 +78,20 @@ static inline qint64 ticksToNanoseconds(qint64 ticks) static quint64 getTickCount() { - resolveLibs(); + resolveCounterFrequency(); // This avoids a division by zero and disables the high performance counter if it's not available if (counterFrequency > 0) { LARGE_INTEGER counter; - if (QueryPerformanceCounter(&counter)) { - return counter.QuadPart; - } else { - qWarning("QueryPerformanceCounter failed, although QueryPerformanceFrequency succeeded."); - return 0; - } + bool ok = QueryPerformanceCounter(&counter); + Q_ASSERT_X(ok, "QElapsedTimer::start()", + "QueryPerformanceCounter failed, although QueryPerformanceFrequency succeeded."); + Q_UNUSED(ok); + return counter.QuadPart; } -#ifndef Q_OS_WINRT - if (ptrGetTickCount64) - return ptrGetTickCount64(); - - static quint32 highdword = 0; - static quint32 lastval = 0; - quint32 val = GetTickCount(); - if (val < lastval) - ++highdword; - lastval = val; - return val | (quint64(highdword) << 32); -#else // !Q_OS_WINRT - // ptrGetTickCount64 is always set on WinRT but GetTickCount is not available - return ptrGetTickCount64(); -#endif // Q_OS_WINRT + return GetTickCount64(); } quint64 qt_msectime() @@ -130,7 +101,7 @@ quint64 qt_msectime() QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW { - resolveLibs(); + resolveCounterFrequency(); if (counterFrequency > 0) return PerformanceCounter; diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index b004f74be9..8942292a3d 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -214,6 +214,14 @@ QT_BEGIN_NAMESPACE Returns this line translated the distance specified by \a dx and \a dy. */ +/*! + \fn QPoint QLine::center() const + + \since 5.8 + + Returns the center point of this line. This is equivalent to + (p1() + p2()) / 2, except it will never overflow. +*/ /*! \fn void QLine::setP1(const QPoint &p1) @@ -351,6 +359,12 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) translate() function, and can be traversed using the pointAt() function. + \section1 Constraints + + QLine is limited to the minimum and maximum values for the + \c int type. Operations on a QLine that could potentially result + in values outside this range will result in undefined behavior. + \sa QLine, QPolygonF, QRectF */ @@ -711,6 +725,15 @@ QLineF::IntersectType QLineF::intersect(const QLineF &l, QPointF *intersectionPo */ /*! + \fn QPointF QLineF::center() const + + \since 5.8 + + Returns the center point of this line. This is equivalent to + 0.5 * p1() + 0.5 * p2(). +*/ + +/*! \fn void QLineF::setP1(const QPointF &p1) \since 4.4 diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h index 819dd3fd3b..5b5ca3b4c8 100644 --- a/src/corelib/tools/qline.h +++ b/src/corelib/tools/qline.h @@ -76,6 +76,8 @@ public: Q_DECL_CONSTEXPR inline QLine translated(const QPoint &p) const Q_REQUIRED_RESULT; Q_DECL_CONSTEXPR inline QLine translated(int dx, int dy) const Q_REQUIRED_RESULT; + Q_DECL_CONSTEXPR inline QPoint center() const Q_REQUIRED_RESULT; + inline void setP1(const QPoint &p1); inline void setP2(const QPoint &p2); inline void setPoints(const QPoint &p1, const QPoint &p2); @@ -165,6 +167,11 @@ Q_DECL_CONSTEXPR inline QLine QLine::translated(int adx, int ady) const return translated(QPoint(adx, ady)); } +Q_DECL_CONSTEXPR inline QPoint QLine::center() const +{ + return QPoint(int((qint64(pt1.x()) + pt2.x()) / 2), int((qint64(pt1.y()) + pt2.y()) / 2)); +} + inline void QLine::setP1(const QPoint &aP1) { pt1 = aP1; @@ -253,6 +260,8 @@ public: Q_DECL_CONSTEXPR inline QLineF translated(const QPointF &p) const Q_REQUIRED_RESULT; Q_DECL_CONSTEXPR inline QLineF translated(qreal dx, qreal dy) const Q_REQUIRED_RESULT; + Q_DECL_CONSTEXPR inline QPointF center() const Q_REQUIRED_RESULT; + inline void setP1(const QPointF &p1); inline void setP2(const QPointF &p2); inline void setPoints(const QPointF &p1, const QPointF &p2); @@ -357,6 +366,11 @@ Q_DECL_CONSTEXPR inline QLineF QLineF::translated(qreal adx, qreal ady) const return translated(QPointF(adx, ady)); } +Q_DECL_CONSTEXPR inline QPointF QLineF::center() const +{ + return QPointF(0.5 * pt1.x() + 0.5 * pt2.x(), 0.5 * pt1.y() + 0.5 * pt2.y()); +} + inline void QLineF::setLength(qreal len) { if (isNull()) diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 90ed5072e7..c7f27abdd6 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -118,7 +118,10 @@ struct Q_CORE_EXPORT QListData { }; template <typename T> -class QList : public QListSpecialMethods<T> +class QList +#ifndef Q_QDOC + : public QListSpecialMethods<T> +#endif { public: struct MemoryLayout diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index ea5d74d9bb..7809c513d6 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -61,7 +61,6 @@ #include "qvariant.h" #include "qstringbuilder.h" #include "private/qnumeric_p.h" -#include "private/qsystemlibrary_p.h" #ifdef Q_OS_WIN # include <qt_windows.h> # include <time.h> diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm index 4b1d190705..4f6efc8832 100644 --- a/src/corelib/tools/qlocale_mac.mm +++ b/src/corelib/tools/qlocale_mac.mm @@ -390,9 +390,6 @@ static QString macFormatCurrency(const QSystemLocale::CurrencyToStringArgument & static QVariant macQuoteString(QSystemLocale::QueryType type, const QStringRef &str) { - if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_6) - return QVariant(); - QString begin, end; QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent(); switch (type) { diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp index 88bfada515..f8b9f86ac6 100644 --- a/src/corelib/tools/qlocale_win.cpp +++ b/src/corelib/tools/qlocale_win.cpp @@ -44,9 +44,6 @@ #include "qstringlist.h" #include "qvariant.h" #include "qdatetime.h" - -#include "private/qsystemlibrary_p.h" - #include "qdebug.h" #ifdef Q_OS_WIN @@ -67,7 +64,6 @@ QT_BEGIN_NAMESPACE #ifndef Q_OS_WINRT static QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT); -static const char *winLangCodeToIsoName(int code); static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT); static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT); #else // !Q_OS_WINRT @@ -600,50 +596,32 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS QVariant QSystemLocalePrivate::uiLanguages() { - if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) { - typedef BOOL (WINAPI *GetUserPreferredUILanguagesFunc) ( - DWORD dwFlags, - PULONG pulNumLanguages, - PWSTR pwszLanguagesBuffer, - PULONG pcchLanguagesBuffer); - static GetUserPreferredUILanguagesFunc GetUserPreferredUILanguages_ptr = 0; #ifndef Q_OS_WINRT - if (!GetUserPreferredUILanguages_ptr) { - QSystemLibrary lib(QLatin1String("kernel32")); - if (lib.load()) - GetUserPreferredUILanguages_ptr = (GetUserPreferredUILanguagesFunc)lib.resolve("GetUserPreferredUILanguages"); - } -#endif // !Q_OS_WINRT - if (GetUserPreferredUILanguages_ptr) { - unsigned long cnt = 0; - QVarLengthArray<wchar_t, 64> buf(64); - unsigned long size = buf.size(); - if (!GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size)) { - size = 0; - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && - GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, NULL, &size)) { - buf.resize(size); - if (!GetUserPreferredUILanguages_ptr(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size)) - return QStringList(); - } - } - QStringList result; - result.reserve(cnt); - const wchar_t *str = buf.constData(); - for (; cnt > 0; --cnt) { - QString s = QString::fromWCharArray(str); - if (s.isEmpty()) - break; // something is wrong - result.append(s); - str += s.size()+1; - } - return result; + unsigned long cnt = 0; + QVarLengthArray<wchar_t, 64> buf(64); +# if !defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE) // Not present in MinGW 4.9/bootstrap builds. + unsigned long size = buf.size(); + if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size)) { + size = 0; + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && + GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &cnt, NULL, &size)) { + buf.resize(size); + if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &cnt, buf.data(), &size)) + return QStringList(); } } - -#ifndef Q_OS_WINRT - // old Windows before Vista - return QStringList(QString::fromLatin1(winLangCodeToIsoName(GetUserDefaultUILanguage()))); +# endif // !QT_BOOTSTRAPPED && !QT_BUILD_QMAKE + QStringList result; + result.reserve(cnt); + const wchar_t *str = buf.constData(); + for (; cnt > 0; --cnt) { + QString s = QString::fromWCharArray(str); + if (s.isEmpty()) + break; // something is wrong + result.append(s); + str += s.size() + 1; + } + return result; #else // !Q_OS_WINRT QStringList result; ComPtr<ABI::Windows::Globalization::IApplicationLanguagesStatics> appLanguagesStatics; @@ -1161,19 +1139,16 @@ static QByteArray getWinLocaleName(LPWSTR id) } } -#if defined(Q_OS_WINCE) - result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID()); -#else // !Q_OS_WINCE -# ifndef Q_OS_WINRT +#ifndef Q_OS_WINRT if (id == LOCALE_USER_DEFAULT) id = GetUserDefaultLCID(); -# else // !Q_OS_WINRT +#else // !Q_OS_WINRT WCHAR lcName[LOCALE_NAME_MAX_LENGTH]; if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) { GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH); id = lcName; } -# endif // Q_OS_WINRT +#endif // Q_OS_WINRT QString resultuage = winIso639LangName(id); QString country = winIso3116CtryName(id); result = resultuage.toLatin1(); @@ -1181,7 +1156,6 @@ static QByteArray getWinLocaleName(LPWSTR id) result += '_'; result += country.toLatin1(); } -#endif // !Q_OS_WINCE return result; } diff --git a/src/corelib/tools/qrect.h b/src/corelib/tools/qrect.h index b376b6b999..8ce668f8ec 100644 --- a/src/corelib/tools/qrect.h +++ b/src/corelib/tools/qrect.h @@ -48,6 +48,10 @@ #error qrect.h must be included before any header file that defines topLeft #endif +#if defined(Q_OS_DARWIN) +struct CGRect; +#endif + QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QRect @@ -149,6 +153,10 @@ public: friend Q_DECL_CONSTEXPR inline bool operator==(const QRect &, const QRect &) Q_DECL_NOTHROW; friend Q_DECL_CONSTEXPR inline bool operator!=(const QRect &, const QRect &) Q_DECL_NOTHROW; +#if defined(Q_OS_DARWIN) || defined(Q_QDOC) + CGRect toCGRect() const Q_DECL_NOTHROW Q_REQUIRED_RESULT; +#endif + private: int x1; int y1; @@ -604,6 +612,11 @@ public: Q_DECL_CONSTEXPR inline QRect toRect() const Q_DECL_NOTHROW Q_REQUIRED_RESULT; QRect toAlignedRect() const Q_DECL_NOTHROW Q_REQUIRED_RESULT; +#if defined(Q_OS_DARWIN) || defined(Q_QDOC) + static QRectF fromCGRect(CGRect rect) Q_DECL_NOTHROW Q_REQUIRED_RESULT; + CGRect toCGRect() const Q_DECL_NOTHROW Q_REQUIRED_RESULT; +#endif + private: qreal xp; qreal yp; diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 1a37e0bc9c..67d11660e1 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -193,6 +193,48 @@ QT_BEGIN_NAMESPACE */ /*! + \fn bool operator==(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) + \relates QScopedPointer + \since 5.8 + + Returns \c true if the scoped pointer \a lhs is a null pointer. + + \sa QScopedPointer::isNull() +*/ + +/*! + \fn bool operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) + \relates QScopedPointer + \since 5.8 + + Returns \c true if the scoped pointer \a rhs is a null pointer. + + \sa QScopedPointer::isNull() +*/ + +/*! + \fn bool operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) + \relates QScopedPointer + \since 5.8 + + Returns \c true if the scoped pointer \a lhs is a valid (i.e. a non-null) + pointer. + + \sa QScopedPointer::isNull() +*/ + +/*! + \fn bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) + \relates QScopedPointer + \since 5.8 + + Returns \c true if the scoped pointer \a rhs is a valid (i.e. a non-null) + pointer. + + \sa QScopedPointer::isNull() +*/ + +/*! \fn bool QScopedPointer::isNull() const Returns \c true if this object is holding a pointer that is \c null. diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h index 3e6af97a33..92d7df6e5d 100644 --- a/src/corelib/tools/qscopedpointer.h +++ b/src/corelib/tools/qscopedpointer.h @@ -97,7 +97,7 @@ class QScopedPointer { typedef T *QScopedPointer:: *RestrictedBool; public: - explicit inline QScopedPointer(T *p = Q_NULLPTR) : d(p) + explicit QScopedPointer(T *p = Q_NULLPTR) Q_DECL_NOTHROW : d(p) { } @@ -113,13 +113,12 @@ public: return *d; } - inline T *operator->() const + T *operator->() const Q_DECL_NOTHROW { - Q_ASSERT(d); return d; } - inline bool operator!() const + bool operator!() const Q_DECL_NOTHROW { return !d; } @@ -130,23 +129,23 @@ public: return isNull() ? Q_NULLPTR : &QScopedPointer::d; } #else - inline operator RestrictedBool() const + operator RestrictedBool() const Q_DECL_NOTHROW { return isNull() ? Q_NULLPTR : &QScopedPointer::d; } #endif - inline T *data() const + T *data() const Q_DECL_NOTHROW { return d; } - inline bool isNull() const + bool isNull() const Q_DECL_NOTHROW { return !d; } - inline void reset(T *other = Q_NULLPTR) + void reset(T *other = Q_NULLPTR) Q_DECL_NOEXCEPT_EXPR(noexcept(Cleanup::cleanup(std::declval<T *>()))) { if (d == other) return; @@ -155,7 +154,7 @@ public: Cleanup::cleanup(oldD); } - inline T *take() + T *take() Q_DECL_NOTHROW { T *oldD = d; d = Q_NULLPTR; @@ -177,18 +176,42 @@ private: }; template <class T, class Cleanup> -inline bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) +inline bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW { return lhs.data() == rhs.data(); } template <class T, class Cleanup> -inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) +inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW { return lhs.data() != rhs.data(); } template <class T, class Cleanup> +inline bool operator==(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) Q_DECL_NOTHROW +{ + return lhs.isNull(); +} + +template <class T, class Cleanup> +inline bool operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW +{ + return rhs.isNull(); +} + +template <class T, class Cleanup> +inline bool operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) Q_DECL_NOTHROW +{ + return !lhs.isNull(); +} + +template <class T, class Cleanup> +inline bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) Q_DECL_NOTHROW +{ + return !rhs.isNull(); +} + +template <class T, class Cleanup> inline void swap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2) Q_DECL_NOTHROW { p1.swap(p2); } diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 84afb0c5db..af09ef6f40 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -442,15 +442,20 @@ */ /*! - \fn QSharedPointer::QSharedPointer(T *ptr) + \fn QSharedPointer::QSharedPointer(X *ptr) Creates a QSharedPointer that points to \a ptr. The pointer \a ptr becomes managed by this QSharedPointer and must not be passed to another QSharedPointer object or deleted outside this object. + + Since Qt 5.8, when the last reference to this QSharedPointer gets + destroyed, \a ptr will be deleted by calling \c X's destructor (even if \c + X is not the same as QSharedPointer's template parameter \c T). Previously, + the destructor for \c T was called. */ /*! - \fn QSharedPointer::QSharedPointer(T *ptr, Deleter deleter) + \fn QSharedPointer::QSharedPointer(X *ptr, Deleter deleter) Creates a QSharedPointer that points to \a ptr. The pointer \a ptr becomes managed by this QSharedPointer and must not be passed to @@ -477,6 +482,9 @@ } \endcode + Note that the custom deleter function will be called with a pointer to type + \c X, even if the QSharedPointer template parameter \c T is not the same. + It is also possible to specify a member function directly, as in: \code QSharedPointer<MyObject> obj = @@ -487,6 +495,22 @@ */ /*! + \fn QSharedPointer::QSharedPointer(std::nullptr_t) + \since 5.8 + + Creates a QSharedPointer that is null. This is equivalent to the + QSharedPointer default constructor. +*/ + +/*! + \fn QSharedPointer::QSharedPointer(std::nullptr_t, Deleter) + \since 5.8 + + Creates a QSharedPointer that is null. This is equivalent to the + QSharedPointer default constructor. +*/ + +/*! \fn QSharedPointer::QSharedPointer(const QSharedPointer<T> &other) Creates a QSharedPointer object that shares \a other's pointer. @@ -1124,6 +1148,90 @@ */ /*! + \fn bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t) + \relates QSharedPointer + \since 5.8 + + Returns \c true if the pointer referenced by \a lhs is a null pointer. + + \sa QSharedPointer::isNull() +*/ + +/*! + \fn bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs) + \relates QSharedPointer + \since 5.8 + + Returns \c true if the pointer referenced by \a rhs is a null pointer. + + \sa QSharedPointer::isNull() +*/ + +/*! + \fn bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t) + \relates QSharedPointer + \since 5.8 + + Returns \c true if the pointer referenced by \a lhs is a valid (i.e. + non-null) pointer. + + \sa QSharedPointer::isNull() +*/ + +/*! + \fn bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs) + \relates QSharedPointer + \since 5.8 + + Returns \c true if the pointer referenced by \a rhs is a valid (i.e. + non-null) pointer. + + \sa QSharedPointer::isNull() +*/ + +/*! + \fn bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t) + \relates QWeakPointer + \since 5.8 + + Returns \c true if the pointer referenced by \a lhs is a null pointer. + + \sa QWeakPointer::isNull() +*/ + +/*! + \fn bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs) + \relates QWeakPointer + \since 5.8 + + Returns \c true if the pointer referenced by \a rhs is a null pointer. + + \sa QWeakPointer::isNull() +*/ + +/*! + \fn bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t) + \relates QWeakPointer + \since 5.8 + + Returns \c true if the pointer referenced by \a lhs is a valid (i.e. + non-null) pointer. + + \sa QWeakPointer::isNull() +*/ + +/*! + \fn bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs) + \relates QWeakPointer + \since 5.8 + + Returns \c true if the pointer referenced by \a rhs is a valid (i.e. + non-null) pointer. + + \sa QWeakPointer::isNull() +*/ + +/*! \fn bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2) \relates QWeakPointer diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h index 72976637d5..3b86eb238b 100644 --- a/src/corelib/tools/qsharedpointer.h +++ b/src/corelib/tools/qsharedpointer.h @@ -67,8 +67,10 @@ public: // constructors QSharedPointer(); - explicit QSharedPointer(T *ptr); - QSharedPointer(T *ptr, Deleter d); + template <typename X> explicit QSharedPointer(X *ptr); + template <typename X, typename Deleter> QSharedPointer(X *ptr, Deleter d); + QSharedPointer(std::nullptr_t); + template <typename Deleter> QSharedPointer(std::nullptr_t, Deleter d); QSharedPointer(const QSharedPointer<T> &other); QSharedPointer(const QWeakPointer<T> &other); @@ -147,6 +149,14 @@ template<class T, class X> bool operator==(const QWeakPointer<T> &ptr1, const QS template<class T, class X> bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2); template<class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2); template<class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2); +template<class T> bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t); +template<class T> bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t); +template<class T> bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs); +template<class T> bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs); +template<class T> bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t); +template<class T> bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t); +template<class T> bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs); +template<class T> bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs); template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other); template <class X, class T> QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index e9a5443121..0f769ffa86 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -305,23 +305,29 @@ public: typedef const value_type &const_reference; typedef qptrdiff difference_type; - inline T *data() const { return value; } - inline bool isNull() const { return !data(); } - inline operator RestrictedBool() const { return isNull() ? Q_NULLPTR : &QSharedPointer::value; } - inline bool operator !() const { return isNull(); } - inline T &operator*() const { return *data(); } - inline T *operator->() const { return data(); } - - QSharedPointer() Q_DECL_NOTHROW : value(Q_NULLPTR), d(Q_NULLPTR) {} + T *data() const Q_DECL_NOTHROW { return value; } + bool isNull() const Q_DECL_NOTHROW { return !data(); } + operator RestrictedBool() const Q_DECL_NOTHROW { return isNull() ? Q_NULLPTR : &QSharedPointer::value; } + bool operator !() const Q_DECL_NOTHROW { return isNull(); } + T &operator*() const { return *data(); } + T *operator->() const Q_DECL_NOTHROW { return data(); } + + Q_DECL_CONSTEXPR QSharedPointer() Q_DECL_NOTHROW : value(nullptr), d(nullptr) { } ~QSharedPointer() { deref(); } - inline explicit QSharedPointer(T *ptr) : value(ptr) // noexcept + Q_DECL_CONSTEXPR QSharedPointer(std::nullptr_t) Q_DECL_NOTHROW : value(nullptr), d(nullptr) { } + + template <class X> + inline explicit QSharedPointer(X *ptr) : value(ptr) // noexcept { internalConstruct(ptr, QtSharedPointer::NormalDeleter()); } - template <typename Deleter> - inline QSharedPointer(T *ptr, Deleter deleter) : value(ptr) // throws + template <class X, typename Deleter> + inline QSharedPointer(X *ptr, Deleter deleter) : value(ptr) // throws { internalConstruct(ptr, deleter); } + template <typename Deleter> + QSharedPointer(std::nullptr_t, Deleter) : value(nullptr), d(nullptr) { } + QSharedPointer(const QSharedPointer &other) Q_DECL_NOTHROW : value(other.value), d(other.d) { if (d) ref(); } QSharedPointer &operator=(const QSharedPointer &other) Q_DECL_NOTHROW @@ -363,7 +369,7 @@ public: #endif template <class X> - inline QSharedPointer(const QSharedPointer<X> &other) : value(other.value), d(other.d) + QSharedPointer(const QSharedPointer<X> &other) Q_DECL_NOTHROW : value(other.value), d(other.d) { if (d) ref(); } template <class X> @@ -511,15 +517,15 @@ private: inline void enableSharedFromThis(...) {} - template <typename Deleter> - inline void internalConstruct(T *ptr, Deleter deleter) + template <typename X, typename Deleter> + inline void internalConstruct(X *ptr, Deleter deleter) { if (!ptr) { d = Q_NULLPTR; return; } - typedef QtSharedPointer::ExternalRefCountWithCustomDeleter<T, Deleter> Private; + typedef QtSharedPointer::ExternalRefCountWithCustomDeleter<X, Deleter> Private; # ifdef QT_SHAREDPOINTER_TRACK_POINTERS typename Private::DestroyerFn actualDeleter = &Private::safetyCheckDeleter; # else @@ -598,10 +604,10 @@ public: typedef const value_type &const_reference; typedef qptrdiff difference_type; - inline bool isNull() const { return d == Q_NULLPTR || d->strongref.load() == 0 || value == Q_NULLPTR; } - inline operator RestrictedBool() const { return isNull() ? Q_NULLPTR : &QWeakPointer::value; } - inline bool operator !() const { return isNull(); } - inline T *data() const { return d == Q_NULLPTR || d->strongref.load() == 0 ? Q_NULLPTR : value; } + bool isNull() const Q_DECL_NOTHROW { return d == Q_NULLPTR || d->strongref.load() == 0 || value == Q_NULLPTR; } + operator RestrictedBool() const Q_DECL_NOTHROW { return isNull() ? Q_NULLPTR : &QWeakPointer::value; } + bool operator !() const Q_DECL_NOTHROW { return isNull(); } + T *data() const Q_DECL_NOTHROW { return d == Q_NULLPTR || d->strongref.load() == 0 ? Q_NULLPTR : value; } inline QWeakPointer() Q_DECL_NOTHROW : d(Q_NULLPTR), value(Q_NULLPTR) { } inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; } @@ -668,11 +674,11 @@ public: } template <class X> - inline bool operator==(const QWeakPointer<X> &o) const + bool operator==(const QWeakPointer<X> &o) const Q_DECL_NOTHROW { return d == o.d && value == static_cast<const T *>(o.value); } template <class X> - inline bool operator!=(const QWeakPointer<X> &o) const + bool operator!=(const QWeakPointer<X> &o) const Q_DECL_NOTHROW { return !(*this == o); } template <class X> @@ -688,11 +694,11 @@ public: } template <class X> - inline bool operator==(const QSharedPointer<X> &o) const + bool operator==(const QSharedPointer<X> &o) const Q_DECL_NOTHROW { return d == o.d; } template <class X> - inline bool operator!=(const QSharedPointer<X> &o) const + bool operator!=(const QSharedPointer<X> &o) const Q_DECL_NOTHROW { return !(*this == o); } inline void clear() { *this = QWeakPointer(); } @@ -774,48 +780,96 @@ public: // operator== and operator!= // template <class T, class X> -bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) +bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) Q_DECL_NOTHROW { return ptr1.data() == ptr2.data(); } template <class T, class X> -bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) +bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) Q_DECL_NOTHROW { return ptr1.data() != ptr2.data(); } template <class T, class X> -bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2) +bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2) Q_DECL_NOTHROW { return ptr1.data() == ptr2; } template <class T, class X> -bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2) +bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2) Q_DECL_NOTHROW { return ptr1 == ptr2.data(); } template <class T, class X> -bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2) +bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2) Q_DECL_NOTHROW { return !(ptr1 == ptr2); } template <class T, class X> -bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2) +bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2) Q_DECL_NOTHROW { return !(ptr2 == ptr1); } template <class T, class X> -bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) +bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) Q_DECL_NOTHROW { return ptr2 == ptr1; } template <class T, class X> -bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) +bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) Q_DECL_NOTHROW { return ptr2 != ptr1; } +template<class T> +inline bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t) Q_DECL_NOTHROW +{ + return lhs.isNull(); +} + +template<class T> +inline bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t) Q_DECL_NOTHROW +{ + return !lhs.isNull(); +} + +template<class T> +inline bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs) Q_DECL_NOTHROW +{ + return rhs.isNull(); +} + +template<class T> +inline bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs) Q_DECL_NOTHROW +{ + return !rhs.isNull(); +} + +template<class T> +inline bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t) Q_DECL_NOTHROW +{ + return lhs.isNull(); +} + +template<class T> +inline bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t) Q_DECL_NOTHROW +{ + return !lhs.isNull(); +} + +template<class T> +inline bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs) Q_DECL_NOTHROW +{ + return rhs.isNull(); +} + +template<class T> +inline bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs) Q_DECL_NOTHROW +{ + return !rhs.isNull(); +} + // // operator- // diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index c869c4e089..d4edf459de 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -48,16 +48,8 @@ #endif #if defined(Q_OS_WIN) -# if defined(Q_OS_WINCE) -# include <qt_windows.h> -# if _WIN32_WCE < 0x800 -# include <cmnintrin.h> -# endif -# endif # if !defined(Q_CC_GNU) -# ifndef Q_OS_WINCE -# include <intrin.h> -# endif +# include <intrin.h> # endif #elif defined(Q_OS_LINUX) && (defined(Q_PROCESSOR_ARM) || defined(Q_PROCESSOR_MIPS_32)) #include "private/qcore_unix_p.h" @@ -93,25 +85,6 @@ static inline uint detectProcessorFeatures() { return 0; } -#elif defined (Q_OS_WINCE) -static inline quint64 detectProcessorFeatures() -{ - quint64 features = 0; - -#if defined (ARM) -# ifdef PF_ARM_NEON - if (IsProcessorFeaturePresent(PF_ARM_NEON)) - features |= Q_UINT64_C(1) << CpuFeatureNEON; -# endif -#elif defined(_X86_) - if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) - features |= Q_UINT64_C(1) << CpuFeatureSSE2; - if (IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) - features |= Q_UINT64_C(1) << CpuFeatureSSE3; -#endif - return features; -} - #elif defined(Q_PROCESSOR_ARM) static inline quint64 detectProcessorFeatures() { diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 8ddaed8032..8cf0c5a4d2 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -139,7 +139,7 @@ * } */ -#if defined(__MINGW64_VERSION_MAJOR) || (defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)) +#if defined(__MINGW64_VERSION_MAJOR) || defined(Q_CC_MSVC) #include <intrin.h> #endif @@ -465,65 +465,6 @@ static inline quint64 qCpuFeatures() #define qCpuHasFeature(feature) ((qCompilerCpuFeatures & (Q_UINT64_C(1) << CpuFeature ## feature)) \ || (qCpuFeatures() & (Q_UINT64_C(1) << CpuFeature ## feature))) -#if QT_HAS_BUILTIN(__builtin_clz) && QT_HAS_BUILTIN(__builtin_ctz) && defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) -static Q_ALWAYS_INLINE unsigned _bit_scan_reverse(unsigned val) -{ - Q_ASSERT(val != 0); // if val==0, the result is undefined. - unsigned result = static_cast<unsigned>(__builtin_clz(val)); // Count Leading Zeros - // Now Invert the result: clz will count *down* from the msb to the lsb, so the msb index is 31 - // and the lsb inde is 0. The result for _bit_scan_reverse is expected to be the index when - // counting up: msb index is 0 (because it starts there), and the lsb index is 31. - result ^= sizeof(unsigned) * 8 - 1; - return result; -} -static Q_ALWAYS_INLINE unsigned _bit_scan_forward(unsigned val) -{ - Q_ASSERT(val != 0); // if val==0, the result is undefined. - return static_cast<unsigned>(__builtin_ctz(val)); // Count Trailing Zeros -} -#elif defined(Q_PROCESSOR_X86) -// Bit scan functions for x86 -# if defined(Q_CC_MSVC) -# if defined _WIN32_WCE && _WIN32_WCE < 0x800 -extern "C" unsigned char _BitScanForward(unsigned long* Index, unsigned long Mask); -extern "C" unsigned char _BitScanReverse(unsigned long* Index, unsigned long Mask); -# pragma intrinsic(_BitScanForward) -# pragma intrinsic(_BitScanReverse) -# endif -// MSVC calls it _BitScanReverse and returns the carry flag, which we don't need -static __forceinline unsigned long _bit_scan_reverse(uint val) -{ - unsigned long result; - _BitScanReverse(&result, val); - return result; -} -static __forceinline unsigned long _bit_scan_forward(uint val) -{ - unsigned long result; - _BitScanForward(&result, val); - return result; -} -# elif (defined(Q_CC_CLANG) || (defined(Q_CC_GNU) && Q_CC_GNU < 405)) \ - && !defined(Q_CC_INTEL) -// Clang is missing the intrinsic for _bit_scan_reverse -// GCC only added it in version 4.5 -static inline __attribute__((always_inline)) -unsigned _bit_scan_reverse(unsigned val) -{ - unsigned result; - asm("bsr %1, %0" : "=r" (result) : "r" (val)); - return result; -} -static inline __attribute__((always_inline)) -unsigned _bit_scan_forward(unsigned val) -{ - unsigned result; - asm("bsf %1, %0" : "=r" (result) : "r" (val)); - return result; -} -# endif -#endif // Q_PROCESSOR_X86 - #define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \ for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 85da174366..c79bced52e 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -81,9 +81,6 @@ #ifdef Q_OS_WIN # include <qt_windows.h> -# ifdef Q_OS_WINCE -# include <winnls.h> -# endif #endif #ifdef truncate @@ -471,7 +468,7 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l) uint mask = ~_mm_movemask_epi8(result); if (ushort(mask)) { // found a different byte - uint idx = uint(_bit_scan_forward(mask)); + uint idx = qCountTrailingZeroBits(mask); return reinterpret_cast<const QChar *>(ptr + idx)->unicode() - reinterpret_cast<const QChar *>(ptr + distance + idx)->unicode(); } @@ -574,7 +571,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) # endif if (mask) { // found a different character - uint idx = uint(_bit_scan_forward(mask)); + uint idx = qCountTrailingZeroBits(mask); return uc[offset + idx / 2] - c[offset + idx / 2]; } } @@ -592,7 +589,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) uint mask = ~_mm_movemask_epi8(result); if (ushort(mask)) { // found a different character - uint idx = uint(_bit_scan_forward(mask)); + uint idx = qCountTrailingZeroBits(mask); return uc[offset + idx / 2] - c[offset + idx / 2]; } @@ -686,7 +683,7 @@ static int findChar(const QChar *str, int len, QChar ch, int from, // found a match // same as: return n - s + _bit_scan_forward(mask) / 2 return (reinterpret_cast<const char *>(n) - reinterpret_cast<const char *>(s) - + _bit_scan_forward(mask)) >> 1; + + qCountTrailingZeroBits(mask)) >> 1; } } @@ -1151,7 +1148,7 @@ const QString::Null QString::null = { }; has a ref count of 1, whereas QString::append() needs an extra test). - There are three ways you can access this improved method of string + There are two ways you can access this improved method of string construction. The straightforward way is to include \c{QStringBuilder} wherever you want to use it, and use the \c{'%'} operator instead of \c{'+'} when concatenating strings: @@ -3273,7 +3270,7 @@ int QString::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) co { const int sl = str.size(); if (sl == 1) - return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs); + return lastIndexOf(str.at(0), from, cs); const int l = d->size; if (from < 0) @@ -5522,7 +5519,7 @@ int QString::localeAwareCompare(const QString &other) const return localeAwareCompare_helper(constData(), length(), other.constData(), other.length()); } -#if defined(QT_USE_ICU) && !defined(Q_OS_WIN32) && !defined(Q_OS_WINCE) && !defined (Q_OS_MAC) +#if defined(QT_USE_ICU) && !defined(Q_OS_WIN32) && !defined(Q_OS_DARWIN) Q_GLOBAL_STATIC(QThreadStorage<QCollator>, defaultCollator) #endif @@ -5537,12 +5534,12 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1, if (length1 == 0 || length2 == 0) return ucstrcmp(data1, length1, data2, length2); -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) -#ifndef Q_OS_WINRT +#if defined(Q_OS_WIN) +# ifndef Q_OS_WINRT int res = CompareString(GetUserDefaultLCID(), 0, (wchar_t*)data1, length1, (wchar_t*)data2, length2); -#else +# else int res = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, (LPCWSTR)data1, length1, (LPCWSTR)data2, length2, NULL, NULL, 0); -#endif +# endif switch (res) { case CSTR_LESS_THAN: @@ -7949,40 +7946,6 @@ QString QString::multiArg(int numArgs, const QString **args) const return result; } - -/*! \fn QString QString::fromCFString(CFStringRef string) - \since 5.2 - - Constructs a new QString containing a copy of the \a string CFString. - - \note this function is only available on OS X and iOS. -*/ - -/*! \fn CFStringRef QString::toCFString() const - \since 5.2 - - Creates a CFString from a QString. The caller owns the CFString and is - responsible for releasing it. - - \note this function is only available on OS X and iOS. -*/ - -/*! \fn QString QString::fromNSString(const NSString *string) - \since 5.2 - - Constructs a new QString containing a copy of the \a string NSString. - - \note this function is only available on OS X and iOS. -*/ - -/*! \fn NSString QString::toNSString() const - \since 5.2 - - Creates a NSString from a QString. The NSString is autoreleased. - - \note this function is only available on OS X and iOS. -*/ - /*! \fn bool QString::isSimpleText() const \internal @@ -8332,6 +8295,78 @@ QString &QString::setRawData(const QChar *unicode, int size) Returns the size of the Latin-1 string stored in this object. */ +/*! \fn QLatin1Char QLatin1String::at(int pos) const + \since 5.8 + + Returns the character at position \a pos in this object. + + \note This function performs no error checking. + The behavior is undefined when \a pos < 0 or \a pos ≥ size(). + + \sa operator[]() +*/ + +/*! \fn QLatin1Char QLatin1String::operator[](int pos) const + \since 5.8 + + Returns the character at position \a pos in this object. + + \note This function performs no error checking. + The behavior is undefined when \a pos < 0 or \a pos ≥ size(). + + \sa at() +*/ + +/*! \fn QLatin1String QLatin1String::mid(int start) const + \since 5.8 + + Returns the substring starting at position \a start in this object, + and extending to the end of the string. + + \note This function performs no error checking. + The behavior is undefined when \a start < 0 or \a start > size(). + + \sa left(), right() +*/ + +/*! \fn QLatin1String QLatin1String::mid(int start, int length) const + \since 5.8 + \overload + + Returns the substring of length \a length starting at position + \a start in this object. + + \note This function performs no error checking. + The behavior is undefined when \a start < 0, \length < 0, + or \a start + \a length > size(). + + \sa left(), right() +*/ + +/*! \fn QLatin1String QLatin1String::left(int length) const + \since 5.8 + + Returns the substring of length \a length starting at position + 0 in this object. + + \note This function performs no error checking. + The behavior is undefined when \length < 0 or \a length > size(). + + \sa mid(), right() +*/ + +/*! \fn QLatin1String QLatin1String::right(int length) const + \since 5.8 + + Returns the substring of length \a length starting at position + size() - \a length in this object. + + \note This function performs no error checking. + The behavior is undefined when \length < 0 or \a length > size(). + + \sa mid(), left() +*/ + /*! \fn bool QLatin1String::operator==(const QString &other) const Returns \c true if this string is equal to string \a other; @@ -9364,6 +9399,24 @@ QStringRef QStringRef::appendTo(QString *string) const */ /*! + \overload + \fn int QStringRef::compare(const QByteArray &other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const + \since 5.8 + + Compares this string with \a other and returns an + integer less than, equal to, or greater than zero if this string + is less than, equal to, or greater than the \a other byte array, + interpreted as a UTF-8 sequence. + + If \a cs is Qt::CaseSensitive, the comparison is case sensitive; + otherwise the comparison is case insensitive. + + Equivalent to \c {compare(*this, other, cs)}. + + \sa QString::compare() +*/ + +/*! \fn int QStringRef::localeAwareCompare(const QStringRef &s1, const QString & s2) \since 4.5 @@ -9747,7 +9800,7 @@ int QStringRef::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) { const int sl = str.size(); if (sl == 1) - return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs); + return lastIndexOf(str.at(0), from, cs); const int l = size(); if (from < 0) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 793a859228..16a48515e8 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -68,11 +68,9 @@ namespace std #error qstring.h must be included before any header file that defines truncate #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_DARWIN) || defined(Q_QDOC) Q_FORWARD_DECLARE_CF_TYPE(CFString); -# ifdef __OBJC__ Q_FORWARD_DECLARE_OBJC_CLASS(NSString); -# endif #endif QT_BEGIN_NAMESPACE @@ -99,6 +97,18 @@ public: Q_DECL_CONSTEXPR int size() const Q_DECL_NOTHROW { return m_size; } Q_DECL_CONSTEXPR const char *data() const Q_DECL_NOTHROW { return m_data; } + Q_DECL_CONSTEXPR QLatin1Char at(int i) const { return QLatin1Char(m_data[i]); } + Q_DECL_CONSTEXPR QLatin1Char operator[](int i) const { return at(i); } + + Q_DECL_CONSTEXPR QLatin1String mid(int pos) const + { return QLatin1String(m_data + pos, m_size - pos); } + Q_DECL_CONSTEXPR QLatin1String mid(int pos, int n) const + { return QLatin1String(m_data + pos, n); } + Q_DECL_CONSTEXPR QLatin1String left(int n) const + { return QLatin1String(m_data, n); } + Q_DECL_CONSTEXPR QLatin1String right(int n) const + { return QLatin1String(m_data + m_size - n, n); } + inline bool operator==(const QString &s) const Q_DECL_NOTHROW; inline bool operator!=(const QString &s) const Q_DECL_NOTHROW; inline bool operator>(const QString &s) const Q_DECL_NOTHROW; @@ -593,7 +603,7 @@ public: Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW { return -s2.compare(s1, cs); } - int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW; + inline int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW; static int compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity = Qt::CaseSensitive) Q_DECL_NOTHROW; @@ -768,13 +778,11 @@ public: inline std::u32string toStdU32String() const; #endif -#if defined(Q_OS_MAC) || defined(Q_QDOC) +#if defined(Q_OS_DARWIN) || defined(Q_QDOC) static QString fromCFString(CFStringRef string); CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED; -# if defined(__OBJC__) || defined(Q_QDOC) static QString fromNSString(const NSString *string); NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED; -# endif #endif // compatibility struct Null { }; @@ -802,6 +810,16 @@ private: Data *d; + friend inline bool operator==(QChar, const QString &) Q_DECL_NOTHROW; + friend inline bool operator< (QChar, const QString &) Q_DECL_NOTHROW; + friend inline bool operator> (QChar, const QString &) Q_DECL_NOTHROW; + friend inline bool operator==(QChar, const QStringRef &) Q_DECL_NOTHROW; + friend inline bool operator< (QChar, const QStringRef &) Q_DECL_NOTHROW; + friend inline bool operator> (QChar, const QStringRef &) Q_DECL_NOTHROW; + friend inline bool operator==(QChar, QLatin1String) Q_DECL_NOTHROW; + friend inline bool operator< (QChar, QLatin1String) Q_DECL_NOTHROW; + friend inline bool operator> (QChar, QLatin1String) Q_DECL_NOTHROW; + void reallocData(uint alloc, bool grow = false); void expand(int i); QString multiArg(int numArgs, const QString **args) const; @@ -1483,6 +1501,10 @@ public: int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW; int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW; int compare(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW; +#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII) + int compare(const QByteArray &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const + { return QString::compare_helper(unicode(), size(), s.data(), qstrnlen(s.data(), s.size()), cs); } +#endif static int compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity = Qt::CaseSensitive) Q_DECL_NOTHROW; static int compare(const QStringRef &s1, const QStringRef &s2, @@ -1518,24 +1540,10 @@ inline QStringRef::QStringRef(const QString *aString, int aPosition, int aSize) inline QStringRef::QStringRef(const QString *aString) :m_string(aString), m_position(0), m_size(aString?aString->size() : 0){} +// QStringRef <> QStringRef Q_CORE_EXPORT bool operator==(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW; inline bool operator!=(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW { return !(s1 == s2); } -Q_CORE_EXPORT bool operator==(const QString &s1, const QStringRef &s2) Q_DECL_NOTHROW; -inline bool operator!=(const QString &s1, const QStringRef &s2) Q_DECL_NOTHROW -{ return !(s1 == s2); } -inline bool operator==(const QStringRef &s1, const QString &s2) Q_DECL_NOTHROW -{ return s2 == s1; } -inline bool operator!=(const QStringRef &s1, const QString &s2) Q_DECL_NOTHROW -{ return s2 != s1; } -Q_CORE_EXPORT bool operator==(QLatin1String s1, const QStringRef &s2) Q_DECL_NOTHROW; -inline bool operator!=(QLatin1String s1, const QStringRef &s2) Q_DECL_NOTHROW -{ return !(s1 == s2); } -inline bool operator==(const QStringRef &s1, QLatin1String s2) Q_DECL_NOTHROW -{ return s2 == s1; } -inline bool operator!=(const QStringRef &s1, QLatin1String s2) Q_DECL_NOTHROW -{ return s2 != s1; } - Q_CORE_EXPORT bool operator<(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW; inline bool operator>(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW { return s2 < s1; } @@ -1544,7 +1552,127 @@ inline bool operator<=(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHRO inline bool operator>=(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW { return !(s1 < s2); } +// QString <> QStringRef +Q_CORE_EXPORT bool operator==(const QString &lhs, const QStringRef &rhs) Q_DECL_NOTHROW; +inline bool operator!=(const QString &lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return lhs.compare(rhs) != 0; } +inline bool operator< (const QString &lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return lhs.compare(rhs) < 0; } +inline bool operator> (const QString &lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return lhs.compare(rhs) > 0; } +inline bool operator<=(const QString &lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return lhs.compare(rhs) <= 0; } +inline bool operator>=(const QString &lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return lhs.compare(rhs) >= 0; } + +inline bool operator==(const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW { return rhs == lhs; } +inline bool operator!=(const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW { return rhs != lhs; } +inline bool operator< (const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW { return rhs > lhs; } +inline bool operator> (const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW { return rhs < lhs; } +inline bool operator<=(const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW { return rhs >= lhs; } +inline bool operator>=(const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW { return rhs <= lhs; } + +inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW +{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); } +inline int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW +{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); } +inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW +{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); } +inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW +{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); } +inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW +{ return QString::compare_helper(constData(), length(), s, cs); } +inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW +{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); } +inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW +{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); } +inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW +{ return QString::compare_helper(s1.constData(), s1.length(), s2, cs); } + +// QLatin1String <> QStringRef +Q_CORE_EXPORT bool operator==(QLatin1String lhs, const QStringRef &rhs) Q_DECL_NOTHROW; +inline bool operator!=(QLatin1String lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return rhs.compare(lhs) != 0; } +inline bool operator< (QLatin1String lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return rhs.compare(lhs) > 0; } +inline bool operator> (QLatin1String lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return rhs.compare(lhs) < 0; } +inline bool operator<=(QLatin1String lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return rhs.compare(lhs) >= 0; } +inline bool operator>=(QLatin1String lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return rhs.compare(lhs) <= 0; } + +inline bool operator==(const QStringRef &lhs, QLatin1String rhs) Q_DECL_NOTHROW { return rhs == lhs; } +inline bool operator!=(const QStringRef &lhs, QLatin1String rhs) Q_DECL_NOTHROW { return rhs != lhs; } +inline bool operator< (const QStringRef &lhs, QLatin1String rhs) Q_DECL_NOTHROW { return rhs > lhs; } +inline bool operator> (const QStringRef &lhs, QLatin1String rhs) Q_DECL_NOTHROW { return rhs < lhs; } +inline bool operator<=(const QStringRef &lhs, QLatin1String rhs) Q_DECL_NOTHROW { return rhs >= lhs; } +inline bool operator>=(const QStringRef &lhs, QLatin1String rhs) Q_DECL_NOTHROW { return rhs <= lhs; } + +// QChar <> QString +inline bool operator==(QChar lhs, const QString &rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) == 0; } +inline bool operator< (QChar lhs, const QString &rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; } +inline bool operator> (QChar lhs, const QString &rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; } + +inline bool operator!=(QChar lhs, const QString &rhs) Q_DECL_NOTHROW { return !(lhs == rhs); } +inline bool operator<=(QChar lhs, const QString &rhs) Q_DECL_NOTHROW { return !(lhs > rhs); } +inline bool operator>=(QChar lhs, const QString &rhs) Q_DECL_NOTHROW { return !(lhs < rhs); } + +inline bool operator==(const QString &lhs, QChar rhs) Q_DECL_NOTHROW { return rhs == lhs; } +inline bool operator!=(const QString &lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs == lhs); } +inline bool operator< (const QString &lhs, QChar rhs) Q_DECL_NOTHROW { return rhs > lhs; } +inline bool operator> (const QString &lhs, QChar rhs) Q_DECL_NOTHROW { return rhs < lhs; } +inline bool operator<=(const QString &lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs < lhs); } +inline bool operator>=(const QString &lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs > lhs); } + +// QChar <> QStringRef +inline bool operator==(QChar lhs, const QStringRef &rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) == 0; } +inline bool operator< (QChar lhs, const QStringRef &rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; } +inline bool operator> (QChar lhs, const QStringRef &rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; } + +inline bool operator!=(QChar lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return !(lhs == rhs); } +inline bool operator<=(QChar lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return !(lhs > rhs); } +inline bool operator>=(QChar lhs, const QStringRef &rhs) Q_DECL_NOTHROW { return !(lhs < rhs); } + +inline bool operator==(const QStringRef &lhs, QChar rhs) Q_DECL_NOTHROW { return rhs == lhs; } +inline bool operator!=(const QStringRef &lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs == lhs); } +inline bool operator< (const QStringRef &lhs, QChar rhs) Q_DECL_NOTHROW { return rhs > lhs; } +inline bool operator> (const QStringRef &lhs, QChar rhs) Q_DECL_NOTHROW { return rhs < lhs; } +inline bool operator<=(const QStringRef &lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs < lhs); } +inline bool operator>=(const QStringRef &lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs > lhs); } + +// QChar <> QLatin1String +inline bool operator==(QChar lhs, QLatin1String rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs) == 0; } +inline bool operator< (QChar lhs, QLatin1String rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs) < 0; } +inline bool operator> (QChar lhs, QLatin1String rhs) Q_DECL_NOTHROW +{ return QString::compare_helper(&lhs, 1, rhs) > 0; } + +inline bool operator!=(QChar lhs, QLatin1String rhs) Q_DECL_NOTHROW { return !(lhs == rhs); } +inline bool operator<=(QChar lhs, QLatin1String rhs) Q_DECL_NOTHROW { return !(lhs > rhs); } +inline bool operator>=(QChar lhs, QLatin1String rhs) Q_DECL_NOTHROW { return !(lhs < rhs); } + +inline bool operator==(QLatin1String lhs, QChar rhs) Q_DECL_NOTHROW { return rhs == lhs; } +inline bool operator!=(QLatin1String lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs == lhs); } +inline bool operator< (QLatin1String lhs, QChar rhs) Q_DECL_NOTHROW { return rhs > lhs; } +inline bool operator> (QLatin1String lhs, QChar rhs) Q_DECL_NOTHROW { return rhs < lhs; } +inline bool operator<=(QLatin1String lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs < lhs); } +inline bool operator>=(QLatin1String lhs, QChar rhs) Q_DECL_NOTHROW { return !(rhs > lhs); } + #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII) +// QStringRef <> QByteArray +inline QT_ASCII_CAST_WARN bool operator==(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) == 0; } +inline QT_ASCII_CAST_WARN bool operator!=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) != 0; } +inline QT_ASCII_CAST_WARN bool operator< (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) < 0; } +inline QT_ASCII_CAST_WARN bool operator> (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) > 0; } +inline QT_ASCII_CAST_WARN bool operator<=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) <= 0; } +inline QT_ASCII_CAST_WARN bool operator>=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) >= 0; } + +inline QT_ASCII_CAST_WARN bool operator==(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) == 0; } +inline QT_ASCII_CAST_WARN bool operator!=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) != 0; } +inline QT_ASCII_CAST_WARN bool operator< (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) > 0; } +inline QT_ASCII_CAST_WARN bool operator> (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) < 0; } +inline QT_ASCII_CAST_WARN bool operator<=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) >= 0; } +inline QT_ASCII_CAST_WARN bool operator>=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) <= 0; } + +// QStringRef <> const char * inline QT_ASCII_CAST_WARN bool QStringRef::operator==(const char *s) const { return QString::compare_helper(constData(), size(), s, -1) == 0; } inline QT_ASCII_CAST_WARN bool QStringRef::operator!=(const char *s) const @@ -1572,23 +1700,6 @@ inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QStringRef &s2) { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) <= 0; } #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII) -inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW -{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); } -inline int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW -{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); } -inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW -{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); } -inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW -{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); } -inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW -{ return QString::compare_helper(constData(), length(), s, cs); } -inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW -{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); } -inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW -{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); } -inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW -{ return QString::compare_helper(s1.constData(), s1.length(), s2, cs); } - inline int QString::localeAwareCompare(const QStringRef &s) const { return localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); } inline int QString::localeAwareCompare(const QString& s1, const QStringRef& s2) diff --git a/src/corelib/tools/qstring_mac.mm b/src/corelib/tools/qstring_mac.mm deleted file mode 100644 index 7b3d6b53c0..0000000000 --- a/src/corelib/tools/qstring_mac.mm +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qstring.h" - -#import <Foundation/Foundation.h> - -QT_BEGIN_NAMESPACE - -QString QString::fromCFString(CFStringRef string) -{ - if (!string) - return QString(); - CFIndex length = CFStringGetLength(string); - - // Fast path: CFStringGetCharactersPtr does not copy but may - // return null for any and no reason. - const UniChar *chars = CFStringGetCharactersPtr(string); - if (chars) - return QString(reinterpret_cast<const QChar *>(chars), length); - - QString ret(length, Qt::Uninitialized); - CFStringGetCharacters(string, CFRangeMake(0, length), reinterpret_cast<UniChar *>(ret.data())); - return ret; -} - -CFStringRef QString::toCFString() const -{ - return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(unicode()), length()); -} - -QString QString::fromNSString(const NSString *string) -{ - if (!string) - return QString(); - QString qstring; - qstring.resize([string length]); - [string getCharacters: reinterpret_cast<unichar*>(qstring.data()) range: NSMakeRange(0, [string length])]; - return qstring; -} - -NSString *QString::toNSString() const -{ - return [NSString stringWithCharacters: reinterpret_cast<const UniChar*>(unicode()) length: length()]; -} - -QT_END_NAMESPACE diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h index e01f9e16e8..87f15528bf 100644 --- a/src/corelib/tools/qstringlist.h +++ b/src/corelib/tools/qstringlist.h @@ -149,6 +149,7 @@ public: Q_DECLARE_TYPEINFO(QStringList, Q_MOVABLE_TYPE); +#ifndef Q_QDOC inline QStringList *QListSpecialMethods<QString>::self() { return static_cast<QStringList *>(this); } inline const QStringList *QListSpecialMethods<QString>::self() const @@ -284,6 +285,7 @@ inline int QStringList::lastIndexOf(const QRegularExpression &rx, int from) cons } #endif // QT_NO_REGULAREXPRESSION #endif // QT_BOOTSTRAPPED +#endif // Q_QDOC QT_END_NAMESPACE diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp index 8e32db48de..4febeda537 100644 --- a/src/corelib/tools/qtimezoneprivate_win.cpp +++ b/src/corelib/tools/qtimezoneprivate_win.cpp @@ -383,17 +383,11 @@ static void calculateTransitionsForYear(const QWinTimeZonePrivate::QWinTransitio static QLocale::Country userCountry() { -#if defined(Q_OS_WINCE) - // Guess that the syslem locale country is the right one to use - // TODO Find if WinCE has equivalent api - return QLocale::system().country(); -#else const GEOID id = GetUserGeoID(GEOCLASS_NATION); wchar_t code[3]; const int size = GetGeoInfo(id, GEO_ISO2, code, 3, 0); return (size == 3) ? QLocalePrivate::codeToCountry(reinterpret_cast<const QChar*>(code), size) : QLocale::AnyCountry; -#endif // Q_OS_WINCE } // Create the system default time zone diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index b64ec756ba..4d77f4e43f 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -133,9 +133,6 @@ false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator SOURCES += tools/qelapsedtimer_mac.cpp OBJECTIVE_SOURCES += tools/qlocale_mac.mm \ tools/qtimezoneprivate_mac.mm \ - tools/qstring_mac.mm \ - tools/qbytearray_mac.mm \ - tools/qdatetime_mac.mm } else:android { SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_android.cpp @@ -152,11 +149,11 @@ else:win32 { } else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp else:SOURCES += tools/qelapsedtimer_generic.cpp -contains(QT_CONFIG, zlib) { - include($$PWD/../../3rdparty/zlib.pri) +contains(QT_CONFIG, system-zlib) { + include($$PWD/../../3rdparty/zlib_dependency.pri) } else { CONFIG += no_core_dep - include($$PWD/../../3rdparty/zlib_dependency.pri) + include($$PWD/../../3rdparty/zlib.pri) } contains(QT_CONFIG,icu) { @@ -198,12 +195,10 @@ INCLUDEPATH += ../3rdparty/md5 \ ../3rdparty/md4 \ ../3rdparty/sha3 -contains(QT_CONFIG, doubleconversion) { - include($$PWD/../../3rdparty/double-conversion/double-conversion.pri) -} else:contains(QT_CONFIG, system-doubleconversion) { +contains(QT_CONFIG, system-doubleconversion) { LIBS_PRIVATE += -ldouble-conversion -} else { - DEFINES += QT_NO_DOUBLECONVERSION +} else: contains(QT_CONFIG, doubleconversion) { + include($$PWD/../../3rdparty/double-conversion/double-conversion.pri) } # Note: libm should be present by default becaue this is C++ |