diff options
Diffstat (limited to 'src/corelib/tools')
22 files changed, 1392 insertions, 388 deletions
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index ff4d5a3ebd..57fbdf0eba 100644..100755 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -584,6 +584,131 @@ Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qPopulationCount(long unsigne #undef QALGORITHMS_USE_BUILTIN_POPCOUNT #endif +Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint32 v) Q_DECL_NOTHROW +{ +#if defined(Q_CC_GNU) + return v ? __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 + v &= -signed(v); + if (v) c--; + if (v & 0x0000FFFF) c -= 16; + if (v & 0x00FF00FF) c -= 8; + if (v & 0x0F0F0F0F) c -= 4; + if (v & 0x33333333) c -= 2; + if (v & 0x55555555) c -= 1; + return c; +#endif +} + +Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint8 v) Q_DECL_NOTHROW +{ +#if defined(Q_CC_GNU) + return v ? __builtin_ctz(v) : 8U; +#else + unsigned int c = 8; // c will be the number of zero bits on the right + v &= -signed(v); + if (v) c--; + if (v & 0x0000000F) c -= 4; + if (v & 0x00000033) c -= 2; + if (v & 0x00000055) c -= 1; + return c; +#endif +} + +Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint16 v) Q_DECL_NOTHROW +{ +#if defined(Q_CC_GNU) + return v ? __builtin_ctz(v) : 16U; +#else + unsigned int c = 16; // c will be the number of zero bits on the right + v &= -signed(v); + if (v) c--; + if (v & 0x000000FF) c -= 8; + if (v & 0x00000F0F) c -= 4; + if (v & 0x00003333) c -= 2; + if (v & 0x00005555) c -= 1; + return c; +#endif +} + +Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint64 v) Q_DECL_NOTHROW +{ +#if defined(Q_CC_GNU) + return v ? __builtin_ctzll(v) : 64; +#else + quint32 x = static_cast<quint32>(v); + return x ? qCountTrailingZeroBits(x) + : 32 + qCountTrailingZeroBits(static_cast<quint32>(v >> 32)); +#endif +} + +Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(unsigned long v) Q_DECL_NOTHROW +{ + return qCountTrailingZeroBits(QIntegerForSizeof<long>::Unsigned(v)); +} + +Q_DECL_CONSTEXPR inline uint qCountLeadingZeroBits(quint32 v) Q_DECL_NOTHROW +{ +#if defined(Q_CC_GNU) + return v ? __builtin_clz(v) : 32U; +#else + // Hacker's Delight, 2nd ed. Fig 5-16, p. 102 + v = v | (v >> 1); + v = v | (v >> 2); + v = v | (v >> 4); + v = v | (v >> 8); + v = v | (v >> 16); + return qPopulationCount(~v); +#endif +} + +Q_DECL_CONSTEXPR inline uint qCountLeadingZeroBits(quint8 v) Q_DECL_NOTHROW +{ +#if defined(Q_CC_GNU) + return v ? __builtin_clz(v)-24U : 8U; +#else + v = v | (v >> 1); + v = v | (v >> 2); + v = v | (v >> 4); + return qPopulationCount(static_cast<quint8>(~v)); +#endif +} + +Q_DECL_CONSTEXPR inline uint qCountLeadingZeroBits(quint16 v) Q_DECL_NOTHROW +{ +#if defined(Q_CC_GNU) + return v ? __builtin_clz(v)-16U : 16U; +#else + v = v | (v >> 1); + v = v | (v >> 2); + v = v | (v >> 4); + v = v | (v >> 8); + return qPopulationCount(static_cast<quint16>(~v)); +#endif +} + +Q_DECL_CONSTEXPR inline uint qCountLeadingZeroBits(quint64 v) Q_DECL_NOTHROW +{ +#if defined(Q_CC_GNU) + return v ? __builtin_clzll(v) : 64U; +#else + v = v | (v >> 1); + v = v | (v >> 2); + v = v | (v >> 4); + v = v | (v >> 8); + v = v | (v >> 16); + v = v | (v >> 32); + return qPopulationCount(~v); +#endif +} + +Q_DECL_CONSTEXPR inline uint qCountLeadingZeroBits(unsigned long v) Q_DECL_NOTHROW +{ + return qCountLeadingZeroBits(QIntegerForSizeof<long>::Unsigned(v)); +} + QT_WARNING_POP QT_END_NAMESPACE diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc index 193042e017..dac353fa70 100644..100755 --- a/src/corelib/tools/qalgorithms.qdoc +++ b/src/corelib/tools/qalgorithms.qdoc @@ -785,3 +785,73 @@ \since 5.2 \overload */ + +/*! + \fn uint qCountTrailingZeroBits(quint8 v) + \relates <QtAlgorithms> + \since 5.6 + + Returns the number of consecutive zero bits in \a v, when searching from the LSB. + For example, qCountTrailingZeroBits(1) returns 0 and qCountTrailingZeroBits(8) returns 3. + */ + +/*! + \fn uint qCountTrailingZeroBits(quint16 v) + \relates <QtAlgorithms> + \since 5.6 + \overload + */ + +/*! + \fn uint qCountTrailingZeroBits(quint32 v) + \relates <QtAlgorithms> + \since 5.6 + \overload + */ + +/*! + \fn uint qCountTrailingZeroBits(quint64 v) + \relates <QtAlgorithms> + \since 5.6 + \overload + */ + +/*! + \fn uint qCountLeadingZeroBits(quint8 v) + \relates <QtAlgorithms> + \since 5.6 + + Returns the number of consecutive zero bits in \a v, when searching from the MSB. + For example, qCountLeadingZeroBits(quint8(1)) returns 7 and + qCountLeadingZeroBits(quint8(8)) returns 4. + */ + +/*! + \fn uint qCountLeadingZeroBits(quint16 v) + \relates <QtAlgorithms> + \since 5.6 + + Returns the number of consecutive zero bits in \a v, when searching from the MSB. + For example, qCountLeadingZeroBits(quint16(1)) returns 15 and + qCountLeadingZeroBits(quint16(8)) returns 12. + */ + +/*! + \fn uint qCountLeadingZeroBits(quint32 v) + \relates <QtAlgorithms> + \since 5.6 + + Returns the number of consecutive zero bits in \a v, when searching from the MSB. + For example, qCountLeadingZeroBits(quint32(1)) returns 31 and + qCountLeadingZeroBits(quint32(8)) returns 28. + */ + +/*! + \fn uint qCountLeadingZeroBits(quint64 v) + \relates <QtAlgorithms> + \since 5.6 + + Returns the number of consecutive zero bits in \a v, when searching from the MSB. + For example, qCountLeadingZeroBits(quint64(1)) returns 63 and + qCountLeadingZeroBits(quint64(8)) returns 60. + */ diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index 5c094772b8..56904c91d7 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -681,7 +681,7 @@ QT_BEGIN_NAMESPACE Note that this gives no indication of whether the character is available in a particular font. */ -bool QChar::isPrint(uint ucs4) +bool QChar::isPrint(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -714,7 +714,7 @@ bool QChar::isPrint(uint ucs4) /*! \internal */ -bool QT_FASTCALL QChar::isSpace_helper(uint ucs4) +bool QT_FASTCALL QChar::isSpace_helper(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -740,7 +740,7 @@ bool QT_FASTCALL QChar::isSpace_helper(uint ucs4) Returns \c true if the UCS-4-encoded character specified by \a ucs4 is a mark (Mark_* categories); otherwise returns \c false. */ -bool QChar::isMark(uint ucs4) +bool QChar::isMark(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -764,7 +764,7 @@ bool QChar::isMark(uint ucs4) Returns \c true if the UCS-4-encoded character specified by \a ucs4 is a punctuation mark (Punctuation_* categories); otherwise returns \c false. */ -bool QChar::isPunct(uint ucs4) +bool QChar::isPunct(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -792,7 +792,7 @@ bool QChar::isPunct(uint ucs4) Returns \c true if the UCS-4-encoded character specified by \a ucs4 is a symbol (Symbol_* categories); otherwise returns \c false. */ -bool QChar::isSymbol(uint ucs4) +bool QChar::isSymbol(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -822,7 +822,7 @@ bool QChar::isSymbol(uint ucs4) /*! \internal */ -bool QT_FASTCALL QChar::isLetter_helper(uint ucs4) +bool QT_FASTCALL QChar::isLetter_helper(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -857,7 +857,7 @@ bool QT_FASTCALL QChar::isLetter_helper(uint ucs4) /*! \internal */ -bool QT_FASTCALL QChar::isNumber_helper(uint ucs4) +bool QT_FASTCALL QChar::isNumber_helper(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -886,7 +886,7 @@ bool QT_FASTCALL QChar::isNumber_helper(uint ucs4) /*! \internal */ -bool QT_FASTCALL QChar::isLetterOrNumber_helper(uint ucs4) +bool QT_FASTCALL QChar::isLetterOrNumber_helper(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -1049,7 +1049,7 @@ bool QT_FASTCALL QChar::isLetterOrNumber_helper(uint ucs4) Returns the numeric value of the digit specified by the UCS-4-encoded character, \a ucs4, or -1 if the character is not a digit. */ -int QChar::digitValue(uint ucs4) +int QChar::digitValue(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return -1; @@ -1066,7 +1066,7 @@ int QChar::digitValue(uint ucs4) \overload Returns the category of the UCS-4-encoded character specified by \a ucs4. */ -QChar::Category QChar::category(uint ucs4) +QChar::Category QChar::category(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return QChar::Other_NotAssigned; @@ -1083,7 +1083,7 @@ QChar::Category QChar::category(uint ucs4) \overload Returns the direction of the UCS-4-encoded character specified by \a ucs4. */ -QChar::Direction QChar::direction(uint ucs4) +QChar::Direction QChar::direction(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return QChar::DirL; @@ -1106,7 +1106,7 @@ QChar::Direction QChar::direction(uint ucs4) character specified by \a ucs4 (needed for certain languages such as Arabic or Syriac). */ -QChar::JoiningType QChar::joiningType(uint ucs4) +QChar::JoiningType QChar::joiningType(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return QChar::Joining_None; @@ -1129,7 +1129,7 @@ QChar::JoiningType QChar::joiningType(uint ucs4) Returns information about the joining properties of the UCS-4-encoded character specified by \a ucs4 (needed for certain languages such as Arabic). */ -QChar::Joining QChar::joining(uint ucs4) +QChar::Joining QChar::joining(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return QChar::OtherJoining; @@ -1165,7 +1165,7 @@ QChar::Joining QChar::joining(uint ucs4) \sa mirroredChar() */ -bool QChar::hasMirrored(uint ucs4) +bool QChar::hasMirrored(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return false; @@ -1247,7 +1247,7 @@ bool QChar::hasMirrored(uint ucs4) \sa hasMirrored() */ -uint QChar::mirroredChar(uint ucs4) +uint QChar::mirroredChar(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return ucs4; @@ -1331,7 +1331,7 @@ QString QChar::decomposition(uint ucs4) Returns the tag defining the composition of the UCS-4-encoded character specified by \a ucs4. Returns QChar::NoDecomposition if no decomposition exists. */ -QChar::Decomposition QChar::decompositionTag(uint ucs4) +QChar::Decomposition QChar::decompositionTag(uint ucs4) Q_DECL_NOTHROW { if (ucs4 >= Hangul_SBase && ucs4 < Hangul_SBase + Hangul_SCount) return QChar::Canonical; @@ -1357,7 +1357,7 @@ QChar::Decomposition QChar::decompositionTag(uint ucs4) Returns the combining class for the UCS-4-encoded character specified by \a ucs4, as defined in the Unicode standard. */ -unsigned char QChar::combiningClass(uint ucs4) +unsigned char QChar::combiningClass(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return 0; @@ -1378,7 +1378,7 @@ unsigned char QChar::combiningClass(uint ucs4) Returns the Unicode script property value for the character specified in its UCS-4-encoded form as \a ucs4. */ -QChar::Script QChar::script(uint ucs4) +QChar::Script QChar::script(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return QChar::Script_Unknown; @@ -1396,7 +1396,7 @@ QChar::Script QChar::script(uint ucs4) Returns the Unicode version that introduced the character specified in its UCS-4-encoded form as \a ucs4. */ -QChar::UnicodeVersion QChar::unicodeVersion(uint ucs4) +QChar::UnicodeVersion QChar::unicodeVersion(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return QChar::Unicode_Unassigned; @@ -1406,14 +1406,14 @@ QChar::UnicodeVersion QChar::unicodeVersion(uint ucs4) /*! Returns the most recent supported Unicode version. */ -QChar::UnicodeVersion QChar::currentUnicodeVersion() +QChar::UnicodeVersion QChar::currentUnicodeVersion() Q_DECL_NOTHROW { return UNICODE_DATA_VERSION; } template <typename T> -Q_DECL_CONST_FUNCTION static inline T toLowerCase_helper(T uc) +Q_DECL_CONST_FUNCTION static inline T toLowerCase_helper(T uc) Q_DECL_NOTHROW { const QUnicodeTables::Properties *p = qGetProp(uc); if (p->lowerCaseSpecial) { @@ -1424,7 +1424,7 @@ Q_DECL_CONST_FUNCTION static inline T toLowerCase_helper(T uc) } template <typename T> -Q_DECL_CONST_FUNCTION static inline T toUpperCase_helper(T uc) +Q_DECL_CONST_FUNCTION static inline T toUpperCase_helper(T uc) Q_DECL_NOTHROW { const QUnicodeTables::Properties *p = qGetProp(uc); if (p->upperCaseSpecial) { @@ -1435,7 +1435,7 @@ Q_DECL_CONST_FUNCTION static inline T toUpperCase_helper(T uc) } template <typename T> -Q_DECL_CONST_FUNCTION static inline T toTitleCase_helper(T uc) +Q_DECL_CONST_FUNCTION static inline T toTitleCase_helper(T uc) Q_DECL_NOTHROW { const QUnicodeTables::Properties *p = qGetProp(uc); if (p->titleCaseSpecial) { @@ -1446,7 +1446,7 @@ Q_DECL_CONST_FUNCTION static inline T toTitleCase_helper(T uc) } template <typename T> -Q_DECL_CONST_FUNCTION static inline T toCaseFolded_helper(T uc) +Q_DECL_CONST_FUNCTION static inline T toCaseFolded_helper(T uc) Q_DECL_NOTHROW { const QUnicodeTables::Properties *p = qGetProp(uc); if (p->caseFoldSpecial) { @@ -1469,7 +1469,7 @@ Q_DECL_CONST_FUNCTION static inline T toCaseFolded_helper(T uc) by \a ucs4 if the character is uppercase or titlecase; otherwise returns the character itself. */ -uint QChar::toLower(uint ucs4) +uint QChar::toLower(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return ucs4; @@ -1489,7 +1489,7 @@ uint QChar::toLower(uint ucs4) by \a ucs4 if the character is lowercase or titlecase; otherwise returns the character itself. */ -uint QChar::toUpper(uint ucs4) +uint QChar::toUpper(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return ucs4; @@ -1509,7 +1509,7 @@ uint QChar::toUpper(uint ucs4) by \a ucs4 if the character is lowercase or uppercase; otherwise returns the character itself. */ -uint QChar::toTitleCase(uint ucs4) +uint QChar::toTitleCase(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return ucs4; @@ -1524,7 +1524,7 @@ static inline uint foldCase(const ushort *ch, const ushort *start) return toCaseFolded_helper<uint>(c); } -static inline uint foldCase(uint ch, uint &last) +static inline uint foldCase(uint ch, uint &last) Q_DECL_NOTHROW { uint c = ch; if (QChar(c).isLowSurrogate() && QChar(last).isHighSurrogate()) @@ -1533,7 +1533,7 @@ static inline uint foldCase(uint ch, uint &last) return toCaseFolded_helper<uint>(c); } -static inline ushort foldCase(ushort ch) +static inline ushort foldCase(ushort ch) Q_DECL_NOTHROW { return toCaseFolded_helper<ushort>(ch); } @@ -1550,7 +1550,7 @@ static inline ushort foldCase(ushort ch) Returns the case folded equivalent of the UCS-4-encoded character specified by \a ucs4. For most Unicode characters this is the same as toLower(). */ -uint QChar::toCaseFolded(uint ucs4) +uint QChar::toCaseFolded(uint ucs4) Q_DECL_NOTHROW { if (ucs4 > LastValidCodePoint) return ucs4; diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h index 97e2aa7088..fc1fc7bc16 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -44,9 +44,9 @@ class QString; struct QLatin1Char { public: - Q_DECL_CONSTEXPR inline explicit QLatin1Char(char c) : ch(c) {} - Q_DECL_CONSTEXPR inline char toLatin1() const { return ch; } - Q_DECL_CONSTEXPR inline ushort unicode() const { return ushort(uchar(ch)); } + Q_DECL_CONSTEXPR inline explicit QLatin1Char(char c) Q_DECL_NOTHROW : ch(c) {} + Q_DECL_CONSTEXPR inline char toLatin1() const Q_DECL_NOTHROW { return ch; } + Q_DECL_CONSTEXPR inline ushort unicode() const Q_DECL_NOTHROW { return ushort(uchar(ch)); } private: char ch; @@ -72,19 +72,19 @@ public: LastValidCodePoint = 0x10ffff }; - Q_DECL_CONSTEXPR QChar() : ucs(0) {} - Q_DECL_CONSTEXPR QChar(ushort rc) : ucs(rc){} // implicit - Q_DECL_CONSTEXPR QChar(uchar c, uchar r) : ucs(ushort((r << 8) | c)){} - Q_DECL_CONSTEXPR QChar(short rc) : ucs(ushort(rc)){} // implicit - Q_DECL_CONSTEXPR QChar(uint rc) : ucs(ushort(rc & 0xffff)){} - Q_DECL_CONSTEXPR QChar(int rc) : ucs(ushort(rc & 0xffff)){} - Q_DECL_CONSTEXPR QChar(SpecialCharacter s) : ucs(ushort(s)) {} // implicit - Q_DECL_CONSTEXPR QChar(QLatin1Char ch) : ucs(ch.unicode()) {} // implicit + Q_DECL_CONSTEXPR QChar() Q_DECL_NOTHROW : ucs(0) {} + Q_DECL_CONSTEXPR QChar(ushort rc) Q_DECL_NOTHROW : ucs(rc) {} // implicit + Q_DECL_CONSTEXPR QChar(uchar c, uchar r) Q_DECL_NOTHROW : ucs(ushort((r << 8) | c)) {} + Q_DECL_CONSTEXPR QChar(short rc) Q_DECL_NOTHROW : ucs(ushort(rc)) {} // implicit + Q_DECL_CONSTEXPR QChar(uint rc) Q_DECL_NOTHROW : ucs(ushort(rc & 0xffff)) {} + Q_DECL_CONSTEXPR QChar(int rc) Q_DECL_NOTHROW : ucs(ushort(rc & 0xffff)) {} + Q_DECL_CONSTEXPR QChar(SpecialCharacter s) Q_DECL_NOTHROW : ucs(ushort(s)) {} // implicit + Q_DECL_CONSTEXPR QChar(QLatin1Char ch) Q_DECL_NOTHROW : ucs(ch.unicode()) {} // implicit #ifndef QT_NO_CAST_FROM_ASCII - QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(char c) : ucs(uchar(c)) { } + QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(char c) Q_DECL_NOTHROW : ucs(uchar(c)) { } #ifndef QT_RESTRICTED_CAST_FROM_ASCII - QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(uchar c) : ucs(c) { } + QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(uchar c) Q_DECL_NOTHROW : ucs(c) { } #endif #endif // Unicode information @@ -369,11 +369,11 @@ public: }; // ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO - inline Category category() const { return QChar::category(ucs); } - inline Direction direction() const { return QChar::direction(ucs); } - inline JoiningType joiningType() const { return QChar::joiningType(ucs); } + inline Category category() const Q_DECL_NOTHROW { return QChar::category(ucs); } + inline Direction direction() const Q_DECL_NOTHROW { return QChar::direction(ucs); } + inline JoiningType joiningType() const Q_DECL_NOTHROW { return QChar::joiningType(ucs); } #if QT_DEPRECATED_SINCE(5, 3) - QT_DEPRECATED inline Joining joining() const + QT_DEPRECATED inline Joining joining() const Q_DECL_NOTHROW { switch (QChar::joiningType(ucs)) { case QChar::Joining_Causing: return QChar::Center; @@ -386,194 +386,177 @@ public: } } #endif - inline unsigned char combiningClass() const { return QChar::combiningClass(ucs); } + inline unsigned char combiningClass() const Q_DECL_NOTHROW { return QChar::combiningClass(ucs); } - inline QChar mirroredChar() const { return QChar::mirroredChar(ucs); } - inline bool hasMirrored() const { return QChar::hasMirrored(ucs); } + inline QChar mirroredChar() const Q_DECL_NOTHROW { return QChar::mirroredChar(ucs); } + inline bool hasMirrored() const Q_DECL_NOTHROW { return QChar::hasMirrored(ucs); } QString decomposition() const; - inline Decomposition decompositionTag() const { return QChar::decompositionTag(ucs); } + inline Decomposition decompositionTag() const Q_DECL_NOTHROW { return QChar::decompositionTag(ucs); } - inline int digitValue() const { return QChar::digitValue(ucs); } - inline QChar toLower() const { return QChar::toLower(ucs); } - inline QChar toUpper() const { return QChar::toUpper(ucs); } - inline QChar toTitleCase() const { return QChar::toTitleCase(ucs); } - inline QChar toCaseFolded() const { return QChar::toCaseFolded(ucs); } + inline int digitValue() const Q_DECL_NOTHROW { return QChar::digitValue(ucs); } + inline QChar toLower() const Q_DECL_NOTHROW { return QChar::toLower(ucs); } + inline QChar toUpper() const Q_DECL_NOTHROW { return QChar::toUpper(ucs); } + inline QChar toTitleCase() const Q_DECL_NOTHROW { return QChar::toTitleCase(ucs); } + inline QChar toCaseFolded() const Q_DECL_NOTHROW { return QChar::toCaseFolded(ucs); } - inline Script script() const { return QChar::script(ucs); } + inline Script script() const Q_DECL_NOTHROW { return QChar::script(ucs); } - inline UnicodeVersion unicodeVersion() const { return QChar::unicodeVersion(ucs); } + inline UnicodeVersion unicodeVersion() const Q_DECL_NOTHROW { return QChar::unicodeVersion(ucs); } #if QT_DEPRECATED_SINCE(5, 0) - QT_DEPRECATED Q_DECL_CONSTEXPR inline char toAscii() const { return toLatin1(); } + QT_DEPRECATED Q_DECL_CONSTEXPR inline char toAscii() const Q_DECL_NOTHROW { return toLatin1(); } #endif - Q_DECL_CONSTEXPR inline char toLatin1() const; - Q_DECL_CONSTEXPR inline ushort unicode() const { return ucs; } - inline ushort &unicode() { return ucs; } + Q_DECL_CONSTEXPR inline char toLatin1() const Q_DECL_NOTHROW { return ucs > 0xff ? '\0' : char(ucs); } + Q_DECL_CONSTEXPR inline ushort unicode() const Q_DECL_NOTHROW { return ucs; } + Q_DECL_RELAXED_CONSTEXPR inline ushort &unicode() Q_DECL_NOTHROW { return ucs; } #if QT_DEPRECATED_SINCE(5, 0) - QT_DEPRECATED static Q_DECL_CONSTEXPR inline QChar fromAscii(char c) + QT_DEPRECATED static Q_DECL_CONSTEXPR inline QChar fromAscii(char c) Q_DECL_NOTHROW { return fromLatin1(c); } #endif - Q_DECL_CONSTEXPR static inline QChar fromLatin1(char c); - - Q_DECL_CONSTEXPR inline bool isNull() const { return ucs == 0; } - - inline bool isPrint() const { return QChar::isPrint(ucs); } - Q_DECL_CONSTEXPR inline bool isSpace() const { return QChar::isSpace(ucs); } - inline bool isMark() const { return QChar::isMark(ucs); } - inline bool isPunct() const { return QChar::isPunct(ucs); } - inline bool isSymbol() const { return QChar::isSymbol(ucs); } - Q_DECL_CONSTEXPR inline bool isLetter() const { return QChar::isLetter(ucs); } - Q_DECL_CONSTEXPR inline bool isNumber() const { return QChar::isNumber(ucs); } - Q_DECL_CONSTEXPR inline bool isLetterOrNumber() const { return QChar::isLetterOrNumber(ucs); } - Q_DECL_CONSTEXPR inline bool isDigit() const { return QChar::isDigit(ucs); } - Q_DECL_CONSTEXPR inline bool isLower() const { return QChar::isLower(ucs); } - Q_DECL_CONSTEXPR inline bool isUpper() const { return QChar::isUpper(ucs); } - Q_DECL_CONSTEXPR inline bool isTitleCase() const { return QChar::isTitleCase(ucs); } - - Q_DECL_CONSTEXPR inline bool isNonCharacter() const { return QChar::isNonCharacter(ucs); } - Q_DECL_CONSTEXPR inline bool isHighSurrogate() const { return QChar::isHighSurrogate(ucs); } - Q_DECL_CONSTEXPR inline bool isLowSurrogate() const { return QChar::isLowSurrogate(ucs); } - Q_DECL_CONSTEXPR inline bool isSurrogate() const { return QChar::isSurrogate(ucs); } - - Q_DECL_CONSTEXPR inline uchar cell() const { return uchar(ucs & 0xff); } - Q_DECL_CONSTEXPR inline uchar row() const { return uchar((ucs>>8)&0xff); } - inline void setCell(uchar cell); - inline void setRow(uchar row); - - static Q_DECL_CONSTEXPR inline bool isNonCharacter(uint ucs4) + static Q_DECL_CONSTEXPR inline QChar fromLatin1(char c) Q_DECL_NOTHROW { return QChar(ushort(uchar(c))); } + + Q_DECL_CONSTEXPR inline bool isNull() const Q_DECL_NOTHROW { return ucs == 0; } + + inline bool isPrint() const Q_DECL_NOTHROW { return QChar::isPrint(ucs); } + Q_DECL_CONSTEXPR inline bool isSpace() const Q_DECL_NOTHROW { return QChar::isSpace(ucs); } + inline bool isMark() const Q_DECL_NOTHROW { return QChar::isMark(ucs); } + inline bool isPunct() const Q_DECL_NOTHROW { return QChar::isPunct(ucs); } + inline bool isSymbol() const Q_DECL_NOTHROW { return QChar::isSymbol(ucs); } + Q_DECL_CONSTEXPR inline bool isLetter() const Q_DECL_NOTHROW { return QChar::isLetter(ucs); } + Q_DECL_CONSTEXPR inline bool isNumber() const Q_DECL_NOTHROW { return QChar::isNumber(ucs); } + Q_DECL_CONSTEXPR inline bool isLetterOrNumber() const Q_DECL_NOTHROW { return QChar::isLetterOrNumber(ucs); } + Q_DECL_CONSTEXPR inline bool isDigit() const Q_DECL_NOTHROW { return QChar::isDigit(ucs); } + Q_DECL_CONSTEXPR inline bool isLower() const Q_DECL_NOTHROW { return QChar::isLower(ucs); } + Q_DECL_CONSTEXPR inline bool isUpper() const Q_DECL_NOTHROW { return QChar::isUpper(ucs); } + Q_DECL_CONSTEXPR inline bool isTitleCase() const Q_DECL_NOTHROW { return QChar::isTitleCase(ucs); } + + Q_DECL_CONSTEXPR inline bool isNonCharacter() const Q_DECL_NOTHROW { return QChar::isNonCharacter(ucs); } + Q_DECL_CONSTEXPR inline bool isHighSurrogate() const Q_DECL_NOTHROW { return QChar::isHighSurrogate(ucs); } + Q_DECL_CONSTEXPR inline bool isLowSurrogate() const Q_DECL_NOTHROW { return QChar::isLowSurrogate(ucs); } + Q_DECL_CONSTEXPR inline bool isSurrogate() const Q_DECL_NOTHROW { return QChar::isSurrogate(ucs); } + + Q_DECL_CONSTEXPR inline uchar cell() const Q_DECL_NOTHROW { return uchar(ucs & 0xff); } + Q_DECL_CONSTEXPR inline uchar row() const Q_DECL_NOTHROW { return uchar((ucs>>8)&0xff); } + Q_DECL_RELAXED_CONSTEXPR inline void setCell(uchar acell) Q_DECL_NOTHROW { ucs = ushort((ucs & 0xff00) + acell); } + Q_DECL_RELAXED_CONSTEXPR inline void setRow(uchar arow) Q_DECL_NOTHROW { ucs = ushort((ushort(arow)<<8) + (ucs&0xff)); } + + static Q_DECL_CONSTEXPR inline bool isNonCharacter(uint ucs4) Q_DECL_NOTHROW { return ucs4 >= 0xfdd0 && (ucs4 <= 0xfdef || (ucs4 & 0xfffe) == 0xfffe); } - static Q_DECL_CONSTEXPR inline bool isHighSurrogate(uint ucs4) + static Q_DECL_CONSTEXPR inline bool isHighSurrogate(uint ucs4) Q_DECL_NOTHROW { return ((ucs4 & 0xfffffc00) == 0xd800); } - static Q_DECL_CONSTEXPR inline bool isLowSurrogate(uint ucs4) + static Q_DECL_CONSTEXPR inline bool isLowSurrogate(uint ucs4) Q_DECL_NOTHROW { return ((ucs4 & 0xfffffc00) == 0xdc00); } - static Q_DECL_CONSTEXPR inline bool isSurrogate(uint ucs4) + static Q_DECL_CONSTEXPR inline bool isSurrogate(uint ucs4) Q_DECL_NOTHROW { return (ucs4 - 0xd800u < 2048u); } - static Q_DECL_CONSTEXPR inline bool requiresSurrogates(uint ucs4) + static Q_DECL_CONSTEXPR inline bool requiresSurrogates(uint ucs4) Q_DECL_NOTHROW { return (ucs4 >= 0x10000); } - static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(ushort high, ushort low) + static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(ushort high, ushort low) Q_DECL_NOTHROW { return (uint(high)<<10) + low - 0x35fdc00; } - static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(QChar high, QChar low) + static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(QChar high, QChar low) Q_DECL_NOTHROW { return surrogateToUcs4(high.ucs, low.ucs); } - static Q_DECL_CONSTEXPR inline ushort highSurrogate(uint ucs4) + static Q_DECL_CONSTEXPR inline ushort highSurrogate(uint ucs4) Q_DECL_NOTHROW { return ushort((ucs4>>10) + 0xd7c0); } - static Q_DECL_CONSTEXPR inline ushort lowSurrogate(uint ucs4) + static Q_DECL_CONSTEXPR inline ushort lowSurrogate(uint ucs4) Q_DECL_NOTHROW { return ushort(ucs4%0x400 + 0xdc00); } - static Category QT_FASTCALL category(uint ucs4) Q_DECL_CONST_FUNCTION; - static Direction QT_FASTCALL direction(uint ucs4) Q_DECL_CONST_FUNCTION; - static JoiningType QT_FASTCALL joiningType(uint ucs4) Q_DECL_CONST_FUNCTION; + static Category QT_FASTCALL category(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static Direction QT_FASTCALL direction(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static JoiningType QT_FASTCALL joiningType(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; #if QT_DEPRECATED_SINCE(5, 3) - QT_DEPRECATED static Joining QT_FASTCALL joining(uint ucs4) Q_DECL_CONST_FUNCTION; + QT_DEPRECATED static Joining QT_FASTCALL joining(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; #endif - static unsigned char QT_FASTCALL combiningClass(uint ucs4) Q_DECL_CONST_FUNCTION; + static unsigned char QT_FASTCALL combiningClass(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; - static uint QT_FASTCALL mirroredChar(uint ucs4) Q_DECL_CONST_FUNCTION; - static bool QT_FASTCALL hasMirrored(uint ucs4) Q_DECL_CONST_FUNCTION; + static uint QT_FASTCALL mirroredChar(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static bool QT_FASTCALL hasMirrored(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; static QString QT_FASTCALL decomposition(uint ucs4); - static Decomposition QT_FASTCALL decompositionTag(uint ucs4) Q_DECL_CONST_FUNCTION; + static Decomposition QT_FASTCALL decompositionTag(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; - static int QT_FASTCALL digitValue(uint ucs4) Q_DECL_CONST_FUNCTION; - static uint QT_FASTCALL toLower(uint ucs4) Q_DECL_CONST_FUNCTION; - static uint QT_FASTCALL toUpper(uint ucs4) Q_DECL_CONST_FUNCTION; - static uint QT_FASTCALL toTitleCase(uint ucs4) Q_DECL_CONST_FUNCTION; - static uint QT_FASTCALL toCaseFolded(uint ucs4) Q_DECL_CONST_FUNCTION; + static int QT_FASTCALL digitValue(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static uint QT_FASTCALL toLower(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static uint QT_FASTCALL toUpper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static uint QT_FASTCALL toTitleCase(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static uint QT_FASTCALL toCaseFolded(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; - static Script QT_FASTCALL script(uint ucs4) Q_DECL_CONST_FUNCTION; + static Script QT_FASTCALL script(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; - static UnicodeVersion QT_FASTCALL unicodeVersion(uint ucs4) Q_DECL_CONST_FUNCTION; + static UnicodeVersion QT_FASTCALL unicodeVersion(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; - static UnicodeVersion QT_FASTCALL currentUnicodeVersion() Q_DECL_CONST_FUNCTION; + static UnicodeVersion QT_FASTCALL currentUnicodeVersion() Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; - static bool QT_FASTCALL isPrint(uint ucs4) Q_DECL_CONST_FUNCTION; - static Q_DECL_CONSTEXPR inline bool isSpace(uint ucs4) Q_DECL_CONST_FUNCTION; - static bool QT_FASTCALL isMark(uint ucs4) Q_DECL_CONST_FUNCTION; - static bool QT_FASTCALL isPunct(uint ucs4) Q_DECL_CONST_FUNCTION; - static bool QT_FASTCALL isSymbol(uint ucs4) Q_DECL_CONST_FUNCTION; - static Q_DECL_CONSTEXPR inline bool isLetter(uint ucs4) Q_DECL_CONST_FUNCTION; - static Q_DECL_CONSTEXPR inline bool isNumber(uint ucs4) Q_DECL_CONST_FUNCTION; - static Q_DECL_CONSTEXPR inline bool isLetterOrNumber(uint ucs4) Q_DECL_CONST_FUNCTION; - static Q_DECL_CONSTEXPR inline bool isDigit(uint ucs4) Q_DECL_CONST_FUNCTION; - static Q_DECL_CONSTEXPR inline bool isLower(uint ucs4) Q_DECL_CONST_FUNCTION; - static Q_DECL_CONSTEXPR inline bool isUpper(uint ucs4) Q_DECL_CONST_FUNCTION; - static Q_DECL_CONSTEXPR inline bool isTitleCase(uint ucs4) Q_DECL_CONST_FUNCTION; + static bool QT_FASTCALL isPrint(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static Q_DECL_CONSTEXPR inline bool isSpace(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION + { + // note that [0x09..0x0d] + 0x85 are exceptional Cc-s and must be handled explicitly + return ucs4 == 0x20 || (ucs4 <= 0x0d && ucs4 >= 0x09) + || (ucs4 > 127 && (ucs4 == 0x85 || ucs4 == 0xa0 || QChar::isSpace_helper(ucs4))); + } + static bool QT_FASTCALL isMark(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static bool QT_FASTCALL isPunct(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static bool QT_FASTCALL isSymbol(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static Q_DECL_CONSTEXPR inline bool isLetter(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION + { + return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z')) + || (ucs4 > 127 && QChar::isLetter_helper(ucs4)); + } + static Q_DECL_CONSTEXPR inline bool isNumber(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION + { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::isNumber_helper(ucs4)); } + static Q_DECL_CONSTEXPR inline bool isLetterOrNumber(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION + { + return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z')) + || (ucs4 >= '0' && ucs4 <= '9') + || (ucs4 > 127 && QChar::isLetterOrNumber_helper(ucs4)); + } + static Q_DECL_CONSTEXPR inline bool isDigit(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION + { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::category(ucs4) == Number_DecimalDigit); } + static Q_DECL_CONSTEXPR inline bool isLower(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION + { return (ucs4 <= 'z' && ucs4 >= 'a') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Lowercase); } + static Q_DECL_CONSTEXPR inline bool isUpper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION + { return (ucs4 <= 'Z' && ucs4 >= 'A') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Uppercase); } + static Q_DECL_CONSTEXPR inline bool isTitleCase(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION + { return ucs4 > 127 && QChar::category(ucs4) == Letter_Titlecase; } private: - static bool QT_FASTCALL isSpace_helper(uint ucs4) Q_DECL_CONST_FUNCTION; - static bool QT_FASTCALL isLetter_helper(uint ucs4) Q_DECL_CONST_FUNCTION; - static bool QT_FASTCALL isNumber_helper(uint ucs4) Q_DECL_CONST_FUNCTION; - static bool QT_FASTCALL isLetterOrNumber_helper(uint ucs4) Q_DECL_CONST_FUNCTION; + static bool QT_FASTCALL isSpace_helper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static bool QT_FASTCALL isLetter_helper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static bool QT_FASTCALL isNumber_helper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; + static bool QT_FASTCALL isLetterOrNumber_helper(uint ucs4) Q_DECL_NOTHROW Q_DECL_CONST_FUNCTION; #ifdef QT_NO_CAST_FROM_ASCII - QChar(char c); - QChar(uchar c); + QChar(char c) Q_DECL_NOTHROW; + QChar(uchar c) Q_DECL_NOTHROW; #endif - friend Q_DECL_CONSTEXPR bool operator==(QChar, QChar); - friend Q_DECL_CONSTEXPR bool operator< (QChar, QChar); + friend Q_DECL_CONSTEXPR bool operator==(QChar, QChar) Q_DECL_NOTHROW; + friend Q_DECL_CONSTEXPR bool operator< (QChar, QChar) Q_DECL_NOTHROW; ushort ucs; }; Q_DECLARE_TYPEINFO(QChar, Q_MOVABLE_TYPE); -Q_DECL_CONSTEXPR inline char QChar::toLatin1() const { return ucs > 0xff ? '\0' : char(ucs); } -Q_DECL_CONSTEXPR inline QChar QChar::fromLatin1(char c) { return QChar(ushort(uchar(c))); } - -inline void QChar::setCell(uchar acell) -{ ucs = ushort((ucs & 0xff00) + acell); } -inline void QChar::setRow(uchar arow) -{ ucs = ushort((ushort(arow)<<8) + (ucs&0xff)); } - -Q_DECL_CONSTEXPR inline bool QChar::isSpace(uint ucs4) -{ - // note that [0x09..0x0d] + 0x85 are exceptional Cc-s and must be handled explicitly - return ucs4 == 0x20 || (ucs4 <= 0x0d && ucs4 >= 0x09) - || (ucs4 > 127 && (ucs4 == 0x85 || ucs4 == 0xa0 || QChar::isSpace_helper(ucs4))); -} -Q_DECL_CONSTEXPR inline bool QChar::isLetter(uint ucs4) -{ - return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z')) - || (ucs4 > 127 && QChar::isLetter_helper(ucs4)); -} -Q_DECL_CONSTEXPR inline bool QChar::isNumber(uint ucs4) -{ return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::isNumber_helper(ucs4)); } -Q_DECL_CONSTEXPR inline bool QChar::isLetterOrNumber(uint ucs4) -{ - return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z')) - || (ucs4 >= '0' && ucs4 <= '9') - || (ucs4 > 127 && QChar::isLetterOrNumber_helper(ucs4)); -} -Q_DECL_CONSTEXPR inline bool QChar::isDigit(uint ucs4) -{ return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::category(ucs4) == Number_DecimalDigit); } -Q_DECL_CONSTEXPR inline bool QChar::isLower(uint ucs4) -{ return (ucs4 <= 'z' && ucs4 >= 'a') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Lowercase); } -Q_DECL_CONSTEXPR inline bool QChar::isUpper(uint ucs4) -{ return (ucs4 <= 'Z' && ucs4 >= 'A') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Uppercase); } -Q_DECL_CONSTEXPR inline bool QChar::isTitleCase(uint ucs4) -{ return ucs4 > 127 && QChar::category(ucs4) == Letter_Titlecase; } - -Q_DECL_CONSTEXPR inline bool operator==(QChar c1, QChar c2) { return c1.ucs == c2.ucs; } -Q_DECL_CONSTEXPR inline bool operator< (QChar c1, QChar c2) { return c1.ucs < c2.ucs; } +Q_DECL_CONSTEXPR inline bool operator==(QChar c1, QChar c2) Q_DECL_NOTHROW { return c1.ucs == c2.ucs; } +Q_DECL_CONSTEXPR inline bool operator< (QChar c1, QChar c2) Q_DECL_NOTHROW { return c1.ucs < c2.ucs; } Q_DECL_CONSTEXPR inline bool operator!=(QChar c1, QChar c2) { return !operator==(c1, c2); } Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) { return !operator< (c1, c2); } diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp index 7f898f68a8..51723f4a57 100644 --- a/src/corelib/tools/qcommandlineoption.cpp +++ b/src/corelib/tools/qcommandlineoption.cpp @@ -42,6 +42,7 @@ class QCommandLineOptionPrivate : public QSharedData { public: inline QCommandLineOptionPrivate() + : hidden(false) { } void setNames(const QStringList &nameList); @@ -58,6 +59,9 @@ public: //! The list of default values used for this option. QStringList defaultValues; + + //! Show or hide in --help + bool hidden; }; /*! @@ -362,4 +366,30 @@ QStringList QCommandLineOption::defaultValues() const return d->defaultValues; } +/*! + Sets whether to hide this option in the user-visible help output. + + All options are visible by default. Setting \a hidden to true for + a particular option makes it internal, i.e. not listed in the help output. + + \since 5.6 + \sa isHidden + */ +void QCommandLineOption::setHidden(bool hide) +{ + d->hidden = hide; +} + +/*! + Returns true if this option is omitted from the help output, + false if the option is listed. + + \since 5.6 + \sa setHidden() + */ +bool QCommandLineOption::isHidden() const +{ + return d->hidden; +} + QT_END_NAMESPACE diff --git a/src/corelib/tools/qcommandlineoption.h b/src/corelib/tools/qcommandlineoption.h index cf4160ecd2..85fc5ca6dd 100644 --- a/src/corelib/tools/qcommandlineoption.h +++ b/src/corelib/tools/qcommandlineoption.h @@ -77,6 +77,9 @@ public: void setDefaultValues(const QStringList &defaultValues); QStringList defaultValues() const; + void setHidden(bool hidden); + bool isHidden() const; + private: QSharedDataPointer<QCommandLineOptionPrivate> d; }; diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index 21bc14a272..7e49253f9b 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -53,6 +53,7 @@ class QCommandLineParserPrivate public: inline QCommandLineParserPrivate() : singleDashWordOptionMode(QCommandLineParser::ParseAsCompactedShortOptions), + optionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsOptions), builtinVersionOption(false), builtinHelpOption(false), needsParsing(true) @@ -103,6 +104,9 @@ public: //! The parsing mode for "-abc" QCommandLineParser::SingleDashWordOptionMode singleDashWordOptionMode; + //! How to parse "arg -option" + QCommandLineParser::OptionsAfterPositionalArgumentsMode optionsAfterPositionalArgumentsMode; + //! Whether addVersionOption was called bool builtinVersionOption; @@ -299,6 +303,41 @@ void QCommandLineParser::setSingleDashWordOptionMode(QCommandLineParser::SingleD } /*! + \enum QCommandLineParser::OptionsAfterPositionalArgumentsMode + + This enum describes the way the parser interprets options that + occur after positional arguments. + + \value ParseAsOptions \c{application argument --opt -t} is interpreted as setting + the options \c{opt} and \c{t}, just like \c{application --opt -t argument} would do. + This is the default parsing mode. In order to specify that \c{--opt} and \c{-t} + are positional arguments instead, the user can use \c{--}, as in + \c{application argument -- --opt -t}. + + \value ParseAsPositionalArguments \c{application argument --opt} is interpreted as + having two positional arguments, \c{argument} and \c{--opt}. + This mode is useful for executables that aim to launch other executables + (e.g. wrappers, debugging tools, etc.) or that support internal commands + followed by options for the command. \c{argument} is the name of the command, + and all options occurring after it can be collected and parsed by another + command line parser, possibly in another executable. + + \sa setOptionsAfterPositionalArgumentsMode() + + \since 5.5 +*/ + +/*! + Sets the parsing mode to \a parsingMode. + This must be called before process() or parse(). + \since 5.5 +*/ +void QCommandLineParser::setOptionsAfterPositionalArgumentsMode(QCommandLineParser::OptionsAfterPositionalArgumentsMode parsingMode) +{ + d->optionsAfterPositionalArgumentsMode = parsingMode; +} + +/*! Adds the option \a option to look for while parsing. Returns \c true if adding the option was successful; otherwise returns \c false. @@ -640,7 +679,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args) const QLatin1Char dashChar('-'); const QLatin1Char assignChar('='); - bool doubleDashFound = false; + bool forcePositional = false; errorText.clear(); positionalArgumentList.clear(); optionNames.clear(); @@ -658,7 +697,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args) for (; argumentIterator != args.end() ; ++argumentIterator) { QString argument = *argumentIterator; - if (doubleDashFound) { + if (forcePositional) { positionalArgumentList.append(argument); } else if (argument.startsWith(doubleDashString)) { if (argument.length() > 2) { @@ -670,7 +709,7 @@ bool QCommandLineParserPrivate::parse(const QStringList &args) error = true; } } else { - doubleDashFound = true; + forcePositional = true; } } else if (argument.startsWith(dashChar)) { if (argument.size() == 1) { // single dash ("stdin") @@ -722,6 +761,8 @@ bool QCommandLineParserPrivate::parse(const QStringList &args) } } else { positionalArgumentList.append(argument); + if (optionsAfterPositionalArgumentsMode == QCommandLineParser::ParseAsPositionalArguments) + forcePositional = true; } if (argumentIterator == args.end()) break; @@ -1062,6 +1103,8 @@ QString QCommandLineParserPrivate::helpText() const ++longestOptionNameString; for (int i = 0; i < commandLineOptionList.count(); ++i) { const QCommandLineOption &option = commandLineOptionList.at(i); + if (option.isHidden()) + continue; text += wrapText(optionNameList.at(i), longestOptionNameString, option.description()); } if (!positionalArgumentDefinitions.isEmpty()) { diff --git a/src/corelib/tools/qcommandlineparser.h b/src/corelib/tools/qcommandlineparser.h index 91a799b4d5..8c528ba69e 100644 --- a/src/corelib/tools/qcommandlineparser.h +++ b/src/corelib/tools/qcommandlineparser.h @@ -57,6 +57,12 @@ public: }; void setSingleDashWordOptionMode(SingleDashWordOptionMode parsingMode); + enum OptionsAfterPositionalArgumentsMode { + ParseAsOptions, + ParseAsPositionalArguments + }; + void setOptionsAfterPositionalArgumentsMode(OptionsAfterPositionalArgumentsMode mode); + bool addOption(const QCommandLineOption &commandLineOption); bool addOptions(const QList<QCommandLineOption> &options); diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index a9ece12670..c4c8c8f3cc 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -38,10 +38,9 @@ #include <QtCore/qchar.h> #include <QtCore/qiterator.h> #include <QtCore/qlist.h> -#include <QtCore/qpair.h> #include <QtCore/qrefcount.h> +#include <QtCore/qhashfunctions.h> -#include <numeric> // for std::accumulate #ifdef Q_COMPILER_INITIALIZER_LISTS #include <initializer_list> #endif @@ -54,101 +53,6 @@ QT_BEGIN_NAMESPACE -class QBitArray; -class QByteArray; -class QString; -class QStringRef; -class QLatin1String; - -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHashBits(const void *p, size_t size, uint seed = 0) Q_DECL_NOTHROW; - -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uchar key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(signed char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ushort key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(short key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uint key, uint seed = 0) Q_DECL_NOTHROW { return key ^ seed; } -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(int key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ulong key, uint seed = 0) Q_DECL_NOTHROW -{ - return (sizeof(ulong) > sizeof(uint)) - ? (uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed) - : (uint(key & (~0U)) ^ seed); -} -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(long key, uint seed = 0) Q_DECL_NOTHROW { return qHash(ulong(key), seed); } -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW -{ - return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed; -} -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); } -Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW; -Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW; -#ifndef Q_OS_DARWIN -Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW; -#endif -Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(const QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); } -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW; -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW; -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QStringRef &key, uint seed = 0) Q_DECL_NOTHROW; -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed = 0) Q_DECL_NOTHROW; -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW; -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QString &key) Q_DECL_NOTHROW; -Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QStringRef &key) Q_DECL_NOTHROW; - -template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW -{ - return qHash(reinterpret_cast<quintptr>(key), seed); -} -template<typename T> inline uint qHash(const T &t, uint seed) - Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t))) -{ return (qHash(t) ^ seed); } - -namespace QtPrivate { - -struct QHashCombine { - typedef uint result_type; - template <typename T> - Q_DECL_CONSTEXPR result_type operator()(uint seed, const T &t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t))) - // combiner taken from N3876 / boost::hash_combine - { return seed ^ (qHash(t) + 0x9e3779b9 + (seed << 6) + (seed >> 2)) ; } -}; - -struct QHashCombineCommutative { - // QHashCombine is a good hash combiner, but is not commutative, - // ie. it depends on the order of the input elements. That is - // usually what we want: {0,1,3} should hash differently than - // {1,3,0}. Except when it isn't (e.g. for QSet and - // QHash). Therefore, provide a commutative combiner, too. - typedef uint result_type; - template <typename T> - Q_DECL_CONSTEXPR result_type operator()(uint seed, const T &t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t))) - { return seed + qHash(t); } // don't use xor! -}; - -} // namespace QtPrivate - -template <typename InputIterator> -inline uint qHashRange(InputIterator first, InputIterator last, uint seed = 0) - Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(*first))) // assume iterator operations don't throw -{ - return std::accumulate(first, last, seed, QtPrivate::QHashCombine()); -} - -template <typename InputIterator> -inline uint qHashRangeCommutative(InputIterator first, InputIterator last, uint seed = 0) - Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(*first))) // assume iterator operations don't throw -{ - return std::accumulate(first, last, seed, QtPrivate::QHashCombineCommutative()); -} - -template <typename T1, typename T2> inline uint qHash(const QPair<T1, T2> &key, uint seed = 0) - Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed))) -{ - uint h1 = qHash(key.first, seed); - uint h2 = qHash(key.second, seed); - return ((h1 << 16) | (h1 >> 16)) ^ h2 ^ seed; -} - struct Q_CORE_EXPORT QHashData { struct Node { diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h new file mode 100644 index 0000000000..e15fbb07ac --- /dev/null +++ b/src/corelib/tools/qhashfunctions.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHASHFUNCTIONS_H +#define QHASHFUNCTIONS_H + +#include <QtCore/qchar.h> +#include <QtCore/qpair.h> + +#include <numeric> // for std::accumulate + +#if 0 +#pragma qt_class(QHashFunctions) +#endif + +#if defined(Q_CC_MSVC) +#pragma warning( push ) +#pragma warning( disable : 4311 ) // disable pointer truncation warning +#pragma warning( disable : 4127 ) // conditional expression is constant +#endif + +QT_BEGIN_NAMESPACE + +class QBitArray; +class QByteArray; +class QString; +class QStringRef; +class QLatin1String; + +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHashBits(const void *p, size_t size, uint seed = 0) Q_DECL_NOTHROW; + +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uchar key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(signed char key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ushort key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(short key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(uint key, uint seed = 0) Q_DECL_NOTHROW { return key ^ seed; } +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(int key, uint seed = 0) Q_DECL_NOTHROW { return uint(key) ^ seed; } +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(ulong key, uint seed = 0) Q_DECL_NOTHROW +{ + return (sizeof(ulong) > sizeof(uint)) + ? (uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed) + : (uint(key & (~0U)) ^ seed); +} +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(long key, uint seed = 0) Q_DECL_NOTHROW { return qHash(ulong(key), seed); } +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW +{ + return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)) ^ seed; +} +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); } +Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW; +Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW; +#ifndef Q_OS_DARWIN +Q_CORE_EXPORT Q_DECL_CONST_FUNCTION uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW; +#endif +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline uint qHash(const QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); } +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW; +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW; +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QStringRef &key, uint seed = 0) Q_DECL_NOTHROW; +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed = 0) Q_DECL_NOTHROW; +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW; +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QString &key) Q_DECL_NOTHROW; +Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QStringRef &key) Q_DECL_NOTHROW; + +template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW +{ + return qHash(reinterpret_cast<quintptr>(key), seed); +} +template<typename T> inline uint qHash(const T &t, uint seed) + Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t))) +{ return qHash(t) ^ seed; } + +namespace QtPrivate { + +struct QHashCombine { + typedef uint result_type; + template <typename T> + Q_DECL_CONSTEXPR result_type operator()(uint seed, const T &t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t))) + // combiner taken from N3876 / boost::hash_combine + { return seed ^ (qHash(t) + 0x9e3779b9 + (seed << 6) + (seed >> 2)) ; } +}; + +struct QHashCombineCommutative { + // QHashCombine is a good hash combiner, but is not commutative, + // ie. it depends on the order of the input elements. That is + // usually what we want: {0,1,3} should hash differently than + // {1,3,0}. Except when it isn't (e.g. for QSet and + // QHash). Therefore, provide a commutative combiner, too. + typedef uint result_type; + template <typename T> + Q_DECL_CONSTEXPR result_type operator()(uint seed, const T &t) const Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t))) + { return seed + qHash(t); } // don't use xor! +}; + +} // namespace QtPrivate + +template <typename InputIterator> +inline uint qHashRange(InputIterator first, InputIterator last, uint seed = 0) + Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(*first))) // assume iterator operations don't throw +{ + return std::accumulate(first, last, seed, QtPrivate::QHashCombine()); +} + +template <typename InputIterator> +inline uint qHashRangeCommutative(InputIterator first, InputIterator last, uint seed = 0) + Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(*first))) // assume iterator operations don't throw +{ + return std::accumulate(first, last, seed, QtPrivate::QHashCombineCommutative()); +} + +template <typename T1, typename T2> inline uint qHash(const QPair<T1, T2> &key, uint seed = 0) + Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed))) +{ + uint h1 = qHash(key.first, seed); + uint h2 = qHash(key.second, seed); + return ((h1 << 16) | (h1 >> 16)) ^ h2 ^ seed; +} + +QT_END_NAMESPACE + +#if defined(Q_CC_MSVC) +#pragma warning( pop ) +#endif + +#endif // QHASHFUNCTIONS_H diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index db00dcb458..f4901d336e 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -584,6 +584,65 @@ void **QListData::erase(void **xi) \sa operator==() */ +/*! \fn bool operator<(const QList<T> &lhs, const QList<T> &rhs) + \since 5.6 + \relates QList + + Returns \c true if list \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically less than} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator<=(const QList<T> &lhs, const QList<T> &rhs) + \since 5.6 + \relates QList + + Returns \c true if list \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically less than or equal to} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator>(const QList<T> &lhs, const QList<T> &rhs) + \since 5.6 + \relates QList + + Returns \c true if list \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically greater than} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator>=(const QList<T> &lhs, const QList<T> &rhs) + \since 5.6 + \relates QList + + Returns \c true if list \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically greater than or equal to} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! + \fn uint qHash(const QList<T> &key, uint seed = 0) + \since 5.6 + \relates QList + + Returns the hash value for \a key, + using \a seed to seed the calculation. + + This function requires qHash() to be overloaded for the value type \c T. +*/ + /*! \fn int QList::size() const @@ -1000,6 +1059,52 @@ void **QListData::erase(void **xi) \sa constBegin(), end() */ +/*! \fn QList::reverse_iterator QList::rbegin() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + item in the list, in reverse order. + + \sa begin(), crbegin(), rend() +*/ + +/*! \fn QList::const_reverse_iterator QList::rbegin() const + \since 5.6 + \overload +*/ + +/*! \fn QList::const_reverse_iterator QList::crbegin() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + item in the list, in reverse order. + + \sa begin(), rbegin(), rend() +*/ + +/*! \fn QList::reverse_iterator QList::rend() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past + the last item in the list, in reverse order. + + \sa end(), crend(), rbegin() +*/ + +/*! \fn QList::const_reverse_iterator QList::rend() const + \since 5.6 + \overload +*/ + +/*! \fn QList::const_reverse_iterator QList::crend() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one + past the last item in the list, in reverse order. + + \sa end(), rend(), rbegin() +*/ + /*! \fn QList::iterator QList::erase(iterator pos) Removes the item associated with the iterator \a pos from the @@ -1070,6 +1175,38 @@ void **QListData::erase(void **xi) Typedef for const T &. Provided for STL compatibility. */ +/*! \typedef QList::reverse_iterator + \since 5.6 + + The QList::reverse_iterator typedef provides an STL-style non-const + reverse iterator for QList. + + It is simply a typedef for \c{std::reverse_iterator<iterator>}. + + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + + \sa QList::rbegin(), QList::rend(), QList::const_reverse_iterator, QList::iterator +*/ + +/*! \typedef QList::const_reverse_iterator + \since 5.6 + + The QList::const_reverse_iterator typedef provides an STL-style const + reverse iterator for QList. + + It is simply a typedef for \c{std::reverse_iterator<const_iterator>}. + + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + + \sa QList::rbegin(), QList::rend(), QList::reverse_iterator, QList::const_iterator +*/ + /*! \fn int QList::count() const Returns the number of items in the list. This is effectively the diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index f5ff952f97..1e002633df 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -38,6 +38,7 @@ #include <QtCore/qiterator.h> #include <QtCore/qrefcount.h> #include <QtCore/qarraydata.h> +#include <QtCore/qhashfunctions.h> #include <iterator> #include <list> @@ -220,7 +221,6 @@ public: inline iterator() : i(0) {} inline iterator(Node *n) : i(n) {} - inline iterator(const iterator &o): i(o.i){} inline T &operator*() const { return i->t(); } inline T *operator->() const { return &i->t(); } inline T &operator[](difference_type j) const { return i[j].t(); } @@ -268,7 +268,6 @@ public: inline const_iterator() : i(0) {} inline const_iterator(Node *n) : i(n) {} - inline const_iterator(const const_iterator &o): i(o.i) {} #ifdef QT_STRICT_ITERATORS inline explicit const_iterator(const iterator &o): i(o.i) {} #else @@ -296,6 +295,8 @@ public: friend class const_iterator; // stl style + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; inline iterator begin() { detach(); return reinterpret_cast<Node *>(p.begin()); } inline const_iterator begin() const { return reinterpret_cast<Node *>(p.begin()); } inline const_iterator cbegin() const { return reinterpret_cast<Node *>(p.begin()); } @@ -304,6 +305,12 @@ public: inline const_iterator end() const { return reinterpret_cast<Node *>(p.end()); } inline const_iterator cend() const { return reinterpret_cast<Node *>(p.end()); } inline const_iterator constEnd() const { return reinterpret_cast<Node *>(p.end()); } + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } iterator insert(iterator before, const T &t); iterator erase(iterator pos); iterator erase(iterator first, iterator last); @@ -1020,6 +1027,43 @@ inline int QList<T>::count_impl(const T &t, QListData::ArrayCompatibleLayout) co Q_DECLARE_SEQUENTIAL_ITERATOR(List) Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List) +template <typename T> +uint qHash(const QList<T> &key, uint seed = 0) + Q_DECL_NOEXCEPT_EXPR(noexcept(qHashRange(key.cbegin(), key.cend(), seed))) +{ + return qHashRange(key.cbegin(), key.cend(), seed); +} + +template <typename T> +bool operator<(const QList<T> &lhs, const QList<T> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(), + rhs.begin(), rhs.end()))) +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), + rhs.begin(), rhs.end()); +} + +template <typename T> +inline bool operator>(const QList<T> &lhs, const QList<T> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return rhs < lhs; +} + +template <typename T> +inline bool operator<=(const QList<T> &lhs, const QList<T> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return !(lhs > rhs); +} + +template <typename T> +inline bool operator>=(const QList<T> &lhs, const QList<T> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return !(lhs < rhs); +} + QT_END_NAMESPACE #include <QtCore/qbytearraylist.h> diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index ead85e9da0..9ca14d2987 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -58,7 +58,7 @@ public: buffers.append(QByteArray()); } - inline int nextDataBlockSize() const { + inline qint64 nextDataBlockSize() const { return (tailBuffer == 0 ? tail : buffers.first().size()) - head; } @@ -86,9 +86,9 @@ public: return 0; } - inline void free(int bytes) { + inline void free(qint64 bytes) { while (bytes > 0) { - int blockSize = buffers.first().size() - head; + const qint64 blockSize = buffers.first().size() - head; if (tailBuffer == 0 || blockSize > bytes) { // keep a single block around if it does not exceed @@ -102,7 +102,8 @@ public: clear(); // try to minify/squeeze us } } else { - head += bytes; + Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + head += int(bytes); bufferSize -= bytes; } return; @@ -116,13 +117,15 @@ public: } } - inline char *reserve(int bytes) { - if (bytes <= 0) + inline char *reserve(qint64 bytes) { + if (bytes <= 0 || quint64(bytes) >= QByteArray::MaxSize) return 0; + const qint64 newSize = bytes + tail; // if need buffer reallocation - if (tail + bytes > buffers.last().size()) { - if (tail + bytes > buffers.last().capacity() && tail >= basicBlockSize) { + if (newSize > buffers.last().size()) { + if (newSize > buffers.last().capacity() && (tail >= basicBlockSize + || quint64(newSize) >= QByteArray::MaxSize)) { // shrink this buffer to its current size buffers.last().resize(tail); @@ -131,21 +134,22 @@ public: ++tailBuffer; tail = 0; } - buffers.last().resize(qMax(basicBlockSize, tail + bytes)); + buffers.last().resize(qMax(basicBlockSize, tail + int(bytes))); } char *writePtr = buffers.last().data() + tail; bufferSize += bytes; - tail += bytes; + Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + tail += int(bytes); return writePtr; } - inline void truncate(int pos) { + inline void truncate(qint64 pos) { if (pos < size()) chop(size() - pos); } - inline void chop(int bytes) { + inline void chop(qint64 bytes) { while (bytes > 0) { if (tailBuffer == 0 || tail > bytes) { // keep a single block around if it does not exceed @@ -159,7 +163,8 @@ public: clear(); // try to minify/squeeze us } } else { - tail -= bytes; + Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + tail -= int(bytes); bufferSize -= bytes; } return; @@ -206,7 +211,7 @@ public: ++bufferSize; } - inline int size() const { + inline qint64 size() const { return bufferSize; } @@ -219,9 +224,9 @@ public: bufferSize = 0; } - inline int indexOf(char c) const { - int index = 0; - int j = head; + inline qint64 indexOf(char c) const { + qint64 index = 0; + qint64 j = head; for (int i = 0; i < buffers.size(); ++i) { const char *ptr = buffers[i].constData() + j; j = index + (i == tailBuffer ? tail : buffers[i].size()) - j; @@ -236,9 +241,9 @@ public: return -1; } - inline int indexOf(char c, int maxLength) const { - int index = 0; - int j = head; + inline qint64 indexOf(char c, qint64 maxLength) const { + qint64 index = 0; + qint64 j = head; for (int i = 0; index < maxLength && i < buffers.size(); ++i) { const char *ptr = buffers[i].constData() + j; j = qMin(index + (i == tailBuffer ? tail : buffers[i].size()) - j, maxLength); @@ -253,11 +258,12 @@ public: return -1; } - inline int read(char *data, int maxLength) { - int bytesToRead = qMin(size(), maxLength); - int readSoFar = 0; + inline qint64 read(char *data, qint64 maxLength) { + const qint64 bytesToRead = qMin(size(), maxLength); + qint64 readSoFar = 0; while (readSoFar < bytesToRead) { - int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, nextDataBlockSize()); + const qint64 bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, + nextDataBlockSize()); if (data) memcpy(data + readSoFar, readPointer(), bytesToReadFromThisBlock); readSoFar += bytesToReadFromThisBlock; @@ -287,6 +293,30 @@ public: return qba; } + // peek the bytes from a specified position + inline qint64 peek(char *data, qint64 maxLength, qint64 pos = 0) const + { + qint64 readSoFar = 0; + + if (pos >= 0) { + pos += head; + for (int i = 0; readSoFar < maxLength && i < buffers.size(); ++i) { + qint64 blockLength = (i == tailBuffer ? tail : buffers[i].size()); + + if (pos < blockLength) { + blockLength = qMin(blockLength - pos, maxLength - readSoFar); + memcpy(data + readSoFar, buffers[i].constData() + pos, blockLength); + readSoFar += blockLength; + pos = 0; + } else { + pos -= blockLength; + } + } + } + + return readSoFar; + } + // append a new buffer to the end inline void append(const QByteArray &qba) { if (tail == 0) { @@ -300,15 +330,15 @@ public: bufferSize += tail; } - inline int skip(int length) { + inline qint64 skip(qint64 length) { return read(0, length); } - inline int readLine(char *data, int maxLength) { + inline qint64 readLine(char *data, qint64 maxLength) { if (!data || --maxLength <= 0) return -1; - int i = indexOf('\n', maxLength); + qint64 i = indexOf('\n', maxLength); i = read(data, i >= 0 ? (i + 1) : maxLength); // Terminate it. @@ -325,7 +355,7 @@ private: int head, tail; int tailBuffer; // always buffers.size() - 1 const int basicBlockSize; - int bufferSize; + qint64 bufferSize; }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index 9dd8fff9cb..a9f71c7b57 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.h @@ -36,7 +36,10 @@ #include <QtCore/qglobal.h> #include <QtCore/qatomic.h> +#if QT_DEPRECATED_SINCE(5, 5) #include <QtCore/qhash.h> +#endif +#include <QtCore/qhashfunctions.h> QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 9e6b48a97d..3d20f4dca9 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -55,7 +55,10 @@ QT_END_NAMESPACE #include <new> #include <QtCore/qatomic.h> #include <QtCore/qobject.h> // for qobject_cast -#include <QtCore/qhash.h> // for qHash +#if QT_DEPRECATED_SINCE(5, 5) +#include <QtCore/qhash.h> +#endif +#include <QtCore/qhashfunctions.h> #if defined(Q_COMPILER_RVALUE_REFS) && defined(Q_COMPILER_VARIADIC_TEMPLATES) # include <utility> // for std::forward diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 51b1617cdc..373d25c6ad 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -50,7 +50,6 @@ #include "qstringmatcher.h" #include "qvarlengtharray.h" #include "qtools_p.h" -#include "qhash.h" #include "qdebug.h" #include "qendian.h" #include "qcollator.h" @@ -1828,6 +1827,51 @@ QString &QString::operator=(QChar ch) /*! + \fn QString& QString::insert(int position, const QStringRef &str) + \since 5.5 + \overload insert() + + Inserts the string reference \a str at the given index \a position and + returns a reference to this string. + + If the given \a position is greater than size(), the array is + first extended using resize(). +*/ + + +/*! + \fn QString& QString::insert(int position, const char *str) + \since 5.5 + \overload insert() + + Inserts the C string \a str at the given index \a position and + returns a reference to this string. + + If the given \a position is greater than size(), the array is + first extended using resize(). + + This function is not available when QT_NO_CAST_FROM_ASCII is + defined. +*/ + + +/*! + \fn QString& QString::insert(int position, const QByteArray &str) + \since 5.5 + \overload insert() + + Inserts the byte array \a str at the given index \a position and + returns a reference to this string. + + If the given \a position is greater than size(), the array is + first extended using resize(). + + This function is not available when QT_NO_CAST_FROM_ASCII is + defined. +*/ + + +/*! \fn QString &QString::insert(int position, QLatin1String str) \overload insert() @@ -2027,6 +2071,22 @@ QString &QString::append(QChar ch) Prepends the Latin-1 string \a str to this string. */ +/*! \fn QString &QString::prepend(const QChar *str, int len) + \since 5.5 + \overload prepend() + + Prepends \a len characters from the QChar array \a str to this string and + returns a reference to this string. +*/ + +/*! \fn QString &QString::prepend(const QStringRef &str) + \since 5.5 + \overload prepend() + + Prepends the string reference \a str to the beginning of this string and + returns a reference to this string. +*/ + /*! \fn QString &QString::prepend(const QByteArray &ba) \overload prepend() @@ -3936,10 +3996,9 @@ int QString::count(const QRegularExpression &re) const QString QString::section(const QString &sep, int start, int end, SectionFlags flags) const { - QStringList sections = split(sep, KeepEmptyParts, - (flags & SectionCaseInsensitiveSeps) ? Qt::CaseInsensitive : Qt::CaseSensitive); + const QVector<QStringRef> sections = splitRef(sep, KeepEmptyParts, + (flags & SectionCaseInsensitiveSeps) ? Qt::CaseInsensitive : Qt::CaseSensitive); const int sectionsSize = sections.size(); - if (!(flags & SectionSkipEmpty)) { if (start < 0) start += sectionsSize; @@ -3959,11 +4018,10 @@ QString QString::section(const QString &sep, int start, int end, SectionFlags fl if (start >= sectionsSize || end < 0 || start > end) return QString(); - int x = 0; QString ret; int first_i = start, last_i = end; - for (int i = 0; x <= end && i < sectionsSize; ++i) { - QString section = sections.at(i); + for (int x = 0, i = 0; x <= end && i < sectionsSize; ++i) { + const QStringRef §ion = sections.at(i); const bool empty = section.isEmpty(); if (x >= start) { if(x == start) @@ -3988,9 +4046,9 @@ QString QString::section(const QString &sep, int start, int end, SectionFlags fl class qt_section_chunk { public: qt_section_chunk() {} - qt_section_chunk(int l, QString s) : length(l), string(qMove(s)) {} + qt_section_chunk(int l, QStringRef s) : length(l), string(qMove(s)) {} int length; - QString string; + QStringRef string; }; Q_DECLARE_TYPEINFO(qt_section_chunk, Q_MOVABLE_TYPE); @@ -4083,12 +4141,12 @@ QString QString::section(const QRegExp ®, int start, int end, SectionFlags fl QVector<qt_section_chunk> sections; int n = length(), m = 0, last_m = 0, last_len = 0; while ((m = sep.indexIn(*this, m)) != -1) { - sections.append(qt_section_chunk(last_len, QString(uc + last_m, m - last_m))); + sections.append(qt_section_chunk(last_len, QStringRef(this, last_m, m - last_m))); last_m = m; last_len = sep.matchedLength(); m += qMax(sep.matchedLength(), 1); } - sections.append(qt_section_chunk(last_len, QString(uc + last_m, n - last_m))); + sections.append(qt_section_chunk(last_len, QStringRef(this, last_m, n - last_m))); return extractSections(sections, start, end, flags); } @@ -4131,11 +4189,11 @@ QString QString::section(const QRegularExpression &re, int start, int end, Secti while (iterator.hasNext()) { QRegularExpressionMatch match = iterator.next(); m = match.capturedStart(); - sections.append(qt_section_chunk(last_len, QString(uc + last_m, m - last_m))); + sections.append(qt_section_chunk(last_len, QStringRef(this, last_m, m - last_m))); last_m = m; last_len = match.capturedLength(); } - sections.append(qt_section_chunk(last_len, QString(uc + last_m, n - last_m))); + sections.append(qt_section_chunk(last_len, QStringRef(this, last_m, n - last_m))); return extractSections(sections, start, end, flags); } @@ -7600,86 +7658,155 @@ static int getEscape(const QChar *uc, int *pos, int len, int maxNumber = 999) return -1; } +/* + Algorithm for multiArg: + + 1. Parse the string as a sequence of verbatim text and placeholders (%L?\d{,3}). + The L is parsed and accepted for compatibility with non-multi-arg, but since + multiArg only accepts strings as replacements, the localization request can + be safely ignored. + 2. The result of step (1) is a list of (string-ref,int)-tuples. The string-ref + either points at text to be copied verbatim (in which case the int is -1), + or, initially, at the textual representation of the placeholder. In that case, + the int contains the numerical number as parsed from the placeholder. + 3. Next, collect all the non-negative ints found, sort them in ascending order and + remove duplicates. + 3a. If the result has more entires than multiArg() was given replacement strings, + we have found placeholders we can't satisfy with replacement strings. That is + fine (there could be another .arg() call coming after this one), so just + truncate the result to the number of actual multiArg() replacement strings. + 3b. If the result has less entries than multiArg() was given replacement strings, + the string is missing placeholders. This is an error that the user should be + warned about. + 4. The result of step (3) is a mapping from the index of any replacement string to + placeholder number. This is the wrong way around, but since placeholder + numbers could get as large as 999, while we typically don't have more than 9 + replacement strings, we trade 4K of sparsely-used memory for doing a reverse lookup + each time we need to map a placeholder number to a replacement string index + (that's a linear search; but still *much* faster than using an associative container). + 5. Next, for each of the tuples found in step (1), do the following: + 5a. If the int is negative, do nothing. + 5b. Otherwise, if the int is found in the result of step (3) at index I, replace + the string-ref with a string-ref for the (complete) I'th replacement string. + 5c. Otherwise, do nothing. + 6. Concatenate all string refs into a single result string. +*/ + namespace { -class ArgMapper { - QVarLengthArray<int, 16> argPosToNumberMap; // maps from argument position to number -public: - void found(int n) { argPosToNumberMap.push_back(n); } +struct Part +{ + Part() : stringRef(), number(0) {} + Part(const QString &s, int pos, int len, int num = -1) Q_DECL_NOTHROW + : stringRef(&s, pos, len), number(num) {} - struct AssignmentResult { - int numArgs; - int lastNumber; - }; + QStringRef stringRef; + int number; +}; +} // unnamed namespace - AssignmentResult assignArgumentNumberToEachOfTheNs(int numArgs) - { - std::sort(argPosToNumberMap.begin(), argPosToNumberMap.end()); - argPosToNumberMap.erase(std::unique(argPosToNumberMap.begin(), argPosToNumberMap.end()), - argPosToNumberMap.end()); +template <> +class QTypeInfo<Part> : public QTypeInfoMerger<Part, QStringRef, int> {}; // Q_DECLARE_METATYPE - if (argPosToNumberMap.size() > numArgs) - argPosToNumberMap.resize(numArgs); - int lastNumber = argPosToNumberMap.empty() ? -1 : argPosToNumberMap.back(); - int arg = argPosToNumberMap.size(); +namespace { - const AssignmentResult result = {arg, lastNumber}; - return result; - } +enum { ExpectedParts = 32 }; - int numberToArgsIndex(int number) const - { - if (number != -1) { - const int * const it = std::find(argPosToNumberMap.begin(), argPosToNumberMap.end(), number); - return it == argPosToNumberMap.end() ? -1 : it - argPosToNumberMap.begin(); - } else { - return -1; - } - } -}; -} // unnamed namespace +typedef QVarLengthArray<Part, ExpectedParts> ParseResult; +typedef QVarLengthArray<int, ExpectedParts/2> ArgIndexToPlaceholderMap; -QString QString::multiArg(int numArgs, const QString **args) const +static ParseResult parseMultiArgFormatString(const QString &s) { - QString result; - ArgMapper mapper; - const QChar *uc = (const QChar *) d->data(); - const int len = d->size; + ParseResult result; + + const QChar *uc = s.constData(); + const int len = s.size(); const int end = len - 1; int i = 0; + int last = 0; - // populate the arg-mapper with the %n's that actually occur in the string while (i < end) { if (uc[i] == QLatin1Char('%')) { + int percent = i; int number = getEscape(uc, &i, len); if (number != -1) { - mapper.found(number); + if (last != percent) + result.push_back(Part(s, last, percent - last)); // literal text (incl. failed placeholders) + result.push_back(Part(s, percent, i - percent, number)); // parsed placeholder + last = i; continue; } } ++i; } - const ArgMapper::AssignmentResult r = mapper.assignArgumentNumberToEachOfTheNs(numArgs); + if (last < len) + result.push_back(Part(s, last, len - last)); // trailing literal text + + return result; +} + +static ArgIndexToPlaceholderMap makeArgIndexToPlaceholderMap(const ParseResult &parts) +{ + ArgIndexToPlaceholderMap result; + + for (ParseResult::const_iterator it = parts.begin(), end = parts.end(); it != end; ++it) { + if (it->number >= 0) + result.push_back(it->number); + } + + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), + result.end()); - // sanity - if (numArgs > r.numArgs) { - qWarning("QString::arg: %d argument(s) missing in %s", numArgs - r.numArgs, toLocal8Bit().data()); - numArgs = r.numArgs; + return result; +} + +static int resolveStringRefsAndReturnTotalSize(ParseResult &parts, const ArgIndexToPlaceholderMap &argIndexToPlaceholderMap, const QString *args[]) +{ + int totalSize = 0; + for (ParseResult::iterator pit = parts.begin(), end = parts.end(); pit != end; ++pit) { + if (pit->number != -1) { + const ArgIndexToPlaceholderMap::const_iterator ait + = std::find(argIndexToPlaceholderMap.begin(), argIndexToPlaceholderMap.end(), pit->number); + if (ait != argIndexToPlaceholderMap.end()) + pit->stringRef = QStringRef(args[ait - argIndexToPlaceholderMap.begin()]); + } + totalSize += pit->stringRef.size(); } + return totalSize; +} - i = 0; - while (i < len) { - if (uc[i] == QLatin1Char('%') && i != end) { - int number = getEscape(uc, &i, len, r.lastNumber); - int arg = mapper.numberToArgsIndex(number); - if (number != -1 && arg != -1) { - result += *args[arg]; - continue; - } +} // unnamed namespace + +QString QString::multiArg(int numArgs, const QString **args) const +{ + // Step 1-2 above + ParseResult parts = parseMultiArgFormatString(*this); + + // 3-4 + ArgIndexToPlaceholderMap argIndexToPlaceholderMap = makeArgIndexToPlaceholderMap(parts); + + if (argIndexToPlaceholderMap.size() > numArgs) // 3a + argIndexToPlaceholderMap.resize(numArgs); + else if (argIndexToPlaceholderMap.size() < numArgs) // 3b + qWarning("QString::arg: %d argument(s) missing in %s", + numArgs - argIndexToPlaceholderMap.size(), toLocal8Bit().data()); + + // 5 + const int totalSize = resolveStringRefsAndReturnTotalSize(parts, argIndexToPlaceholderMap, args); + + // 6: + QString result(totalSize, Qt::Uninitialized); + QChar *out = result.data(); + + for (ParseResult::const_iterator it = parts.begin(), end = parts.end(); it != end; ++it) { + if (const int sz = it->stringRef.size()) { + memcpy(out, it->stringRef.constData(), sz * sizeof(QChar)); + out += sz; } - result += uc[i++]; } + return result; } diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index bb918f36c8..532b294c28 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -84,7 +84,7 @@ class QLatin1String public: Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) : m_size(s ? int(strlen(s)) : 0), m_data(s) {} Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) : m_size(sz), m_data(s) {} - inline explicit QLatin1String(const QByteArray &s) : m_size(int(qstrnlen(s.constData(), s.size()))), m_data(s.constData()) {} + inline explicit QLatin1String(const QByteArray &s) : m_size(s.size()), m_data(s.constData()) {} inline const char *latin1() const { return m_data; } inline int size() const { return m_size; } @@ -420,6 +420,7 @@ public: QString &insert(int i, QChar c); QString &insert(int i, const QChar *uc, int len); inline QString &insert(int i, const QString &s) { return insert(i, s.constData(), s.length()); } + inline QString &insert(int i, const QStringRef &s); QString &insert(int i, QLatin1String s); QString &append(QChar c); QString &append(const QChar *uc, int len); @@ -427,7 +428,9 @@ public: QString &append(const QStringRef &s); QString &append(QLatin1String s); inline QString &prepend(QChar c) { return insert(0, c); } + inline QString &prepend(const QChar *uc, int len) { return insert(0, uc, len); } inline QString &prepend(const QString &s) { return insert(0, s); } + inline QString &prepend(const QStringRef &s) { return insert(0, s); } inline QString &prepend(QLatin1String s) { return insert(0, s); } inline QString &operator+=(QChar c) { @@ -534,11 +537,11 @@ public: return fromLocal8Bit_helper(str, (str && size == -1) ? int(strlen(str)) : size); } static inline QString fromLatin1(const QByteArray &str) - { return fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); } + { return str.isNull() ? QString() : fromLatin1(str.data(), str.size()); } static inline QString fromUtf8(const QByteArray &str) - { return fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); } + { return str.isNull() ? QString() : fromUtf8(str.data(), str.size()); } static inline QString fromLocal8Bit(const QByteArray &str) - { return fromLocal8Bit(str.data(), qstrnlen(str.constData(), str.size())); } + { return str.isNull() ? QString() : fromLocal8Bit(str.data(), str.size()); } static QString fromUtf16(const ushort *, int size = -1); static QString fromUcs4(const uint *, int size = -1); static QString fromRawData(const QChar *, int size); @@ -650,7 +653,7 @@ public: : d(fromAscii_helper(ch, ch ? int(strlen(ch)) : -1)) {} inline QT_ASCII_CAST_WARN QString(const QByteArray &a) - : d(fromAscii_helper(a.constData(), qstrnlen(a.constData(), a.size()))) + : d(fromAscii_helper(a.constData(), a.size())) {} inline QT_ASCII_CAST_WARN QString &operator=(const char *ch) { return (*this = fromUtf8(ch)); } @@ -668,6 +671,10 @@ public: { return append(QString::fromUtf8(s)); } inline QT_ASCII_CAST_WARN QString &append(const QByteArray &s) { return append(QString::fromUtf8(s)); } + inline QT_ASCII_CAST_WARN QString &insert(int i, const char *s) + { return insert(i, QString::fromUtf8(s)); } + inline QT_ASCII_CAST_WARN QString &insert(int i, const QByteArray &s) + { return insert(i, QString::fromUtf8(s)); } inline QT_ASCII_CAST_WARN QString &operator+=(const char *s) { return append(QString::fromUtf8(s)); } inline QT_ASCII_CAST_WARN QString &operator+=(const QByteArray &s) @@ -1211,30 +1218,30 @@ inline QT_ASCII_CAST_WARN bool QLatin1String::operator>=(const QByteArray &s) co { return QString::fromUtf8(s) <= *this; } inline QT_ASCII_CAST_WARN bool QString::operator==(const QByteArray &s) const -{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) == 0; } +{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) == 0; } inline QT_ASCII_CAST_WARN bool QString::operator!=(const QByteArray &s) const -{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) != 0; } +{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) != 0; } inline QT_ASCII_CAST_WARN bool QString::operator<(const QByteArray &s) const -{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) < 0; } +{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; } inline QT_ASCII_CAST_WARN bool QString::operator>(const QByteArray &s) const -{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) > 0; } +{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) > 0; } inline QT_ASCII_CAST_WARN bool QString::operator<=(const QByteArray &s) const -{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) <= 0; } +{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) <= 0; } inline QT_ASCII_CAST_WARN bool QString::operator>=(const QByteArray &s) const -{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) >= 0; } +{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) >= 0; } inline bool QByteArray::operator==(const QString &s) const -{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) == 0; } +{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) == 0; } inline bool QByteArray::operator!=(const QString &s) const -{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) != 0; } +{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) != 0; } inline bool QByteArray::operator<(const QString &s) const -{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) < 0; } +{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) < 0; } inline bool QByteArray::operator>(const QString &s) const -{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) > 0; } +{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) > 0; } inline bool QByteArray::operator<=(const QString &s) const -{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) <= 0; } +{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) <= 0; } inline bool QByteArray::operator>=(const QString &s) const -{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) >= 0; } +{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) >= 0; } #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII) #ifndef QT_NO_CAST_TO_ASCII @@ -1576,6 +1583,9 @@ inline bool QStringRef::contains(QChar c, Qt::CaseSensitivity cs) const inline bool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const { return indexOf(s, 0, cs) != -1; } +inline QString &QString::insert(int i, const QStringRef &s) +{ return insert(i, s.constData(), s.length()); } + namespace Qt { #if QT_DEPRECATED_SINCE(5, 0) QT_DEPRECATED inline QString escape(const QString &plain) { diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 90b54b7297..bb15d66439 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -45,6 +45,7 @@ #ifdef Q_COMPILER_INITIALIZER_LISTS #include <initializer_list> #endif +#include <iterator> QT_BEGIN_NAMESPACE @@ -174,6 +175,8 @@ public: typedef T* iterator; typedef const T* const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; inline iterator begin() { return ptr; } inline const_iterator begin() const { return ptr; } @@ -183,6 +186,12 @@ public: inline const_iterator end() const { return ptr + s; } inline const_iterator cend() const { return ptr + s; } inline const_iterator constEnd() const { return ptr + s; } + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } iterator insert(const_iterator before, int n, const T &x); inline iterator insert(const_iterator before, const T &x) { return insert(before, 1, x); } iterator erase(const_iterator begin, const_iterator end); @@ -489,6 +498,36 @@ bool operator!=(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T, return !(l == r); } +template <typename T, int Prealloc1, int Prealloc2> +bool operator<(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengthArray<T, Prealloc2> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(), + rhs.begin(), rhs.end()))) +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), + rhs.begin(), rhs.end()); +} + +template <typename T, int Prealloc1, int Prealloc2> +inline bool operator>(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengthArray<T, Prealloc2> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return rhs < lhs; +} + +template <typename T, int Prealloc1, int Prealloc2> +inline bool operator<=(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengthArray<T, Prealloc2> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return !(lhs > rhs); +} + +template <typename T, int Prealloc1, int Prealloc2> +inline bool operator>=(const QVarLengthArray<T, Prealloc1> &lhs, const QVarLengthArray<T, Prealloc2> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return !(lhs < rhs); +} + QT_END_NAMESPACE #endif // QVARLENGTHARRAY_H diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index a2d4c55f7a..2b7f9c5241 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -468,6 +468,20 @@ Typedef for T *. Provided for STL compatibility. */ +/*! + \typedef QVarLengthArray::const_reverse_iterator + \since 5.6 + + Typedef for \c{std::reverse_iterator<const T*>}. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::reverse_iterator + \since 5.6 + + Typedef for \c{std::reverse_iterator<T*>}. Provided for STL compatibility. +*/ + /*! \fn void QVarLengthArray::prepend(const T &value) \since 4.8 @@ -582,6 +596,52 @@ \sa constBegin(), end() */ +/*! \fn QVarLengthArray::reverse_iterator QVarLengthArray::rbegin() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + item in the variable length array, in reverse order. + + \sa begin(), crbegin(), rend() +*/ + +/*! \fn QVarLengthArray::const_reverse_iterator QVarLengthArray::rbegin() const + \since 5.6 + \overload +*/ + +/*! \fn QVarLengthArray::const_reverse_iterator QVarLengthArray::crbegin() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + item in the variable length array, in reverse order. + + \sa begin(), rbegin(), rend() +*/ + +/*! \fn QVarLengthArray::reverse_iterator QVarLengthArray::rend() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past + the last item in the variable length array, in reverse order. + + \sa end(), crend(), rbegin() +*/ + +/*! \fn QVarLengthArray::const_reverse_iterator QVarLengthArray::rend() const + \since 5.6 + \overload +*/ + +/*! \fn QVarLengthArray::const_reverse_iterator QVarLengthArray::crend() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one + past the last item in the variable length array, in reverse order. + + \sa end(), rend(), rbegin() +*/ + /*! \fn QVarLengthArray::iterator QVarLengthArray::erase(const_iterator pos) \since 4.8 @@ -676,6 +736,54 @@ \sa operator==() */ +/*! \fn bool operator<(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs) + \since 5.6 + \relates QVarLengthArray + + Returns \c true if variable length array \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically less than} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator<=(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs) + \since 5.6 + \relates QVarLengthArray + + Returns \c true if variable length array \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically less than or equal to} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator>(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs) + \since 5.6 + \relates QVarLengthArray + + Returns \c true if variable length array \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically greater than} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator>=(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs) + \since 5.6 + \relates QVarLengthArray + + Returns \c true if variable length array \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically greater than or equal to} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + /*! \fn QVarLengthArray &QVarLengthArray::operator<<(const T &value) \since 4.8 diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index d10f82fbb4..4f46764697 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -290,6 +290,65 @@ \sa operator==() */ +/*! \fn bool operator<(const QVector<T> &lhs, const QVector<T> &rhs) + \since 5.6 + \relates QVector + + Returns \c true if vector \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically less than} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator<=(const QVector<T> &lhs, const QVector<T> &rhs) + \since 5.6 + \relates QVector + + Returns \c true if vector \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically less than or equal to} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator>(const QVector<T> &lhs, const QVector<T> &rhs) + \since 5.6 + \relates QVector + + Returns \c true if vector \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically greater than} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! \fn bool operator>=(const QVector<T> &lhs, const QVector<T> &rhs) + \since 5.6 + \relates QVector + + Returns \c true if vector \a lhs is + \l{http://en.cppreference.com/w/cpp/algorithm/lexicographical_compare} + {lexicographically greater than or equal to} \a rhs; otherwise returns \c false. + + This function requires the value type to have an implementation + of \c operator<(). +*/ + +/*! + \fn uint qHash(const QVector<T> &key, uint seed = 0) + \since 5.6 + \relates QVector + + Returns the hash value for \a key, + using \a seed to seed the calculation. + + This function requires qHash() to be overloaded for the value type \c T. +*/ + /*! \fn int QVector::size() const Returns the number of items in the vector. @@ -823,6 +882,52 @@ \sa constBegin(), end() */ +/*! \fn QVector::reverse_iterator QVector::rbegin() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + item in the vector, in reverse order. + + \sa begin(), crbegin(), rend() +*/ + +/*! \fn QVector::const_reverse_iterator QVector::rbegin() const + \since 5.6 + \overload +*/ + +/*! \fn QVector::const_reverse_iterator QVector::crbegin() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first + item in the vector, in reverse order. + + \sa begin(), rbegin(), rend() +*/ + +/*! \fn QVector::reverse_iterator QVector::rend() + \since 5.6 + + Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past + the last item in the vector, in reverse order. + + \sa end(), crend(), rbegin() +*/ + +/*! \fn QVector::const_reverse_iterator QVector::rend() const + \since 5.6 + \overload +*/ + +/*! \fn QVector::const_reverse_iterator QVector::crend() const + \since 5.6 + + Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one + past the last item in the vector, in reverse order. + + \sa end(), rend(), rbegin() +*/ + /*! \fn QVector::iterator QVector::erase(iterator pos) Removes the item pointed to by the iterator \a pos from the @@ -1013,6 +1118,38 @@ \sa QVector::constBegin(), QVector::constEnd(), QVector::iterator, QVectorIterator */ +/*! \typedef QVector::reverse_iterator + \since 5.6 + + The QVector::reverse_iterator typedef provides an STL-style non-const + reverse iterator for QVector. + + It is simply a typedef for \c{std::reverse_iterator<T*>}. + + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + + \sa QVector::rbegin(), QVector::rend(), QVector::const_reverse_iterator, QVector::iterator +*/ + +/*! \typedef QVector::const_reverse_iterator + \since 5.6 + + The QVector::const_reverse_iterator typedef provides an STL-style const + reverse iterator for QVector. + + It is simply a typedef for \c{std::reverse_iterator<const T*>}. + + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + + \sa QVector::rbegin(), QVector::rend(), QVector::reverse_iterator, QVector::const_iterator +*/ + /*! \typedef QVector::Iterator Qt-style synonym for QVector::iterator. diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 9d5b749e79..12baecd37c 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -39,6 +39,7 @@ #include <QtCore/qlist.h> #include <QtCore/qrefcount.h> #include <QtCore/qarraydata.h> +#include <QtCore/qhashfunctions.h> #include <iterator> #include <vector> @@ -175,6 +176,8 @@ public: // STL-style typedef typename Data::iterator iterator; typedef typename Data::const_iterator const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; #if !defined(QT_STRICT_ITERATORS) || defined(Q_QDOC) inline iterator begin() { detach(); return d->begin(); } inline const_iterator begin() const { return d->constBegin(); } @@ -194,6 +197,12 @@ public: inline const_iterator cend(const_iterator = const_iterator()) const { return d->constEnd(); } inline const_iterator constEnd(const_iterator = const_iterator()) const { return d->constEnd(); } #endif + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } iterator insert(iterator before, int n, const T &x); inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); } iterator erase(iterator begin, iterator end); @@ -265,7 +274,6 @@ private: { return (i <= d->end()) && (d->begin() <= i); } - iterator c2m(const_iterator it) { return begin() + (it - cbegin()); } class AlignmentDummy { Data header; T array[1]; }; }; @@ -866,6 +874,43 @@ QList<T> QList<T>::fromVector(const QVector<T> &vector) Q_DECLARE_SEQUENTIAL_ITERATOR(Vector) Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Vector) +template <typename T> +uint qHash(const QVector<T> &key, uint seed = 0) + Q_DECL_NOEXCEPT_EXPR(noexcept(qHashRange(key.cbegin(), key.cend(), seed))) +{ + return qHashRange(key.cbegin(), key.cend(), seed); +} + +template <typename T> +bool operator<(const QVector<T> &lhs, const QVector<T> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(), + rhs.begin(), rhs.end()))) +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), + rhs.begin(), rhs.end()); +} + +template <typename T> +inline bool operator>(const QVector<T> &lhs, const QVector<T> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return rhs < lhs; +} + +template <typename T> +inline bool operator<=(const QVector<T> &lhs, const QVector<T> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return !(lhs > rhs); +} + +template <typename T> +inline bool operator>=(const QVector<T> &lhs, const QVector<T> &rhs) + Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs)) +{ + return !(lhs < rhs); +} + /* ### Qt 5: ### This needs to be removed for next releases of Qt. It is a workaround for vc++ because diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 5de0c09a4d..5e4a22e283 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -26,6 +26,7 @@ HEADERS += \ tools/qeasingcurve.h \ tools/qfreelist_p.h \ tools/qhash.h \ + tools/qhashfunctions.h \ tools/qiterator.h \ tools/qline.h \ tools/qlinkedlist.h \ |