diff options
Diffstat (limited to 'src/corelib/global')
-rw-r--r-- | src/corelib/global/global.pri | 1 | ||||
-rw-r--r-- | src/corelib/global/qcompilerdetection.h | 21 | ||||
-rw-r--r-- | src/corelib/global/qconfig-bootstrapped.h | 3 | ||||
-rw-r--r-- | src/corelib/global/qendian.cpp (renamed from src/corelib/global/qendian.qdoc) | 399 | ||||
-rw-r--r-- | src/corelib/global/qendian.h | 65 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 94 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 8 | ||||
-rw-r--r-- | src/corelib/global/qglobalstatic.h | 2 | ||||
-rw-r--r-- | src/corelib/global/qglobalstatic.qdoc | 2 | ||||
-rw-r--r-- | src/corelib/global/qlogging.cpp | 38 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.h | 58 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 44 | ||||
-rw-r--r-- | src/corelib/global/qnumeric_p.h | 52 | ||||
-rw-r--r-- | src/corelib/global/qprocessordetection.h | 2 | ||||
-rw-r--r-- | src/corelib/global/qrandom.cpp | 8 | ||||
-rw-r--r-- | src/corelib/global/qtrace_p.h | 2 | ||||
-rw-r--r-- | src/corelib/global/qversiontagging.cpp | 11 |
17 files changed, 699 insertions, 111 deletions
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 2b4fd6d661..a4d132a4f4 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -29,6 +29,7 @@ HEADERS += \ SOURCES += \ global/archdetect.cpp \ + global/qendian.cpp \ global/qglobal.cpp \ global/qlibraryinfo.cpp \ global/qmalloc.cpp \ diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index f46ff73527..2b85ea0815 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -898,7 +898,7 @@ /* C11 features supported in GCC 4.7: */ # define Q_COMPILER_STATIC_ASSERT # endif -# if Q_CC_GNU >= 409 +# if Q_CC_GNU >= 409 && defined(__has_include) /* C11 features supported in GCC 4.9: */ # if __has_include(<threads.h>) # define Q_COMPILER_THREAD_LOCAL @@ -1152,6 +1152,19 @@ # define Q_REQUIRED_RESULT [[nodiscard]] #endif +#if defined(__cpp_enumerator_attributes) && __cpp_enumerator_attributes >= 201411 +#if defined(Q_CC_MSVC) +// Can't mark enum values as __declspec(deprecated) with MSVC, also can't move +// everything to [[deprecated]] because MSVC gives a compilation error when marking +// friend methods of a class as [[deprecated("text")]], breaking qstring.h +# define Q_DECL_ENUMERATOR_DEPRECATED [[deprecated]] +# define Q_DECL_ENUMERATOR_DEPRECATED_X(x) [[deprecated(x)]] +#else +# define Q_DECL_ENUMERATOR_DEPRECATED Q_DECL_DEPRECATED +# define Q_DECL_ENUMERATOR_DEPRECATED_X(x) Q_DECL_DEPRECATED_X(x) +#endif +#endif + /* * Fallback macros to certain compiler features */ @@ -1186,6 +1199,12 @@ #ifndef Q_DECL_DEPRECATED_X # define Q_DECL_DEPRECATED_X(text) Q_DECL_DEPRECATED #endif +#ifndef Q_DECL_ENUMERATOR_DEPRECATED +# define Q_DECL_ENUMERATOR_DEPRECATED +#endif +#ifndef Q_DECL_ENUMERATOR_DEPRECATED_X +# define Q_DECL_ENUMERATOR_DEPRECATED_X(x) +#endif #ifndef Q_DECL_EXPORT # define Q_DECL_EXPORT #endif diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index c5585ea32a..a8dbb3edcd 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -103,6 +103,7 @@ #else # define QT_FEATURE_renameat2 -1 #endif +#define QT_FEATURE_settings -1 #define QT_FEATURE_sharedmemory -1 #define QT_FEATURE_slog2 -1 #ifdef __GLIBC_PREREQ @@ -114,7 +115,7 @@ #define QT_NO_SYSTEMLOCALE #define QT_FEATURE_systemsemaphore -1 #define QT_FEATURE_temporaryfile 1 -#define QT_NO_THREAD +#define QT_FEATURE_thread -1 #define QT_FEATURE_timezone -1 #define QT_FEATURE_topleveldomain -1 #define QT_NO_TRANSLATION diff --git a/src/corelib/global/qendian.qdoc b/src/corelib/global/qendian.cpp index 65df25a205..7fd6e13d3b 100644 --- a/src/corelib/global/qendian.qdoc +++ b/src/corelib/global/qendian.cpp @@ -1,11 +1,12 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:FDL$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,17 +15,36 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** ** $QT_END_LICENSE$ ** ****************************************************************************/ +#include "qendian.h" + +#include "qalgorithms.h" +#include <private/qsimd_p.h> + +QT_BEGIN_NAMESPACE + /*! \headerfile <QtEndian> \title Endian Conversion Functions @@ -66,8 +86,9 @@ On CPU architectures where the host byte order is little-endian (such as x86) this will swap the byte order; otherwise it will just read from \a src. - \note Template type \c{T} can either be a qint16, qint32 or qint64. Other types of - integers, e.g., qlong, are not applicable. + \note Template type \c{T} can either be a quint16, qint16, quint32, qint32, + quint64, or qint64. Other types of integers, e.g., qlong, are not + applicable. \note Since Qt 5.7, the type of the \a src parameter is a void pointer. @@ -90,6 +111,32 @@ unmodified. */ /*! + \fn template <typename T> T qFromBigEndian(const void *src, qsizetype count, void *dest) + \since 5.12 + \relates <QtEndian> + + Reads \a count big-endian numbers from memory location \a src and stores + them in the host byte order representation at \a dest. On CPU architectures + where the host byte order is little-endian (such as x86) this will swap the + byte order; otherwise it will just perform a \c memcpy from \a src to \a + dest. + + \note Template type \c{T} can either be a quint16, qint16, quint32, qint32, + quint64, or qint64. Other types of integers, e.g., qlong, are not + applicable. + + There are no data alignment constraints for \a src. However, \a dest is + expected to be naturally aligned for type \c{T}. + + If \a src and \a dest can be the same pointer, this function will perform + an in-place swap (if necessary). If they are not the same, the memory + regions must not overlap. + + \sa qFromLittleEndian() + \sa qToBigEndian() + \sa qToLittleEndian() +*/ +/*! \fn template <typename T> T qFromLittleEndian(const void *src) \since 4.3 \relates <QtEndian> @@ -99,8 +146,9 @@ On CPU architectures where the host byte order is big-endian (such as PowerPC) this will swap the byte order; otherwise it will just read from \a src. - \note Template type \c{T} can either be a qint16, qint32 or qint64. Other types of - integers, e.g., qlong, are not applicable. + \note Template type \c{T} can either be a quint16, qint16, quint32, qint32, + quint64, or qint64. Other types of integers, e.g., qlong, are not + applicable. \note Since Qt 5.7, the type of the \a src parameter is a void pointer. @@ -123,6 +171,32 @@ unmodified. */ /*! + \fn template <typename T> T qFromLittleEndian(const void *src, qsizetype count, void *dest) + \since 5.12 + \relates <QtEndian> + + Reads \a count little-endian numbers from memory location \a src and stores + them in the host byte order representation at \a dest. On CPU architectures + where the host byte order is big-endian (such as PowerPC) this will swap the + byte order; otherwise it will just perform a \c memcpy from \a src to \a + dest. + + \note Template type \c{T} can either be a quint16, qint16, quint32, qint32, + quint64, or qint64. Other types of integers, e.g., qlong, are not + applicable. + + There are no data alignment constraints for \a src. However, \a dest is + expected to be naturally aligned for type \c{T}. + + If \a src and \a dest can be the same pointer, this function will perform + an in-place swap (if necessary). If they are not the same, the memory + regions must not overlap. + + \sa qFromLittleEndian() + \sa qToBigEndian() + \sa qToLittleEndian() +*/ +/*! \fn template <typename T> void qToBigEndian(T src, void *dest) \since 4.3 \relates <QtEndian> @@ -130,7 +204,9 @@ Writes the number \a src with template type \c{T} to the memory location at \a dest in big-endian byte order. - Note that template type \c{T} can only be an integer data type (signed or unsigned). + \note Template type \c{T} can either be a quint16, qint16, quint32, qint32, + quint64, or qint64. Other types of integers, e.g., qlong, are not + applicable. There are no data alignment constraints for \a dest. @@ -153,6 +229,32 @@ unmodified. */ /*! + \fn template <typename T> T qToBigEndian(const void *src, qsizetype count, void *dest) + \since 5.12 + \relates <QtEndian> + + Reads \a count numbers from memory location \a src in the host byte order + and stores them in big-endian representation at \a dest. On CPU + architectures where the host byte order is little-endian (such as x86) this + will swap the byte order; otherwise it will just perform a \c memcpy from + \a src to \a dest. + + \note Template type \c{T} can either be a quint16, qint16, quint32, qint32, + quint64, or qint64. Other types of integers, e.g., qlong, are not + applicable. + + There are no data alignment constraints for \a dest. However, \a src is + expected to be naturally aligned for type \c{T}. + + If \a src and \a dest can be the same pointer, this function will perform + an in-place swap (if necessary). If they are not the same, the memory + regions must not overlap. + + \sa qFromLittleEndian() + \sa qToBigEndian() + \sa qToLittleEndian() +*/ +/*! \fn template <typename T> void qToLittleEndian(T src, void *dest) \since 4.3 \relates <QtEndian> @@ -160,7 +262,9 @@ Writes the number \a src with template type \c{T} to the memory location at \a dest in little-endian byte order. - Note that template type \c{T} can only be an integer data type (signed or unsigned). + \note Template type \c{T} can either be a quint16, qint16, quint32, qint32, + quint64, or qint64. Other types of integers, e.g., qlong, are not + applicable. There are no data alignment constraints for \a dest. @@ -182,6 +286,32 @@ will return \a src with the byte order swapped; otherwise it will return \a src unmodified. */ +/*! + \fn template <typename T> T qToLittleEndian(const void *src, qsizetype count, void *dest) + \since 5.12 + \relates <QtEndian> + + Reads \a count numbers from memory location \a src in the host byte order + and stores them in little-endian representation at \a dest. On CPU + architectures where the host byte order is big-endian (such as PowerPC) + this will swap the byte order; otherwise it will just perform a \c memcpy + from \a src to \a dest. + + \note Template type \c{T} can either be a quint16, qint16, quint32, qint32, + quint64, or qint64. Other types of integers, e.g., qlong, are not + applicable. + + There are no data alignment constraints for \a dest. However, \a src is + expected to be naturally aligned for type \c{T}. + + If \a src and \a dest can be the same pointer, this function will perform + an in-place swap (if necessary). If they are not the same, the memory + regions must not overlap. + + \sa qFromLittleEndian() + \sa qToBigEndian() + \sa qToLittleEndian() +*/ /*! \class QLEInteger @@ -200,7 +330,7 @@ \endlist \note Using this class may be slower than using native integers, so only use it when - an exact endian is needed. + an exact endianness is needed. */ /*! \fn template <typename T> QLEInteger<T>::QLEInteger(T value) @@ -303,6 +433,46 @@ */ /*! + \fn template <typename T> QLEInteger &QLEInteger<T>::operator++() + + Performs a prefix ++ (increment) on this QLEInteger and returns a reference to + this object. +*/ + +/*! + \fn template <typename T> QLEInteger QLEInteger<T>::operator++(int) + + Performs a postfix ++ (increment) on this QLEInteger and returns a reference to + this object. +*/ + +/*! + \fn template <typename T> QLEInteger &QLEInteger<T>::operator--() + + Performs a prefix -- (decrement) on this QLEInteger and returns a reference to + this object. +*/ + +/*! + \fn template <typename T> QLEInteger QLEInteger<T>::operator--(int) + + Performs a postfix -- (decrement) on this QLEInteger and returns a reference to + this object. +*/ + +/*! + \fn template <typename T> QLEInteger QLEInteger<T>::max() + + Returns the maximum (finite) value representable by the numeric type T. +*/ + +/*! + \fn template <typename T> QLEInteger QLEInteger<T>::min() + + Returns the minimum (finite) value representable by the numeric type T. +*/ + +/*! \class QBEInteger \inmodule QtCore \brief The QBEInteger class provides platform-independent big-endian integers. @@ -319,7 +489,7 @@ \endlist \note Using this class may be slower than using native integers, so only use it when - an exact endian is needed. + an exact endianness is needed. */ /*! \fn template <typename T> QBEInteger<T>::QBEInteger(T value) @@ -422,6 +592,46 @@ */ /*! + \fn template <typename T> QBEInteger &QBEInteger<T>::operator++() + + Performs a prefix ++ (increment) on this QBEInteger and returns a reference to + this object. +*/ + +/*! + \fn template <typename T> QBEInteger QBEInteger<T>::operator++(int) + + Performs a postfix ++ (increment) on this QBEInteger and returns a reference to + this object. +*/ + +/*! + \fn template <typename T> QBEInteger &QBEInteger<T>::operator--() + + Performs a prefix -- (decrement) on this QBEInteger and returns a reference to + this object. +*/ + +/*! + \fn template <typename T> QBEInteger QBEInteger<T>::operator--(int) + + Performs a postfix -- (decrement) on this QBEInteger and returns a reference to + this object. +*/ + +/*! + \fn template <typename T> QBEInteger QBEInteger<T>::max() + + Returns the maximum (finite) value representable by the numeric type T. +*/ + +/*! + \fn template <typename T> QBEInteger QBEInteger<T>::min() + + Returns the minimum (finite) value representable by the numeric type T. +*/ + +/*! \typedef quint16_le \relates <QtEndian> \since 5.10 @@ -552,3 +762,158 @@ \sa qint64 */ + +#if defined(__SSSE3__) +using ShuffleMask = uchar[16]; +Q_DECL_ALIGN(16) static const ShuffleMask shuffleMasks[3] = { + // 16-bit + {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14}, + // 32-bit + {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12}, + // 64-bit + {7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8} +}; + +static size_t sseSwapLoop(const uchar *src, size_t bytes, uchar *dst, + const __m128i *shuffleMaskPtr) noexcept +{ + size_t i = 0; + const __m128i shuffleMask = _mm_load_si128(shuffleMaskPtr); + +# ifdef __AVX2__ + const __m256i shuffleMask256 = _mm256_inserti128_si256(_mm256_castsi128_si256(shuffleMask), shuffleMask, 1); + for ( ; i + sizeof(__m256i) <= bytes; i += sizeof(__m256i)) { + __m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src + i)); + data = _mm256_shuffle_epi8(data, shuffleMask256); + _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst + i), data); + } +# else + for ( ; i + 2 * sizeof(__m128i) <= bytes; i += 2 * sizeof(__m128i)) { + __m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i)); + __m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i) + 1); + data1 = _mm_shuffle_epi8(data1, shuffleMask); + data2 = _mm_shuffle_epi8(data2, shuffleMask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i), data1); + _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i) + 1, data2); + } +# endif + + if (i + sizeof(__m128i) <= bytes) { + __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i)); + data = _mm_shuffle_epi8(data, shuffleMask); + _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i), data); + i += sizeof(__m128i); + } + + return i; +} + +template <typename T> static Q_ALWAYS_INLINE +size_t simdSwapLoop(const uchar *src, size_t bytes, uchar *dst) noexcept +{ + auto shuffleMaskPtr = reinterpret_cast<const __m128i *>(shuffleMasks[0]); + shuffleMaskPtr += qCountTrailingZeroBits(sizeof(T)) - 1; + size_t i = sseSwapLoop(src, bytes, dst, shuffleMaskPtr); + + // epilogue + for (size_t _i = 0 ; i < bytes && _i < sizeof(__m128i); i += sizeof(T), _i += sizeof(T)) + qbswap(qFromUnaligned<T>(src + i), dst + i); + + // return the total, so the bswapLoop below does nothing + return bytes; +} +#elif defined(__SSE2__) +template <typename T> static +size_t simdSwapLoop(const uchar *, size_t, uchar *) noexcept +{ + // no generic version: we can't do 32- and 64-bit swaps easily, + // so we won't try + return 0; +} + +template <> size_t simdSwapLoop<quint16>(const uchar *src, size_t bytes, uchar *dst) noexcept +{ + auto swapEndian = [](__m128i &data) { + __m128i lows = _mm_srli_epi16(data, 8); + __m128i highs = _mm_slli_epi16(data, 8); + data = _mm_xor_si128(lows, highs); + }; + + size_t i = 0; + for ( ; i + 2 * sizeof(__m128i) <= bytes; i += 2 * sizeof(__m128i)) { + __m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i)); + __m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i) + 1); + swapEndian(data1); + swapEndian(data2); + _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i), data1); + _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i) + 1, data2); + } + + if (i + sizeof(__m128i) <= bytes) { + __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i)); + swapEndian(data); + _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i), data); + i += sizeof(__m128i); + } + + // epilogue + for (size_t _i = 0 ; i < bytes && _i < sizeof(__m128i); i += sizeof(quint16), _i += sizeof(quint16)) + qbswap(qFromUnaligned<quint16>(src + i), dst + i); + + // return the total, so the bswapLoop below does nothing + return bytes; +} +#else +template <typename T> static Q_ALWAYS_INLINE +size_t simdSwapLoop(const uchar *, size_t, uchar *) noexcept +{ + return 0; +} +#endif + +template <typename T> static Q_ALWAYS_INLINE +void *bswapLoop(const uchar *src, size_t n, uchar *dst) noexcept +{ + // Buffers cannot partially overlap: either they're identical or totally + // disjoint (note: they can be adjacent). + if (src != dst) { + quintptr s = quintptr(src); + quintptr d = quintptr(dst); + if (s < d) + Q_ASSERT(s + n <= d); + else + Q_ASSERT(d + n <= s); + } + + size_t i = simdSwapLoop<T>(src, n, dst); + + for ( ; i < n; i += sizeof(T)) + qbswap(qFromUnaligned<T>(src + i), dst + i); + return dst + i; +} + +template <> void *qbswap<2>(const void *source, qsizetype n, void *dest) noexcept +{ + const uchar *src = reinterpret_cast<const uchar *>(source); + uchar *dst = reinterpret_cast<uchar *>(dest); + + return bswapLoop<quint16>(src, n << 1, dst); +} + +template <> void *qbswap<4>(const void *source, qsizetype n, void *dest) noexcept +{ + const uchar *src = reinterpret_cast<const uchar *>(source); + uchar *dst = reinterpret_cast<uchar *>(dest); + + return bswapLoop<quint32>(src, n << 2, dst); +} + +template <> void *qbswap<8>(const void *source, qsizetype n, void *dest) noexcept +{ + const uchar *src = reinterpret_cast<const uchar *>(source); + uchar *dst = reinterpret_cast<uchar *>(dest); + + return bswapLoop<quint64>(src, n << 3, dst); +} + +QT_END_NAMESPACE diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index a14fce23f8..1cc8a823d9 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -47,6 +47,11 @@ #include <stdlib.h> #include <string.h> +#ifdef min // MSVC +#undef min +#undef max +#endif + QT_BEGIN_NAMESPACE /* @@ -157,6 +162,14 @@ template <typename T> inline void qbswap(const T src, void *dest) qToUnaligned<T>(qbswap<T>(src), dest); } +template <int Size> void *qbswap(const void *source, qsizetype count, void *dest) noexcept; +template<> inline void *qbswap<1>(const void *source, qsizetype count, void *dest) noexcept +{ + return source != dest ? memcpy(dest, source, size_t(count)) : dest; +} +template<> Q_CORE_EXPORT void *qbswap<2>(const void *source, qsizetype count, void *dest) noexcept; +template<> Q_CORE_EXPORT void *qbswap<4>(const void *source, qsizetype count, void *dest) noexcept; +template<> Q_CORE_EXPORT void *qbswap<8>(const void *source, qsizetype count, void *dest) noexcept; #if Q_BYTE_ORDER == Q_BIG_ENDIAN @@ -172,6 +185,15 @@ template <typename T> inline void qToBigEndian(T src, void *dest) { qToUnaligned<T>(src, dest); } template <typename T> inline void qToLittleEndian(T src, void *dest) { qbswap<T>(src, dest); } + +template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest) +{ if (source != dest) memcpy(dest, source, count * sizeof(T)); } +template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest) +{ qbswap<sizeof(T)>(source, count, dest); } +template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest) +{ if (source != dest) memcpy(dest, source, count * sizeof(T)); } +template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest) +{ qbswap<sizeof(T)>(source, count, dest); } #else // Q_LITTLE_ENDIAN template <typename T> inline Q_DECL_CONSTEXPR T qToBigEndian(T source) @@ -187,6 +209,14 @@ template <typename T> inline void qToBigEndian(T src, void *dest) template <typename T> inline void qToLittleEndian(T src, void *dest) { qToUnaligned<T>(src, dest); } +template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest) +{ qbswap<sizeof(T)>(source, count, dest); } +template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest) +{ if (source != dest) memcpy(dest, source, count * sizeof(T)); } +template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest) +{ qbswap<sizeof(T)>(source, count, dest); } +template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest) +{ if (source != dest) memcpy(dest, source, count * sizeof(T)); } #endif // Q_BYTE_ORDER == Q_BIG_ENDIAN @@ -254,6 +284,27 @@ public: { return (*this = S::fromSpecial(val) & i); } QSpecialInteger &operator ^=(T i) { return (*this = S::fromSpecial(val) ^ i); } + QSpecialInteger &operator ++() + { return (*this = S::fromSpecial(val) + 1); } + QSpecialInteger &operator --() + { return (*this = S::fromSpecial(val) - 1); } + QSpecialInteger operator ++(int) + { + QSpecialInteger<S> pre = *this; + *this += 1; + return pre; + } + QSpecialInteger operator --(int) + { + QSpecialInteger<S> pre = *this; + *this -= 1; + return pre; + } + + static constexpr QSpecialInteger max() + { return QSpecialInteger(std::numeric_limits<T>::max()); } + static constexpr QSpecialInteger min() + { return QSpecialInteger(std::numeric_limits<T>::min()); } }; template<typename T> @@ -291,6 +342,13 @@ public: QLEInteger &operator |=(T i); QLEInteger &operator &=(T i); QLEInteger &operator ^=(T i); + QLEInteger &operator ++(); + QLEInteger &operator --(); + QLEInteger &operator ++(int); + QLEInteger &operator --(int); + + static constexpr QLEInteger max(); + static constexpr QLEInteger min(); }; template<typename T> @@ -311,6 +369,13 @@ public: QBEInteger &operator |=(T i); QBEInteger &operator &=(T i); QBEInteger &operator ^=(T i); + QBEInteger &operator ++(); + QBEInteger &operator --(); + QBEInteger &operator ++(int); + QBEInteger &operator --(int); + + static constexpr QBEInteger max(); + static constexpr QBEInteger min(); }; #else diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index b30d690025..a369bbe490 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -53,10 +53,6 @@ #include <qmutex.h> -#ifndef QT_NO_QOBJECT -#include <private/qthread_p.h> -#endif - #include <stdlib.h> #include <limits.h> #include <stdarg.h> @@ -650,7 +646,8 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value)); The remaining macros are convenience macros for larger operations: The QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRANSLATE_NOOP3() macros provide the possibility of marking strings for delayed - translation. + translation. QT_TR_N_NOOP(), QT_TRANSLATE_N_NOOP(), and + QT_TRANSLATE_N_NOOP3() are numerator dependent variants of these. The Q_ASSERT() and Q_ASSERT_X() enables warning messages of various level of refinement. The Q_FOREACH() and foreach() macros implement Qt's foreach loop. @@ -3450,7 +3447,27 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) Q_DECL_NOEXCEPT bool ok_ = true; const char *endptr; const qlonglong value = qstrtoll(buffer, &endptr, 0, &ok_); - if (int(value) != value || *endptr != '\0') { // this is the check in QByteArray::toInt(), keep it in sync + + // Keep the following checks in sync with QByteArray::toInt() + if (!ok_) { + if (ok) + *ok = false; + return 0; + } + + if (*endptr != '\0') { + while (ascii_isspace(*endptr)) + ++endptr; + } + + if (*endptr != '\0') { + // we stopped at a non-digit character after converting some digits + if (ok) + *ok = false; + return 0; + } + + if (int(value) != value) { if (ok) *ok = false; return 0; @@ -3755,6 +3772,71 @@ bool qunsetenv(const char *varName) */ /*! + \macro QT_TR_N_NOOP(sourceText) + \relates <QtGlobal> + \since 5.12 + + Marks the UTF-8 encoded string literal \a sourceText for numerator + dependent delayed translation in the current context (class). + + The macro tells lupdate to collect the string, and expands to + \a sourceText itself. + + The macro expands to \a sourceText. + + Example: + + \snippet code/src_corelib_global_qglobal.cpp qttrnnoop + + \sa QT_TR_NOOP, {Internationalization with Qt} +*/ + +/*! + \macro QT_TRANSLATE_N_NOOP(context, sourceText) + \relates <QtGlobal> + \since 5.12 + + Marks the UTF-8 encoded string literal \a sourceText for numerator + dependent delayed translation in the given \a context. + The \a context is typically a class name and also needs to be + specified as a string literal. + + The macro tells lupdate to collect the string, and expands to + \a sourceText itself. + + Example: + + \snippet code/src_corelib_global_qglobal.cpp qttranslatennoop + + \sa QT_TRANSLATE_NOOP(), QT_TRANSLATE_N_NOOP3(), + {Internationalization with Qt} +*/ + +/*! + \macro QT_TRANSLATE_N_NOOP3(context, sourceText, comment) + \relates <QtGlobal> + \since 5.12 + + Marks the UTF-8 encoded string literal \a sourceText for numerator + dependent delayed translation in the given \a context with the given + \a comment. + The \a context is typically a class and also needs to be specified + as a string literal. The string literal \a disambiguation should be + a short semantic tag to tell apart otherwise identical strings. + + The macro tells lupdate to collect the string, and expands to an + anonymous struct of the two string literals passed as \a sourceText + and \a comment. + + Example: + + \snippet code/src_corelib_global_qglobal.cpp qttranslatennoop3 + + \sa QT_TR_NOOP(), QT_TRANSLATE_NOOP(), QT_TRANSLATE_NOOP3(), + {Internationalization with Qt} +*/ + +/*! \fn QString qtTrId(const char *id, int n = -1) \relates <QtGlobal> \reentrant diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 3684c6b5de..b608489576 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1034,8 +1034,8 @@ for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ # endif #endif -template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; } -template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); } +template <typename T> inline T *qGetPtrHelper(T *ptr) { return ptr; } +template <typename Ptr> inline auto qGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); } #define Q_DECLARE_PRIVATE(Class) \ inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \ @@ -1064,6 +1064,10 @@ template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelpe #ifndef QT_NO_TRANSLATION // ### Qt6: This should enclose the NOOPs above +#define QT_TR_N_NOOP(x) x +#define QT_TRANSLATE_N_NOOP(scope, x) x +#define QT_TRANSLATE_N_NOOP3(scope, x, comment) {x, comment} + // Defined in qcoreapplication.cpp // The better name qTrId() is reserved for an upcoming function which would // return a much more powerful QStringFormatter instead of a QString. diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h index 7a6dea9b92..555bdf04c1 100644 --- a/src/corelib/global/qglobalstatic.h +++ b/src/corelib/global/qglobalstatic.h @@ -55,7 +55,7 @@ enum GuardValues { }; } -#if defined(QT_NO_THREAD) || defined(Q_COMPILER_THREADSAFE_STATICS) +#if !QT_CONFIG(thread) || defined(Q_COMPILER_THREADSAFE_STATICS) // some compilers support thread-safe statics // The IA-64 C++ ABI requires this, so we know that all GCC versions since 3.4 // support it. C++11 also requires this behavior. diff --git a/src/corelib/global/qglobalstatic.qdoc b/src/corelib/global/qglobalstatic.qdoc index 303709bb1d..dbea04ecab 100644 --- a/src/corelib/global/qglobalstatic.qdoc +++ b/src/corelib/global/qglobalstatic.qdoc @@ -264,7 +264,7 @@ [stmt.decl], but as of the time of this writing, only compilers based on the IA-64 C++ ABI implemented it properly. The implementation requiring thread-safe initialization is also used on the Qt bootstrapped tools, which - define QT_NO_THREAD. + disable the "thread" feature. The implementation requiring thread-safe initialization from the compiler is the simplest: it creates the \a Type object as a function-local static diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 7444145e82..a931b43220 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -2,7 +2,7 @@ ** ** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -61,6 +61,9 @@ #ifdef Q_OS_WIN #include <qt_windows.h> #endif +#ifdef Q_CC_MSVC +#include <intrin.h> +#endif #if QT_CONFIG(slog2) #include <sys/slog2.h> #endif @@ -240,7 +243,7 @@ static bool systemHasStderr() \internal \sa systemHasStderr() */ -bool stderrHasConsoleAttached() +static bool stderrHasConsoleAttached() { static const bool stderrHasConsoleAttached = []() -> bool { if (!systemHasStderr()) @@ -1208,8 +1211,8 @@ void QMessagePattern::setPattern(const QString &pattern) tokens[i] = backtraceTokenC; QString backtraceSeparator = QStringLiteral("|"); int backtraceDepth = 5; - QRegularExpression depthRx(QStringLiteral(" depth=(?|\"([^\"]*)\"|([^ }]*))")); - QRegularExpression separatorRx(QStringLiteral(" separator=(?|\"([^\"]*)\"|([^ }]*))")); + static const QRegularExpression depthRx(QStringLiteral(" depth=(?|\"([^\"]*)\"|([^ }]*))")); + static const QRegularExpression separatorRx(QStringLiteral(" separator=(?|\"([^\"]*)\"|([^ }]*))")); QRegularExpressionMatch m = depthRx.match(lexeme); if (m.hasMatch()) { int depth = m.capturedRef(1).toInt(); @@ -1295,8 +1298,7 @@ static QStringList backtraceFramesForLogMessage(int frameCount) // The offset and function name are optional. // This regexp tries to extract the library name (without the path) and the function name. // This code is protected by QMessagePattern::mutex so it is thread safe on all compilers - static QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"), - QRegularExpression::OptimizeOnFirstUsageOption); + static const QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$")); QVarLengthArray<void*, 32> buffer(8 + frameCount); int n = backtrace(buffer.data(), buffer.size()); @@ -1839,7 +1841,31 @@ static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const Q_UNUSED(message); #endif +#ifdef Q_OS_WIN + // std::abort() in the MSVC runtime will call _exit(3) if the abort + // behavior is _WRITE_ABORT_MSG - see also _set_abort_behavior(). This is + // the default for a debug-mode build of the runtime. Worse, MinGW's + // std::abort() implementation (in msvcrt.dll) is basically a call to + // _exit(3) too. Unfortunately, _exit() and _Exit() *do* run the static + // destructors of objects in DLLs, a violation of the C++ standard (see + // [support.start.term]). So we bypass std::abort() and directly + // terminate the application. + +# ifdef Q_CC_MSVC + if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE)) + __fastfail(FAST_FAIL_FATAL_APP_EXIT); +# else + RaiseFailFastException(nullptr, nullptr, 0); +# endif + + // Fallback + TerminateProcess(GetCurrentProcess(), STATUS_FATAL_APP_EXIT); + + // Tell the compiler the application has stopped. + Q_UNREACHABLE_IMPL(); +#else // !Q_OS_WIN std::abort(); +#endif } diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 31b1823690..dec2c44637 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -107,6 +107,7 @@ public: KeyboardModifierMask = 0xfe000000 }; Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier) + Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardModifiers) //shorter names for shortcuts // The use of all-caps identifiers has the potential for clashing with @@ -163,6 +164,7 @@ public: MouseButtonMask = 0xffffffff }; Q_DECLARE_FLAGS(MouseButtons, MouseButton) + Q_DECLARE_OPERATORS_FOR_FLAGS(MouseButtons) enum Orientation { Horizontal = 0x1, @@ -170,6 +172,7 @@ public: }; Q_DECLARE_FLAGS(Orientations, Orientation) + Q_DECLARE_OPERATORS_FOR_FLAGS(Orientations) enum FocusPolicy { NoFocus = 0, @@ -225,6 +228,7 @@ public: }; Q_DECLARE_FLAGS(Alignment, AlignmentFlag) + Q_DECLARE_OPERATORS_FOR_FLAGS(Alignment) enum TextFlag { TextSingleLine = 0x0100, @@ -308,6 +312,7 @@ public: }; Q_DECLARE_FLAGS(WindowFlags, WindowType) + Q_DECLARE_OPERATORS_FOR_FLAGS(WindowFlags) enum WindowState { WindowNoState = 0x00000000, @@ -318,6 +323,7 @@ public: }; Q_DECLARE_FLAGS(WindowStates, WindowState) + Q_DECLARE_OPERATORS_FOR_FLAGS(WindowStates) enum ApplicationState { ApplicationSuspended = 0x00000000, @@ -337,6 +343,7 @@ public: }; Q_DECLARE_FLAGS(ScreenOrientations, ScreenOrientation) + Q_DECLARE_OPERATORS_FOR_FLAGS(ScreenOrientations) enum WidgetAttribute { WA_Disabled = 0, @@ -479,6 +486,8 @@ public: WA_ContentsMarginsRespectsSafeArea = 130, + WA_StyleSheetTarget = 131, + // Add new attributes before this line WA_AttributeCount }; @@ -553,6 +562,7 @@ public: NoFormatConversion = 0x00000200 }; Q_DECLARE_FLAGS(ImageConversionFlags, ImageConversionFlag) + Q_DECLARE_OPERATORS_FOR_FLAGS(ImageConversionFlags) enum BGMode { TransparentMode, @@ -1210,6 +1220,7 @@ public: }; Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea) + Q_DECLARE_OPERATORS_FOR_FLAGS(DockWidgetAreas) enum ToolBarArea { LeftToolBarArea = 0x1, @@ -1227,6 +1238,7 @@ public: }; Q_DECLARE_FLAGS(ToolBarAreas, ToolBarArea) + Q_DECLARE_OPERATORS_FOR_FLAGS(ToolBarAreas) enum DateFormat { TextDate, // default Qt @@ -1285,6 +1297,7 @@ public: }; Q_DECLARE_FLAGS(Edges, Edge) + Q_DECLARE_OPERATORS_FOR_FLAGS(Edges) enum ConnectionType { AutoConnection, @@ -1387,6 +1400,7 @@ public: ImQueryAll = 0xffffffff }; Q_DECLARE_FLAGS(InputMethodQueries, InputMethodQuery) + Q_DECLARE_OPERATORS_FOR_FLAGS(InputMethodQueries) enum InputMethodHint { ImhNone = 0x0, @@ -1421,6 +1435,7 @@ public: ImhExclusiveInputMask = 0xffff0000 }; Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint) + Q_DECLARE_OPERATORS_FOR_FLAGS(InputMethodHints) enum EnterKeyType { EnterKeyDefault, @@ -1471,6 +1486,7 @@ public: IgnoreAction = 0x0 }; Q_DECLARE_FLAGS(DropActions, DropAction) + Q_DECLARE_OPERATORS_FOR_FLAGS(DropActions) enum CheckState { Unchecked, @@ -1525,6 +1541,7 @@ public: ItemIsUserTristate = 256 }; Q_DECLARE_FLAGS(ItemFlags, ItemFlag) + Q_DECLARE_OPERATORS_FOR_FLAGS(ItemFlags) enum MatchFlag { MatchExactly = 0, @@ -1539,6 +1556,7 @@ public: MatchRecursive = 64 }; Q_DECLARE_FLAGS(MatchFlags, MatchFlag) + Q_DECLARE_OPERATORS_FOR_FLAGS(MatchFlags) typedef void * HANDLE; #if QT_DEPRECATED_SINCE(5, 0) @@ -1563,6 +1581,7 @@ public: TextBrowserInteraction = TextSelectableByMouse | LinksAccessibleByMouse | LinksAccessibleByKeyboard }; Q_DECLARE_FLAGS(TextInteractionFlags, TextInteractionFlag) + Q_DECLARE_OPERATORS_FOR_FLAGS(TextInteractionFlags) enum EventPriority { HighEventPriority = 1, @@ -1614,6 +1633,7 @@ public: TouchPointReleased = 0x08 }; Q_DECLARE_FLAGS(TouchPointStates, TouchPointState) + Q_DECLARE_OPERATORS_FOR_FLAGS(TouchPointStates) #ifndef QT_NO_GESTURES enum GestureState @@ -1645,6 +1665,7 @@ public: IgnoredGesturesPropagateToParent = 0x04 }; Q_DECLARE_FLAGS(GestureFlags, GestureFlag) + Q_DECLARE_OPERATORS_FOR_FLAGS(GestureFlags) enum NativeGestureType { @@ -1683,7 +1704,8 @@ public: NoScrollPhase = 0, ScrollBegin, ScrollUpdate, - ScrollEnd + ScrollEnd, + ScrollMomentum }; enum MouseEventSource { @@ -1698,6 +1720,7 @@ public: MouseEventFlagMask = 0xFF }; Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag) + Q_DECLARE_OPERATORS_FOR_FLAGS(MouseEventFlags) enum ChecksumType { ChecksumIso3309, @@ -1800,29 +1823,6 @@ public: #undef QT_Q_ENUM #undef QT_Q_FLAG -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseButtons) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Orientations) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::KeyboardModifiers) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::WindowFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Alignment) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Edges) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ImageConversionFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::DockWidgetAreas) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ToolBarAreas) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::WindowStates) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ScreenOrientations) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::DropActions) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ItemFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodQueries) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates) -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseEventFlags) -#ifndef QT_NO_GESTURES -Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::GestureFlags) -#endif - typedef bool (*qInternalCallback)(void **); class Q_CORE_EXPORT QInternal { @@ -1864,16 +1864,6 @@ public: static bool activateCallbacks(Callback, void **); }; -#if defined(Q_CLANG_QDOC) -// Declared here for qdoc; actual declarations in qtextdocument.h -namespace Qt -{ - bool mightBeRichText(const QString&); - QString convertFromPlainText(const QString &plain, WhiteSpaceMode mode = WhiteSpacePre); - QTextCodec *codecForHtml(const QByteArray &ba); -} -#endif // Q_CLANG_QDOC - QT_END_NAMESPACE #endif // QNAMESPACE_H diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index d6191d1585..37144dcf17 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -383,7 +383,8 @@ \value AltModifier An Alt key on the keyboard is pressed. \value MetaModifier A Meta key on the keyboard is pressed. \value KeypadModifier A keypad button is pressed. - \value GroupSwitchModifier X11 only. A Mode_switch key on the keyboard is pressed. + \value GroupSwitchModifier X11 only (unless activated on Windows by a command line argument). + A Mode_switch key on the keyboard is pressed. \omitvalue KeyboardModifierMask @@ -1155,7 +1156,12 @@ the widget's author. \value WA_StyleSheet Indicates that the widget is styled using a - \l{Qt Style Sheets}{style sheet}. + \l{Qt Style Sheets}{style sheet}. WA_StyleSheet is set whenever a widget + is subject to a style sheet, even if the style sheet did not affect the + widget appearance. + + \value WA_StyleSheetTarget Indicates that the widget appearance was modified + by a \l{Qt Style Sheets}{style sheet}. WA_StyleSheet will also be set. \value WA_TabletTracking Indicates that the widget has tablet tracking enabled. See QWidget::tabletTracking. @@ -3232,37 +3238,3 @@ \value ChecksumItuV41 Checksum calculation based on ITU-V.41. */ - -/*! - \fn bool Qt::mightBeRichText(const QString& text) - - Returns \c true if the string \a text is likely to be rich text; - otherwise returns \c false. - - This function uses a fast and therefore simple heuristic. It - mainly checks whether there is something that looks like a tag - before the first line break. Although the result may be correct - for common cases, there is no guarantee. - - This function is defined in the \c <QTextDocument> header file. -*/ - -/*! - \fn QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode) - - Converts the plain text string \a plain to an HTML-formatted - paragraph while preserving most of its look. - - \a mode defines how whitespace is handled. - - This function is defined in the \c <QTextDocument> header file. - - \sa escape(), mightBeRichText() -*/ - -/*! - \fn QTextCodec *Qt::codecForHtml(const QByteArray &ba) - \internal - - This function is defined in the \c <QTextDocument> header file. -*/ diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 5f8a124bcc..9c8514f5a3 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -163,6 +163,58 @@ Q_DECL_CONST_FUNCTION static inline bool qt_is_finite(float f) #ifndef Q_CLANG_QDOC namespace { +/*! + Returns true if the double \a v can be converted to type \c T, false if + it's out of range. If the conversion is successful, the converted value is + stored in \a value; if it was not successful, \a value will contain the + minimum or maximum of T, depending on the sign of \a d. If \c T is + unsigned, then \a value contains the absolute value of \a v. + + This function works for v containing infinities, but not NaN. It's the + caller's responsibility to exclude that possibility before calling it. +*/ +template <typename T> static inline bool convertDoubleTo(double v, T *value) +{ + Q_STATIC_ASSERT(std::numeric_limits<T>::is_integer); + + // The [conv.fpint] (7.10 Floating-integral conversions) section of the C++ + // standard says only exact conversions are guaranteed. Converting + // integrals to floating-point with loss of precision has implementation- + // defined behavior whether the next higher or next lower is returned; + // converting FP to integral is UB if it can't be represented. + // + // That means we can't write UINT64_MAX+1. Writing ldexp(1, 64) would be + // correct, but Clang, ICC and MSVC don't realize that it's a constant and + // the math call stays in the compiled code. + + double supremum; + if (std::numeric_limits<T>::is_signed) { + supremum = -1.0 * std::numeric_limits<T>::min(); // -1 * (-2^63) = 2^63, exact (for T = qint64) + *value = std::numeric_limits<T>::min(); + if (v < std::numeric_limits<T>::min()) + return false; + } else { + using ST = typename std::make_signed<T>::type; + supremum = -2.0 * std::numeric_limits<ST>::min(); // -2 * (-2^63) = 2^64, exact (for T = quint64) + v = fabs(v); + } + + *value = std::numeric_limits<T>::max(); + if (v >= supremum) + return false; + + // Now we can convert, these two conversions cannot be UB + *value = T(v); + +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wfloat-equal") +QT_WARNING_DISABLE_CLANG("-Wfloat-equal") + + return *value == v; + +QT_WARNING_POP +} + // Overflow math. // This provides efficient implementations for int, unsigned, qsizetype and // size_t. Implementations for 8- and 16-bit types will work but may not be as diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index 0b260d01e3..9a3dfd776d 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -57,7 +57,7 @@ optional and usually dependent on how the compiler was invoked. Variants that are a superset of another should have a define for the superset. - In addition to the procesor family, variants, and revisions, we also set + In addition to the processor family, variants, and revisions, we also set Q_BYTE_ORDER appropriately for the target processor. For bi-endian processors, we try to auto-detect the byte order using the __BIG_ENDIAN__, __LITTLE_ENDIAN__, or __BYTE_ORDER__ preprocessor macros. diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index ebf9864b15..a7d4aa303a 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -527,7 +527,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel \code QRandomGenerator prng1(1234), prng2(1234); - Q_ASSERT(prng1.generate32() == prng2.generate32()); + Q_ASSERT(prng1.generate() == prng2.generate()); Q_ASSERT(prng1.generate64() == prng2.generate64()); \endcode @@ -553,8 +553,8 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel be easily used, as in the following example: \code - int x = QRandomGenerator::global()->generate32(); - int y = QRandomGenerator::global()->generate32(); + int x = QRandomGenerator::global()->generate(); + int y = QRandomGenerator::global()->generate(); int w = QRandomGenerator::global()->bounded(16384); int h = QRandomGenerator::global()->bounded(16384); \endcode @@ -1298,7 +1298,7 @@ struct QRandEngine }; } -#if defined(QT_NO_THREAD) || defined(Q_OS_WIN) +#if defined(Q_OS_WIN) // On Windows srand() and rand() already use Thread-Local-Storage // to store the seed between calls static inline QRandEngine *randTLS() diff --git a/src/corelib/global/qtrace_p.h b/src/corelib/global/qtrace_p.h index ab8fc14af5..3d04a7311d 100644 --- a/src/corelib/global/qtrace_p.h +++ b/src/corelib/global/qtrace_p.h @@ -109,6 +109,8 @@ * qcoreapplication_baz above. */ +#include <QtCore/qglobal.h> + QT_BEGIN_NAMESPACE #if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED) diff --git a/src/corelib/global/qversiontagging.cpp b/src/corelib/global/qversiontagging.cpp index cbfd93f135..b5e524bf4c 100644 --- a/src/corelib/global/qversiontagging.cpp +++ b/src/corelib/global/qversiontagging.cpp @@ -93,7 +93,16 @@ make_versioned_symbol(SYM, QT_VERSION_MAJOR, 11, "@"); make_versioned_symbol(SYM, QT_VERSION_MAJOR, 12, "@"); #endif #if QT_VERSION_MINOR > 13 -// We don't expect there will be a Qt 5.13 +make_versioned_symbol(SYM, QT_VERSION_MAJOR, 13, "@"); +#endif +#if QT_VERSION_MINOR > 14 +make_versioned_symbol(SYM, QT_VERSION_MAJOR, 14, "@"); +#endif +#if QT_VERSION_MINOR > 15 +make_versioned_symbol(SYM, QT_VERSION_MAJOR, 15, "@"); +#endif +#if QT_VERSION_MINOR > 16 +// We don't expect there will be a Qt 5.17 # error "Please update this file with more Qt versions." #endif |