diff options
Diffstat (limited to 'src/corelib/global')
25 files changed, 1783 insertions, 307 deletions
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 36655ca1dd..f162dd95dd 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -2,6 +2,8 @@ HEADERS += \ global/qglobal.h \ + global/qoperatingsystemversion.h \ + global/qoperatingsystemversion_p.h \ global/qsystemdetection.h \ global/qcompilerdetection.h \ global/qprocessordetection.h \ @@ -9,6 +11,8 @@ HEADERS += \ global/qendian.h \ global/qnumeric_p.h \ global/qnumeric.h \ + global/qfloat16_p.h \ + global/qfloat16.h \ global/qglobalstatic.h \ global/qlibraryinfo.h \ global/qlogging.h \ @@ -27,11 +31,16 @@ SOURCES += \ global/qlibraryinfo.cpp \ global/qmalloc.cpp \ global/qnumeric.cpp \ + global/qfloat16.cpp \ + global/qoperatingsystemversion.cpp \ global/qlogging.cpp \ global/qhooks.cpp VERSIONTAGGING_SOURCES = global/qversiontagging.cpp +darwin: SOURCES += global/qoperatingsystemversion_darwin.mm +win32: SOURCES += global/qoperatingsystemversion_win.cpp + # qlibraryinfo.cpp includes qconfig.cpp INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global @@ -70,3 +79,17 @@ gcc:ltcg { } else { SOURCES += $$VERSIONTAGGING_SOURCES } + +# On AARCH64 the fp16 extension is mandatory, so we don't need the conversion tables. +!contains(QT_ARCH, "arm64") { + QMAKE_QFLOAT16_TABLES_GENERATE = global/qfloat16.h + + qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables) + + qfloat16_tables.commands = $$QMAKE_QFLOAT16_TABLES ${QMAKE_FILE_OUT} + qfloat16_tables.output = global/qfloat16tables.cpp + qfloat16_tables.depends = $$QMAKE_QFLOAT16_TABLES + qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE + qfloat16_tables.variable_out = SOURCES + QMAKE_EXTRA_COMPILERS += qfloat16_tables +} diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index eacb7a04d7..fcfe020509 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -354,6 +354,7 @@ # elif defined(__ghs) # define Q_CC_GHS # define Q_DECL_DEPRECATED __attribute__ ((__deprecated__)) +# define Q_PACKED __attribute__ ((__packed__)) # define Q_FUNC_INFO __PRETTY_FUNCTION__ # define Q_TYPEOF(expr) __typeof__(expr) # define Q_ALIGNOF(type) __alignof__(type) diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h index b871c90c9d..feeb488acd 100644 --- a/src/corelib/global/qflags.h +++ b/src/corelib/global/qflags.h @@ -42,15 +42,14 @@ #ifndef QFLAGS_H #define QFLAGS_H -#include <QtCore/qtypeinfo.h> -#include <QtCore/qtypetraits.h> - #ifdef Q_COMPILER_INITIALIZER_LISTS #include <initializer_list> #endif QT_BEGIN_NAMESPACE +class QDataStream; + class QFlag { int i; @@ -94,8 +93,12 @@ class QFlags Q_STATIC_ASSERT_X((sizeof(Enum) <= sizeof(int)), "QFlags uses an int as storage, so an enum with underlying " "long long will overflow."); + Q_STATIC_ASSERT_X((std::is_enum<Enum>::value), "QFlags is only usable on enumeration types."); + struct Private; typedef int (Private::*Zero); + template <typename E> friend QDataStream &operator>>(QDataStream &, QFlags<E> &); + template <typename E> friend QDataStream &operator<<(QDataStream &, QFlags<E>); public: #if defined(Q_CC_MSVC) || defined(Q_QDOC) // see above for MSVC @@ -103,7 +106,7 @@ public: typedef int Int; #else typedef typename std::conditional< - QtPrivate::QIsUnsignedEnum<Enum>::value, + std::is_unsigned<typename std::underlying_type<Enum>::type>::value, unsigned int, signed int >::type Int; diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp new file mode 100644 index 0000000000..1de1ae65fb --- /dev/null +++ b/src/corelib/global/qfloat16.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2016 by Southwest Research Institute (R) +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfloat16_p.h" + +QT_BEGIN_NAMESPACE + +/*! \headerfile <QFloat16> + + This header file provides support for half-precision (16-bit) floating + point data with the class \c qfloat16. It is fully compliant with IEEE + 754 as a storage type. This implies that any arithmetic operation on a + \c qfloat16 instance results in the value first being converted to a + \c float. This conversion to and from \c float is performed by hardware + when possible, but on processors that do not natively support half-precision, + the conversion is performed through a sequence of lookup table operations. + + \c qfloat16 should be treated as if it were a POD (plain old data) type. + Consequently, none of the supported operations need any elaboration beyond + stating that it supports all arithmetic operators incident to floating point + types. + + \since 5.9 +*/ + +Q_STATIC_ASSERT_X(sizeof(float) == sizeof(quint32), + "qfloat16 assumes that floats are 32 bits wide"); + +// There are a few corner cases regarding denormals where GHS compiler is relying +// hardware behavior that is not IEC 559 compliant. Therefore the compiler +// reports std::numeric_limits<float>::is_iec559 as false. This is all right +// according to our needs. + +#if !defined(Q_CC_GHS) +Q_STATIC_ASSERT_X(std::numeric_limits<float>::is_iec559, + "Only works with IEEE 754 floating point"); +#endif + +Q_STATIC_ASSERT_X(std::numeric_limits<float>::has_infinity && + std::numeric_limits<float>::has_quiet_NaN && + std::numeric_limits<float>::has_signaling_NaN, + "Only works with IEEE 754 floating point"); + +/*! + Returns true if the \c qfloat16 \a {f} is equivalent to infinity. + \relates <QFloat16> + + \sa qIsInf +*/ +Q_REQUIRED_RESULT bool qIsInf(qfloat16 f) Q_DECL_NOTHROW { return qt_is_inf(f); } + +/*! + Returns true if the \c qfloat16 \a {f} is not a number (NaN). + \relates <QFloat16> + + \sa qIsNaN +*/ +Q_REQUIRED_RESULT bool qIsNaN(qfloat16 f) Q_DECL_NOTHROW { return qt_is_nan(f); } + +/*! + Returns true if the \c qfloat16 \a {f} is a finite number. + \relates <QFloat16> + + \sa qIsFinite +*/ +Q_REQUIRED_RESULT bool qIsFinite(qfloat16 f) Q_DECL_NOTHROW { return qt_is_finite(f); } + +/*! \fn int qRound(qfloat16 value) + \relates <QFloat16> + + Rounds \a value to the nearest integer. + + \sa qRound +*/ + +/*! \fn qint64 qRound64(qfloat16 value) + \relates <QFloat16> + + Rounds \a value to the nearest 64-bit integer. + + \sa qRound64 +*/ + +/*! \fn bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) + \relates <QFloat16> + + Compares the floating point value \a p1 and \a p2 and + returns \c true if they are considered equal, otherwise \c false. + + The two numbers are compared in a relative way, where the + exactness is stronger the smaller the numbers are. + */ + +QT_END_NAMESPACE diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h new file mode 100644 index 0000000000..05b88e0e92 --- /dev/null +++ b/src/corelib/global/qfloat16.h @@ -0,0 +1,258 @@ +/**************************************************************************** +** +** Copyright (C) 2016 by Southwest Research Institute (R) +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFLOAT16_H +#define QFLOAT16_H + +#include <QtCore/qglobal.h> +#include <QtCore/qmetatype.h> +#include <string.h> + +#if defined __F16C__ +#include <immintrin.h> +#endif + +QT_BEGIN_NAMESPACE + +#if 0 +#pragma qt_class(QFloat16) +#pragma qt_no_master_include +#endif + +class qfloat16 +{ +public: +#ifndef Q_QDOC + Q_DECL_CONSTEXPR inline qfloat16() Q_DECL_NOTHROW : b16(0) { } + inline qfloat16(float f) Q_DECL_NOTHROW; + inline operator float() const Q_DECL_NOTHROW; + inline operator double() const Q_DECL_NOTHROW; + inline operator long double() const Q_DECL_NOTHROW; +#endif + +private: + quint16 b16; + + Q_CORE_EXPORT static const quint32 mantissatable[]; + Q_CORE_EXPORT static const quint32 exponenttable[]; + Q_CORE_EXPORT static const quint32 offsettable[]; + Q_CORE_EXPORT static const quint32 basetable[]; + Q_CORE_EXPORT static const quint32 shifttable[]; + + friend bool qIsNull(qfloat16 f) Q_DECL_NOTHROW; + friend qfloat16 operator-(qfloat16 a) Q_DECL_NOTHROW; +}; + +Q_DECLARE_TYPEINFO(qfloat16, Q_PRIMITIVE_TYPE); + +Q_CORE_EXPORT Q_REQUIRED_RESULT bool qIsInf(qfloat16 f) Q_DECL_NOTHROW; // complements qnumeric.h +Q_CORE_EXPORT Q_REQUIRED_RESULT bool qIsNaN(qfloat16 f) Q_DECL_NOTHROW; // complements qnumeric.h +Q_CORE_EXPORT Q_REQUIRED_RESULT bool qIsFinite(qfloat16 f) Q_DECL_NOTHROW; // complements qnumeric.h + +// The remainder of these utility functions complement qglobal.h +inline Q_REQUIRED_RESULT int qRound(qfloat16 d) Q_DECL_NOTHROW +{ return qRound(static_cast<float>(d)); } + +inline Q_REQUIRED_RESULT qint64 qRound64(qfloat16 d) Q_DECL_NOTHROW +{ return qRound64(static_cast<float>(d)); } + +inline Q_REQUIRED_RESULT bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) Q_DECL_NOTHROW +{ + float f1 = static_cast<float>(p1); + float f2 = static_cast<float>(p2); + // The significand precision for IEEE754 half precision is + // 11 bits (10 explicitly stored), or approximately 3 decimal + // digits. In selecting the fuzzy comparison factor of 102.5f + // (that is, (2^10+1)/10) below, we effectively select a + // window of about 1 (least significant) decimal digit about + // which the two operands can vary and still return true. + return (qAbs(f1 - f2) * 102.5f <= qMin(qAbs(f1), qAbs(f2))); +} + +inline Q_REQUIRED_RESULT bool qIsNull(qfloat16 f) Q_DECL_NOTHROW +{ + return (f.b16 & static_cast<quint16>(0x7fff)) == 0; +} + +inline int qIntCast(qfloat16 f) Q_DECL_NOTHROW +{ return int(static_cast<float>(f)); } + +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wc99-extensions") +inline qfloat16::qfloat16(float f) Q_DECL_NOTHROW +{ +#if defined(QT_COMPILER_SUPPORTS_F16C) && (defined(__F16C__) || defined(__AVX2__)) + __m128 packsingle = _mm_set_ss(f); + __m128i packhalf = _mm_cvtps_ph(packsingle, 0); + b16 = _mm_extract_epi16(packhalf, 0); +#elif defined (__ARM_FP16_FORMAT_IEEE) + __fp16 f16 = f; + memcpy(&b16, &f16, sizeof(quint16)); +#else + quint32 u; + memcpy(&u, &f, sizeof(quint32)); + b16 = basetable[(u >> 23) & 0x1ff] + + ((u & 0x007fffff) >> shifttable[(u >> 23) & 0x1ff]); +#endif +} +QT_WARNING_POP + +inline qfloat16::operator float() const Q_DECL_NOTHROW +{ +#if defined(QT_COMPILER_SUPPORTS_F16C) && (defined(__F16C__) || defined(__AVX2__)) + __m128i packhalf = _mm_cvtsi32_si128(b16); + __m128 packsingle = _mm_cvtph_ps(packhalf); + return _mm_cvtss_f32(packsingle); +#elif defined (__ARM_FP16_FORMAT_IEEE) + __fp16 f16; + memcpy(&f16, &b16, sizeof(quint16)); + return f16; +#else + quint32 u = mantissatable[offsettable[b16 >> 10] + (b16 & 0x3ff)] + + exponenttable[b16 >> 10]; + float f; + memcpy(&f, &u, sizeof(quint32)); + return f; +#endif +} + +inline qfloat16::operator double() const Q_DECL_NOTHROW +{ + return static_cast<double>(float(*this)); +} + +inline qfloat16::operator long double() const Q_DECL_NOTHROW +{ + return static_cast<long double>(float(*this)); +} + +inline qfloat16 operator-(qfloat16 a) Q_DECL_NOTHROW +{ + qfloat16 f; + f.b16 = a.b16 ^ quint16(0x8000); + return f; +} + +inline qfloat16 operator+(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return qfloat16(static_cast<float>(a) + static_cast<float>(b)); } +inline qfloat16 operator-(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return qfloat16(static_cast<float>(a) - static_cast<float>(b)); } +inline qfloat16 operator*(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return qfloat16(static_cast<float>(a) * static_cast<float>(b)); } +inline qfloat16 operator/(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return qfloat16(static_cast<float>(a) / static_cast<float>(b)); } + +#define QF16_MAKE_ARITH_OP_FP(FP, OP) \ + inline FP operator OP(qfloat16 lhs, FP rhs) Q_DECL_NOTHROW { return static_cast<FP>(lhs) OP rhs; } \ + inline FP operator OP(FP lhs, qfloat16 rhs) Q_DECL_NOTHROW { return lhs OP static_cast<FP>(rhs); } +#define QF16_MAKE_ARITH_OP_EQ_FP(FP, OP_EQ, OP) \ + inline qfloat16& operator OP_EQ(qfloat16& lhs, FP rhs) Q_DECL_NOTHROW { lhs = qfloat16(static_cast<FP>(lhs) OP rhs); return lhs; } +#define QF16_MAKE_ARITH_OP(FP) \ + QF16_MAKE_ARITH_OP_FP(FP, +) \ + QF16_MAKE_ARITH_OP_FP(FP, -) \ + QF16_MAKE_ARITH_OP_FP(FP, *) \ + QF16_MAKE_ARITH_OP_FP(FP, /) \ + QF16_MAKE_ARITH_OP_EQ_FP(FP, +=, +) \ + QF16_MAKE_ARITH_OP_EQ_FP(FP, -=, -) \ + QF16_MAKE_ARITH_OP_EQ_FP(FP, *=, *) \ + QF16_MAKE_ARITH_OP_EQ_FP(FP, /=, /) +QF16_MAKE_ARITH_OP(long double) +QF16_MAKE_ARITH_OP(double) +QF16_MAKE_ARITH_OP(float) +#undef QF16_MAKE_ARITH_OP +#undef QF16_MAKE_ARITH_OP_FP + +#define QF16_MAKE_ARITH_OP_INT(OP) \ + inline double operator OP(qfloat16 lhs, int rhs) Q_DECL_NOTHROW { return static_cast<double>(lhs) OP rhs; } \ + inline double operator OP(int lhs, qfloat16 rhs) Q_DECL_NOTHROW { return lhs OP static_cast<double>(rhs); } +QF16_MAKE_ARITH_OP_INT(+) +QF16_MAKE_ARITH_OP_INT(-) +QF16_MAKE_ARITH_OP_INT(*) +QF16_MAKE_ARITH_OP_INT(/) +#undef QF16_MAKE_ARITH_OP_INT + +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wfloat-equal") +QT_WARNING_DISABLE_GCC("-Wfloat-equal") + +inline bool operator>(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return static_cast<float>(a) > static_cast<float>(b); } +inline bool operator<(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return static_cast<float>(a) < static_cast<float>(b); } +inline bool operator>=(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return static_cast<float>(a) >= static_cast<float>(b); } +inline bool operator<=(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return static_cast<float>(a) <= static_cast<float>(b); } +inline bool operator==(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return static_cast<float>(a) == static_cast<float>(b); } +inline bool operator!=(qfloat16 a, qfloat16 b) Q_DECL_NOTHROW { return static_cast<float>(a) != static_cast<float>(b); } + +#define QF16_MAKE_BOOL_OP_FP(FP, OP) \ + inline bool operator OP(qfloat16 lhs, FP rhs) Q_DECL_NOTHROW { return static_cast<FP>(lhs) OP rhs; } \ + inline bool operator OP(FP lhs, qfloat16 rhs) Q_DECL_NOTHROW { return lhs OP static_cast<FP>(rhs); } +#define QF16_MAKE_BOOL_OP(FP) \ + QF16_MAKE_BOOL_OP_FP(FP, <) \ + QF16_MAKE_BOOL_OP_FP(FP, >) \ + QF16_MAKE_BOOL_OP_FP(FP, >=) \ + QF16_MAKE_BOOL_OP_FP(FP, <=) \ + QF16_MAKE_BOOL_OP_FP(FP, ==) \ + QF16_MAKE_BOOL_OP_FP(FP, !=) +QF16_MAKE_BOOL_OP(long double) +QF16_MAKE_BOOL_OP(double) +QF16_MAKE_BOOL_OP(float) +#undef QF16_MAKE_BOOL_OP +#undef QF16_MAKE_BOOL_OP_FP + +#define QF16_MAKE_BOOL_OP_INT(OP) \ + inline bool operator OP(qfloat16 a, int b) Q_DECL_NOTHROW { return static_cast<float>(a) OP b; } \ + inline bool operator OP(int a, qfloat16 b) Q_DECL_NOTHROW { return a OP static_cast<float>(b); } +QF16_MAKE_BOOL_OP_INT(>) +QF16_MAKE_BOOL_OP_INT(<) +QF16_MAKE_BOOL_OP_INT(>=) +QF16_MAKE_BOOL_OP_INT(<=) +QF16_MAKE_BOOL_OP_INT(==) +QF16_MAKE_BOOL_OP_INT(!=) +#undef QF16_MAKE_BOOL_OP_INT + +QT_WARNING_POP + +/*! + \internal +*/ +inline Q_REQUIRED_RESULT bool qFuzzyIsNull(qfloat16 f) Q_DECL_NOTHROW +{ + return qAbs(static_cast<float>(f)) <= 0.001f; +} + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(qfloat16) + +#endif // QFLOAT16_H diff --git a/src/corelib/global/qfloat16_p.h b/src/corelib/global/qfloat16_p.h new file mode 100644 index 0000000000..ae52e64435 --- /dev/null +++ b/src/corelib/global/qfloat16_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 by Southwest Research Institute (R) +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFLOAT16_P_H +#define QFLOAT16_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qfloat16.h> +#include <QtCore/qsysinfo.h> + +QT_BEGIN_NAMESPACE + +static inline bool qt_is_inf(qfloat16 d) Q_DECL_NOTHROW +{ + bool is_inf; + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) + is_inf = (ch[0] & 0x7c) == 0x7c; + else + is_inf = (ch[1] & 0x7c) == 0x7c; + return is_inf; +} + +static inline bool qt_is_nan(qfloat16 d) Q_DECL_NOTHROW +{ + bool is_nan; + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) + is_nan = (ch[0] & 0x7c) == 0x7c && (ch[0] & 0x02) != 0; + else + is_nan = (ch[1] & 0x7c) == 0x7c && (ch[1] & 0x02) != 0; + return is_nan; +} + +static inline bool qt_is_finite(qfloat16 d) Q_DECL_NOTHROW +{ + bool is_finite; + uchar *ch = (uchar *)&d; + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) + is_finite = (ch[0] & 0x7c) != 0x7c; + else + is_finite = (ch[1] & 0x7c) != 0x7c; + return is_finite; +} + + +QT_END_NAMESPACE + +#endif // QFLOAT16_P_H diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 6b3cb502e5..1f93d3cbec 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -45,6 +45,8 @@ #include "qthreadstorage.h" #include "qdir.h" #include "qdatetime.h" +#include "qoperatingsystemversion.h" +#include "qoperatingsystemversion_p.h" #include <private/qlocale_tools_p.h> #include <qmutex.h> @@ -956,7 +958,8 @@ Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined in \snippet code/src_corelib_global_qglobal.cpp 53 - \sa qConstOverload(), qNonConstOverload() + \sa qConstOverload(), qNonConstOverload(), {Differences between String-Based + and Functor-Based Connections} */ /*! \fn auto qConstOverload(T memberFunctionPointer) @@ -967,7 +970,8 @@ Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined in \snippet code/src_corelib_global_qglobal.cpp 54 - \sa qOverload, qNonConstOverload + \sa qOverload, qNonConstOverload, {Differences between String-Based + and Functor-Based Connections} */ /*! \fn auto qNonConstOverload(T memberFunctionPointer) @@ -978,7 +982,8 @@ Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined in \snippet code/src_corelib_global_qglobal.cpp 54 - \sa qOverload, qNonConstOverload + \sa qOverload, qNonConstOverload, {Differences between String-Based + and Functor-Based Connections} */ /*! @@ -1064,10 +1069,6 @@ bool qSharedBuild() Q_DECL_NOTHROW on which the application is compiled. \li \l ByteOrder specifies whether the platform is big-endian or little-endian. - \li \l WindowsVersion specifies the version of the Windows operating - system on which the application is run. - \li \l MacintoshVersion specifies the version of the Macintosh - operating system on which the application is run. \endlist Some constants are defined only on certain platforms. You can use @@ -1088,12 +1089,14 @@ bool qSharedBuild() Q_DECL_NOTHROW */ /*! + \deprecated \variable QSysInfo::WindowsVersion \brief the version of the Windows operating system on which the application is run. */ /*! + \deprecated \fn QSysInfo::WindowsVersion QSysInfo::windowsVersion() \since 4.4 @@ -1103,12 +1106,14 @@ bool qSharedBuild() Q_DECL_NOTHROW */ /*! + \deprecated \variable QSysInfo::MacintoshVersion \brief the version of the Macintosh operating system on which the application is run. */ /*! + \deprecated \fn QSysInfo::MacVersion QSysInfo::macVersion() Returns the version of Darwin (\macos or iOS) on which the @@ -1126,6 +1131,7 @@ bool qSharedBuild() Q_DECL_NOTHROW */ /*! + \deprecated \enum QSysInfo::WinVersion This enum provides symbolic names for the various versions of the @@ -1182,6 +1188,7 @@ bool qSharedBuild() Q_DECL_NOTHROW */ /*! + \deprecated \enum QSysInfo::MacVersion This enum provides symbolic names for the various versions of the @@ -1335,13 +1342,6 @@ bool qSharedBuild() Q_DECL_NOTHROW */ /*! - \macro Q_OS_WINPHONE - \relates <QtGlobal> - - Defined on Windows Phone 8. -*/ - -/*! \macro Q_OS_CYGWIN \relates <QtGlobal> @@ -1941,6 +1941,19 @@ bool qSharedBuild() Q_DECL_NOTHROW disable functions deprecated in Qt 5.1 and earlier. In any release, set QT_DISABLE_DEPRECATED_BEFORE=0x000000 to enable any functions, including the ones deprecated in Qt 5.0 + + \sa QT_DEPRECATED_WARNINGS + */ + + +/*! + \macro QT_DEPRECATED_WARNINGS + \relates <QtGlobal> + + If this macro is defined, the compiler will generate warnings if API declared as + deprecated by Qt is used. + + \sa QT_DISABLE_DEPRECATED_BEFORE */ #if defined(QT_BUILD_QMAKE) @@ -1956,28 +1969,34 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "qnamespace.h" QT_END_INCLUDE_NAMESPACE +#if QT_DEPRECATED_SINCE(5, 9) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QSysInfo::MacVersion QSysInfo::macVersion() { - const QAppleOperatingSystemVersion version = qt_apple_os_version(); // qtcore_mac_objc.mm + const auto version = QOperatingSystemVersion::current(); #if defined(Q_OS_OSX) - return QSysInfo::MacVersion(Q_MV_OSX(version.major, version.minor)); + return QSysInfo::MacVersion(Q_MV_OSX(version.majorVersion(), version.minorVersion())); #elif defined(Q_OS_IOS) - return QSysInfo::MacVersion(Q_MV_IOS(version.major, version.minor)); + return QSysInfo::MacVersion(Q_MV_IOS(version.majorVersion(), version.minorVersion())); #elif defined(Q_OS_TVOS) - return QSysInfo::MacVersion(Q_MV_TVOS(version.major, version.minor)); + return QSysInfo::MacVersion(Q_MV_TVOS(version.majorVersion(), version.minorVersion())); #elif defined(Q_OS_WATCHOS) - return QSysInfo::MacVersion(Q_MV_WATCHOS(version.major, version.minor)); + return QSysInfo::MacVersion(Q_MV_WATCHOS(version.majorVersion(), version.minorVersion())); #else return QSysInfo::MV_Unknown; #endif } const QSysInfo::MacVersion QSysInfo::MacintoshVersion = QSysInfo::macVersion(); +QT_WARNING_POP +#endif -#ifdef Q_OS_OSX -static const char *osxVer_helper(QAppleOperatingSystemVersion version = qt_apple_os_version()) +#ifdef Q_OS_DARWIN +static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current()) { - if (version.major == 10) { - switch (version.minor) { +#ifdef Q_OS_MACOS + if (version.majorVersion() == 10) { + switch (version.minorVersion()) { case 9: return "Mavericks"; case 10: @@ -1989,6 +2008,9 @@ static const char *osxVer_helper(QAppleOperatingSystemVersion version = qt_apple } } // unknown, future version +#else + Q_UNUSED(version); +#endif return 0; } #endif @@ -2029,140 +2051,33 @@ QWindowsSockInit::~QWindowsSockInit() Q_GLOBAL_STATIC(QWindowsSockInit, winsockInit) # endif // QT_BOOTSTRAPPED -#ifdef Q_OS_WINRT -static inline HMODULE moduleHandleForFunction(LPCVOID address) -{ - // This is a widely used, decades-old technique for retrieving the handle - // of a module and is effectively equivalent to GetModuleHandleEx - // (which is unavailable on WinRT) - MEMORY_BASIC_INFORMATION mbi = { 0, 0, 0, 0, 0, 0, 0 }; - if (VirtualQuery(address, &mbi, sizeof(mbi)) == 0) - return 0; - return reinterpret_cast<HMODULE>(mbi.AllocationBase); -} -#endif - -static inline OSVERSIONINFOEX determineWinOsVersion() -{ - OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0}; - -#define GetProcAddressA GetProcAddress - - // GetModuleHandle is not supported in WinRT and linking to it at load time - // will not pass the Windows App Certification Kit... but it exists and is functional, - // so use some unusual but widely used techniques to get a pointer to it -#ifdef Q_OS_WINRT - // 1. Get HMODULE of kernel32.dll, using the address of some function exported by that DLL - HMODULE kernelModule = moduleHandleForFunction(reinterpret_cast<LPCVOID>(VirtualQuery)); - if (Q_UNLIKELY(!kernelModule)) - return result; - - // 2. Get pointer to GetModuleHandle so we can then load other arbitrary modules (DLLs) - typedef HMODULE(WINAPI *GetModuleHandleFunction)(LPCWSTR); - GetModuleHandleFunction pGetModuleHandle = reinterpret_cast<GetModuleHandleFunction>( - GetProcAddressA(kernelModule, "GetModuleHandleW")); - if (Q_UNLIKELY(!pGetModuleHandle)) - return result; -#else -#define pGetModuleHandle GetModuleHandleW -#endif - -#ifndef Q_OS_WINCE - HMODULE ntdll = pGetModuleHandle(L"ntdll.dll"); - if (Q_UNLIKELY(!ntdll)) - return result; - - // NTSTATUS is not defined on WinRT - typedef LONG NTSTATUS; - typedef NTSTATUS (NTAPI *RtlGetVersionFunction)(LPOSVERSIONINFO); - - // RtlGetVersion is documented public API but we must load it dynamically - // because linking to it at load time will not pass the Windows App Certification Kit - // https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910.aspx - RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>( - GetProcAddressA(ntdll, "RtlGetVersion")); - if (Q_UNLIKELY(!pRtlGetVersion)) - return result; - - // GetVersionEx() has been deprecated in Windows 8.1 and will return - // only Windows 8 from that version on, so use the kernel API function. - pRtlGetVersion((LPOSVERSIONINFO) &result); // always returns STATUS_SUCCESS -#else // !Q_OS_WINCE - GetVersionEx(&result); -#endif - return result; -} - -static OSVERSIONINFOEX winOsVersion() -{ - OSVERSIONINFOEX realResult = determineWinOsVersion(); -#ifdef QT_DEBUG - { - if (Q_UNLIKELY(qEnvironmentVariableIsSet("QT_WINVER_OVERRIDE"))) { - OSVERSIONINFOEX result = realResult; - result.dwMajorVersion = 0; - result.dwMinorVersion = 0; - - // Erase any build number and service pack information - result.dwBuildNumber = 0; - result.szCSDVersion[0] = L'\0'; - result.wServicePackMajor = 0; - result.wServicePackMinor = 0; - - const QByteArray winVerOverride = qgetenv("QT_WINVER_OVERRIDE"); - if (winVerOverride == "WINDOWS7" || winVerOverride == "2008_R2") { - result.dwMajorVersion = 6; - result.dwMinorVersion = 1; - } else if (winVerOverride == "WINDOWS8" || winVerOverride == "2012") { - result.dwMajorVersion = 6; - result.dwMinorVersion = 2; - } else if (winVerOverride == "WINDOWS8_1" || winVerOverride == "2012_R2") { - result.dwMajorVersion = 6; - result.dwMinorVersion = 3; - } else if (winVerOverride == "WINDOWS10" || winVerOverride == "2016") { - result.dwMajorVersion = 10; - } else { - return realResult; - } - - if (winVerOverride == "2008_R2" - || winVerOverride == "2012" - || winVerOverride == "2012_R2" - || winVerOverride == "2016") { - // If the current host OS is a domain controller and the override OS - // is also a server type OS, preserve that information - if (result.wProductType == VER_NT_WORKSTATION) - result.wProductType = VER_NT_SERVER; - } else { - // Any other OS must be a workstation OS type - result.wProductType = VER_NT_WORKSTATION; - } - } - } -#endif - return realResult; -} - +#if QT_DEPRECATED_SINCE(5, 9) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QSysInfo::WinVersion QSysInfo::windowsVersion() { - const OSVERSIONINFOEX osver = winOsVersion(); - if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1) + const auto version = QOperatingSystemVersion::current(); + if (version.majorVersion() == 6 && version.minorVersion() == 1) return QSysInfo::WV_WINDOWS7; - if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2) + if (version.majorVersion() == 6 && version.minorVersion() == 2) return QSysInfo::WV_WINDOWS8; - if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3) + if (version.majorVersion() == 6 && version.minorVersion() == 3) return QSysInfo::WV_WINDOWS8_1; - if (osver.dwMajorVersion == 10 && osver.dwMinorVersion == 0) + if (version.majorVersion() == 10 && version.minorVersion() == 0) return QSysInfo::WV_WINDOWS10; return QSysInfo::WV_NT_based; } +const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion(); +QT_WARNING_POP +#endif static QString winSp_helper() { - const qint16 major = winOsVersion().wServicePackMajor; + const auto osv = qWindowsVersionInfo(); + const qint16 major = osv.wServicePackMajor; if (major) { QString sp = QStringLiteral(" SP ") + QString::number(major); - const qint16 minor = winOsVersion().wServicePackMinor; + const qint16 minor = osv.wServicePackMinor; if (minor) sp += QLatin1Char('.') + QString::number(minor); @@ -2171,9 +2086,10 @@ static QString winSp_helper() return QString(); } -static const char *winVer_helper() +static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSystemVersion::current()) { - const OSVERSIONINFOEX osver = winOsVersion(); + Q_UNUSED(version); + const OSVERSIONINFOEX osver = qWindowsVersionInfo(); const bool workstation = osver.wProductType == VER_NT_WORKSTATION; #define Q_WINVER(major, minor) (major << 8 | minor) @@ -2192,8 +2108,6 @@ static const char *winVer_helper() return 0; } -const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion(); - #endif #if defined(Q_OS_UNIX) # if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD) @@ -2374,6 +2288,68 @@ static bool findUnixOsVersion(QUnixOSVersion &v) # endif // USE_ETC_OS_RELEASE #endif // Q_OS_UNIX +#ifdef Q_OS_ANDROID +static const char *osVer_helper(QOperatingSystemVersion) +{ +/* Data: + + + +Cupcake +Donut +Eclair +Eclair +Eclair +Froyo +Gingerbread +Gingerbread +Honeycomb +Honeycomb +Honeycomb +Ice Cream Sandwich +Ice Cream Sandwich +Jelly Bean +Jelly Bean +Jelly Bean +KitKat +KitKat +Lollipop +Lollipop +Marshmallow +Nougat +Nougat + */ + static const char versions_string[] = + "\0" + "Cupcake\0" + "Donut\0" + "Eclair\0" + "Froyo\0" + "Gingerbread\0" + "Honeycomb\0" + "Ice Cream Sandwich\0" + "Jelly Bean\0" + "KitKat\0" + "Lollipop\0" + "Marshmallow\0" + "Nougat\0" + "\0"; + + static const int versions_indices[] = { + 0, 0, 0, 1, 9, 15, 15, 15, + 22, 28, 28, 40, 40, 40, 50, 50, + 69, 69, 69, 80, 80, 87, 87, 96, + 108, 108, -1 + }; + + static const int versions_count = (sizeof versions_indices) / (sizeof versions_indices[0]); + + // https://source.android.com/source/build-numbers.html + // https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels + const int sdk_int = QJNIObjectPrivate::getStaticField<jint>("android/os/Build$VERSION", "SDK_INT"); + return &versions_string[versions_indices[qBound(0, sdk_int, versions_count - 1)]]; +} +#endif /*! \since 5.4 @@ -2622,9 +2598,9 @@ QString QSysInfo::kernelType() QString QSysInfo::kernelVersion() { #ifdef Q_OS_WIN - const OSVERSIONINFOEX osver = winOsVersion(); - return QString::number(int(osver.dwMajorVersion)) + QLatin1Char('.') + QString::number(int(osver.dwMinorVersion)) - + QLatin1Char('.') + QString::number(int(osver.dwBuildNumber)); + const auto osver = QOperatingSystemVersion::current(); + return QString::number(osver.majorVersion()) + QLatin1Char('.') + QString::number(osver.minorVersion()) + + QLatin1Char('.') + QString::number(osver.microVersion()); #else struct utsname u; if (uname(&u) == 0) @@ -2662,8 +2638,8 @@ QString QSysInfo::kernelVersion() \b{FreeBSD note}: this function returns "debian" for Debian/kFreeBSD and "unknown" otherwise. - \b{Windows note}: this function returns "winphone" for builds for Windows - Phone, "winrt" for WinRT builds, and "windows" for normal desktop builds. + \b{Windows note}: this function "winrt" for WinRT builds, and "windows" + for normal desktop builds. For other Unix-type systems, this function usually returns "unknown". @@ -2672,9 +2648,7 @@ QString QSysInfo::kernelVersion() QString QSysInfo::productType() { // similar, but not identical to QFileSelectorPrivate::platformSelectors -#if defined(Q_OS_WINPHONE) - return QStringLiteral("winphone"); -#elif defined(Q_OS_WINRT) +#if defined(Q_OS_WINRT) return QStringLiteral("winrt"); #elif defined(Q_OS_WIN) return QStringLiteral("windows"); @@ -2692,8 +2666,8 @@ QString QSysInfo::productType() #elif defined(Q_OS_WATCHOS) return QStringLiteral("watchos"); #elif defined(Q_OS_MACOS) - const QAppleOperatingSystemVersion version = qt_apple_os_version(); - if (version.major == 10 && version.minor < 12) + const auto version = QOperatingSystemVersion::current(); + if (version.majorVersion() == 10 && version.minorVersion() < 12) return QStringLiteral("osx"); return QStringLiteral("macos"); #elif defined(Q_OS_DARWIN) @@ -2715,8 +2689,23 @@ QString QSysInfo::productType() version could not be determined, this function returns "unknown". It will return the Android, iOS, \macos, Windows full-product - versions on those systems. In particular, on OS X, iOS and Windows, the - returned string is similar to the macVersion() or windowsVersion() enums. + versions on those systems. + + Typical returned values are (note: list not exhaustive): + \list + \li "2016.09" (Amazon Linux AMI 2016.09) + \li "7.1" (Android Nougat) + \li "25" (Fedora 25) + \li "10.1" (iOS 10.1) + \li "10.12" (macOS Sierra) + \li "10.0" (tvOS 10) + \li "16.10" (Ubuntu 16.10) + \li "3.1" (watchOS 3.1) + \li "7 SP 1" (Windows 7 Service Pack 1) + \li "8.1" (Windows 8.1) + \li "10" (Windows 10) + \li "Server 2016" (Windows Server 2016) + \endlist On Linux systems, it will try to determine the distribution version and will return that. This is also done on Debian/kFreeBSD, so this function will @@ -2733,20 +2722,17 @@ QString QSysInfo::productType() */ QString QSysInfo::productVersion() { -#if defined(Q_OS_MAC) - const QAppleOperatingSystemVersion version = qt_apple_os_version(); - return QString::number(version.major) + QLatin1Char('.') + QString::number(version.minor); +#if defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN) + const auto version = QOperatingSystemVersion::current(); + return QString::number(version.majorVersion()) + QLatin1Char('.') + QString::number(version.minorVersion()); #elif defined(Q_OS_WIN) - const char *version = winVer_helper(); + const char *version = osVer_helper(); if (version) { const QLatin1Char spaceChar(' '); return QString::fromLatin1(version).remove(spaceChar).toLower() + winSp_helper().remove(spaceChar).toLower(); } // fall through -// Android should not fall through to the Unix code -#elif defined(Q_OS_ANDROID) - return QJNIObjectPrivate::getStaticObjectField("android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString(); #elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX QUnixOSVersion unixOsVersion; findUnixOsVersion(unixOsVersion); @@ -2774,44 +2760,21 @@ QString QSysInfo::productVersion() */ QString QSysInfo::prettyProductName() { -#if defined(Q_OS_IOS) - return QLatin1String("iOS ") + productVersion(); -#elif defined(Q_OS_TVOS) - return QLatin1String("tvOS ") + productVersion(); -#elif defined(Q_OS_WATCHOS) - return QLatin1String("watchOS ") + productVersion(); -#elif defined(Q_OS_MACOS) - const QAppleOperatingSystemVersion version = qt_apple_os_version(); - const char *name = osxVer_helper(version); - if (name) { - return (version.major == 10 && version.minor < 12 - ? QLatin1String("OS X ") - : QLatin1String("macOS ")) - + QLatin1String(name) - + QLatin1String(" (") + QString::number(version.major) - + QLatin1Char('.') + QString::number(version.minor) - + QLatin1Char(')'); - } else { - return QLatin1String("macOS ") - + QString::number(version.major) + QLatin1Char('.') - + QString::number(version.minor); - } -#elif defined(Q_OS_WINPHONE) - return QLatin1String("Windows Phone ") + QLatin1String(winVer_helper()); -#elif defined(Q_OS_WIN) - const char *name = winVer_helper(); - const OSVERSIONINFOEX osver = winOsVersion(); +#if defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN) + const auto version = QOperatingSystemVersion::current(); + const char *name = osVer_helper(version); if (name) - return QLatin1String("Windows ") + QLatin1String(name) + winSp_helper() - + QLatin1String(" (") + QString::number(osver.dwMajorVersion) - + QLatin1Char('.') + QString::number(osver.dwMinorVersion) + return version.name() + QLatin1Char(' ') + QLatin1String(name) +# if defined(Q_OS_WIN) + + winSp_helper() +# endif + + QLatin1String(" (") + QString::number(version.majorVersion()) + + QLatin1Char('.') + QString::number(version.minorVersion()) + QLatin1Char(')'); - else - return QLatin1String("Windows ") - + QString::number(osver.dwMajorVersion) + QLatin1Char('.') - + QString::number(osver.dwMinorVersion); -#elif defined(Q_OS_ANDROID) - return QLatin1String("Android ") + productVersion(); + else + return version.name() + QLatin1Char(' ') + + QString::number(version.majorVersion()) + QLatin1Char('.') + + QString::number(version.minorVersion()); #elif defined(Q_OS_HAIKU) return QLatin1String("Haiku ") + productVersion(); #elif defined(Q_OS_UNIX) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index b4245ac8f6..9ac29acd16 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -44,6 +44,7 @@ #ifdef __cplusplus # include <type_traits> # include <cstddef> +# include <utility> #endif #include <stddef.h> @@ -915,19 +916,57 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic # endif #endif +namespace QtPrivate { +template <typename T> struct QAddConst { typedef const T Type; }; +} + +// this adds const to non-const objects (like std::as_const) +template <typename T> +Q_DECL_CONSTEXPR typename QtPrivate::QAddConst<T>::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; } +// prevent rvalue arguments: +template <typename T> +void qAsConst(const T &&) Q_DECL_EQ_DELETE; + #ifndef QT_NO_FOREACH +namespace QtPrivate { + template <typename T> class QForeachContainer { - QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE; + Q_DISABLE_COPY(QForeachContainer) public: - QForeachContainer(const T &t) : c(t), i(c.begin()), e(c.end()) {} - QForeachContainer(T &&t) : c(std::move(t)), i(c.begin()), e(c.end()) {} - const T c; + QForeachContainer(const T &t) : c(t), i(qAsConst(c).begin()), e(qAsConst(c).end()) {} + QForeachContainer(T &&t) : c(std::move(t)), i(qAsConst(c).begin()), e(qAsConst(c).end()) {} + + QForeachContainer(QForeachContainer &&other) + : c(std::move(other.c)), + i(qAsConst(c).begin()), + e(qAsConst(c).end()), + control(std::move(other.control)) + { + } + + QForeachContainer &operator=(QForeachContainer &&other) + { + c = std::move(other.c); + i = qAsConst(c).begin(); + e = qAsConst(c).end(); + control = std::move(other.control); + return *this; + } + + T c; typename T::const_iterator i, e; int control = 1; }; +template<typename T> +QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t) +{ + return QForeachContainer<typename std::decay<T>::type>(std::forward<T>(t)); +} + +} // Explanation of the control word: // - it's initialized to 1 // - that means both the inner and outer loops start @@ -938,7 +977,7 @@ public: // - if there was a break inside the inner loop, it will exit with control still // set to 1; in that case, the outer loop will invert it to 0 and will exit too #define Q_FOREACH(variable, container) \ -for (QForeachContainer<typename std::remove_reference<decltype(container)>::type> _container_((container)); \ +for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ _container_.control && _container_.i != _container_.e; \ ++_container_.i, _container_.control ^= 1) \ for (variable = *_container_.i; _container_.control; _container_.control = 0) @@ -966,8 +1005,8 @@ template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelpe friend class Class##Private; #define Q_DECLARE_PRIVATE_D(Dptr, Class) \ - inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(Dptr); } \ - inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(Dptr); } \ + inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr)); } \ + inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr)); } \ friend class Class##Private; #define Q_DECLARE_PUBLIC(Class) \ @@ -1105,17 +1144,8 @@ template <typename T> struct QEnableIf<true, T> { typedef T Type; }; template <bool B, typename T, typename F> struct QConditional { typedef T Type; }; template <typename T, typename F> struct QConditional<false, T, F> { typedef F Type; }; - -template <typename T> struct QAddConst { typedef const T Type; }; } -// this adds const to non-const objects (like std::as_const) -template <typename T> -Q_DECL_CONSTEXPR typename QtPrivate::QAddConst<T>::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; } -// prevent rvalue arguments: -template <typename T> -void qAsConst(const T &&) Q_DECL_EQ_DELETE; - QT_END_NAMESPACE // We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4. diff --git a/src/corelib/global/qglobal_p.h b/src/corelib/global/qglobal_p.h index b8f9e5fbf7..b1d2836783 100644 --- a/src/corelib/global/qglobal_p.h +++ b/src/corelib/global/qglobal_p.h @@ -1,31 +1,37 @@ /**************************************************************************** ** ** Copyright (C) 2015 Intel Corporation. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 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. +** 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. ** -** 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. +** 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$ ** diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp index 7b9a3db30d..bbddb1cbf1 100644 --- a/src/corelib/global/qhooks.cpp +++ b/src/corelib/global/qhooks.cpp @@ -67,7 +67,7 @@ quintptr Q_CORE_EXPORT qtHookData[] = { // The required sizes and offsets are tested in tests/auto/other/toolsupport. // When this fails and the change was intentional, adjust the test and // adjust this value here. - 15 + 16 }; Q_STATIC_ASSERT(QHooks::LastHookIndex == sizeof(qtHookData) / sizeof(qtHookData[0])); diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 03ee0730db..b4ba0b5b2e 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -663,6 +663,8 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) + QLatin1String("Arguments"); return settings->value(key).toStringList(); } +#else + Q_UNUSED(platformName); #endif // !QT_BUILD_QMAKE && !QT_NO_SETTINGS return QStringList(); } diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 6b90a47388..e525869733 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -197,7 +197,7 @@ static bool willLogToConsole() # elif defined(Q_OS_UNIX) // if /dev/tty exists, we can only open it if we have a controlling TTY int devtty = qt_safe_open("/dev/tty", O_RDONLY); - if (devtty == -1 && (errno == ENOENT || errno == EPERM)) { + if (devtty == -1 && (errno == ENOENT || errno == EPERM || errno == ENXIO)) { // no /dev/tty, fall back to isatty on stderr return isatty(STDERR_FILENO); } else if (devtty != -1) { @@ -1445,12 +1445,14 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con now.start(); uint ms = now.msecsSinceReference(); message.append(QString::asprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000))); +#if QT_CONFIG(datestring) } else if (timeFormat.isEmpty()) { message.append(QDateTime::currentDateTime().toString(Qt::ISODate)); } else { message.append(QDateTime::currentDateTime().toString(timeFormat)); +#endif // QT_CONFIG(datestring) } -#endif +#endif // !QT_BOOTSTRAPPED } else if (token == ifCategoryTokenC) { if (!context.category || (strcmp(context.category, "default") == 0)) skip = true; diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index a30344995e..da44c01594 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -472,6 +472,8 @@ public: WA_AlwaysStackOnTop = 128, + WA_TabletTracking = 129, + // Add new attributes before this line WA_AttributeCount }; @@ -505,6 +507,7 @@ public: AA_SynthesizeMouseForUnhandledTabletEvents = 24, AA_CompressHighFrequencyEvents = 25, AA_DontCheckOpenGLContextThreadAffinity = 26, + AA_DisableShaderDiskCache = 27, // Add new attributes before this line AA_AttributeCount @@ -1655,6 +1658,11 @@ public: }; Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag) + enum ChecksumType { + ChecksumIso3309, + ChecksumItuV41 + }; + #ifndef Q_QDOC // NOTE: Generally, do not add QT_Q_ENUM if a corresponding Q_Q_FLAG exists. QT_Q_ENUM(ScrollBarPolicy) @@ -1739,6 +1747,7 @@ public: QT_Q_ENUM(ScrollPhase) QT_Q_ENUM(MouseEventSource) QT_Q_FLAG(MouseEventFlag) + QT_Q_ENUM(ChecksumType) QT_Q_ENUM(TabFocusBehavior) #endif // Q_DOC diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 59fa0b519c..404bbfe65a 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -254,6 +254,15 @@ \l{QOpenGLContext::makeCurrent}{makeCurrent()}. This value has been added in Qt 5.8. + \value AA_DisableShaderDiskCache Disables caching of shader program binaries + on disk. By default Qt Quick, QPainter's OpenGL backend, and any + application using QOpenGLShaderProgram with one of its + \e addCacheableShaderFromSource overloads will employ a disk-based + \l{Caching Program Binaries}{program binary cache} in either the shared + or per-process cache storage location, on systems that support + \e glProgramBinary(). In the unlikely event of this being problematic, + set this attribute to disable all disk-based caching of shaders. + The following values are obsolete: \value AA_ImmediateWidgetCreation This attribute is no longer fully @@ -1130,6 +1139,9 @@ \value WA_StyleSheet Indicates that the widget is styled using a \l{Qt Style Sheets}{style sheet}. + \value WA_TabletTracking Indicates that the widget has tablet + tracking enabled. See QWidget::tabletTracking. + \value WA_TranslucentBackground Indicates that the widget should have a translucent background, i.e., any non-opaque regions of the widgets will be translucent because the widget will have an alpha channel. Setting this @@ -3146,3 +3158,14 @@ \omitvalue MouseEventFlagMask */ + +/*! + \enum Qt::ChecksumType + \since 5.9 + + This enum describes the possible standards used by qChecksum(). + + \value ChecksumIso3309 Checksum calculation based on ISO 3309. + + \value ChecksumItuV41 Checksum calculation based on ITU-V.41. +*/ diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 06658b422d..2291675501 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -167,7 +167,7 @@ static inline bool qt_is_finite(float f) // Unsigned overflow math // namespace { -template <typename T> inline typename QtPrivate::QEnableIf<std::is_unsigned<T>::value, bool>::Type +template <typename T> inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type add_overflow(T v1, T v2, T *r) { // unsigned additions are well-defined @@ -175,7 +175,7 @@ add_overflow(T v1, T v2, T *r) return v1 > T(v1 + v2); } -template <typename T> inline typename QtPrivate::QEnableIf<std::is_unsigned<T>::value, bool>::Type +template <typename T> inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type mul_overflow(T v1, T v2, T *r) { // use the next biggest type diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp new file mode 100644 index 0000000000..bed08f0000 --- /dev/null +++ b/src/corelib/global/qoperatingsystemversion.cpp @@ -0,0 +1,491 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoperatingsystemversion.h" +#if !defined(Q_OS_DARWIN) && !defined(Q_OS_WIN) +#include "qoperatingsystemversion_p.h" +#endif + +#include <qversionnumber.h> + +#if defined(Q_OS_ANDROID) +#include <private/qjni_p.h> +#endif + +QT_BEGIN_NAMESPACE + +/*! + \class QOperatingSystemVersion + \inmodule QtCore + \since 5.9 + \brief The QOperatingSystemVersion class provides information about the + operating system version. + + Unlike other version functions in QSysInfo, QOperatingSystemVersion provides + access to the full version number that \a developers typically use to vary + behavior or determine whether to enable APIs or features based on the + operating system version (as opposed to the kernel version number or + marketing version). + + This class is also a complete replacement for QSysInfo::macVersion and + QSysInfo::windowsVersion, additionally providing access to the third (micro) + version number component. + + Presently, Android, Apple Platforms (iOS, macOS, tvOS, and watchOS), + and Windows are supported. + + The \a majorVersion(), \a minorVersion(), and \a microVersion() functions + return the parts of the operating system version number based on: + + \table + \header + \li Platforms + \li Value + \row + \li Android + \li result of parsing + \l{https://developer.android.com/reference/android/os/Build.VERSION.html#RELEASE}{android.os.Build.VERSION.RELEASE} + using QVersionNumber, with a fallback to + \l{https://developer.android.com/reference/android/os/Build.VERSION.html#SDK_INT}{android.os.Build.VERSION.SDK_INT} + to determine the major and minor version component if the former + fails + \row + \li Apple Platforms + \li majorVersion, minorVersion, and patchVersion from + \l{https://developer.apple.com/reference/foundation/nsprocessinfo/1410906-operatingsystemversion?language=objc}{NSProcessInfo.operatingSystemVersion} + \row + \li Windows + \li dwMajorVersion, dwMinorVersion, and dwBuildNumber from + \l{https://msdn.microsoft.com/en-us/library/mt723418.aspx}{RtlGetVersion} - + note that this function ALWAYS return the version number of the + underlying operating system, as opposed to the shim underneath + GetVersionEx that hides the real version number if the + application is not manifested for that version of the OS + \endtable + + Because QOperatingSystemVersion stores both a version number and an OS type, the OS type + can be taken into account when performing comparisons. For example, on a macOS system running + macOS Sierra (v10.12), the following expression will return \c false even though the + major version number component of the object on the left hand side of the expression (10) is + greater than that of the object on the right (9): + + \code + QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9) + \endcode + + This allows expressions for multiple operating systems to be joined with a logical OR operator + and still work as expected. For example: + + \code + auto current = QOperatingSystemVersion::current(); + if (current >= QOperatingSystemVersion::OSXYosemite || + current >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) { + // returns true on macOS >= 10.10 and iOS >= 8.0, but false on macOS < 10.10 and iOS < 8.0 + } + \endcode + + A more naive comparison algorithm might incorrectly return true on all versions of macOS, + including Mac OS 9. This behavior is achieved by overloading the comparison operators to return + \c false whenever the OS types of the QOperatingSystemVersion instances being compared do not + match. Be aware that due to this it can be the case \c x >= y and \c x < y are BOTH \c false + for the same instances of \c x and \c y. +*/ + +/*! + \enum QOperatingSystemVersion::OSType + + This enum provides symbolic names for the various operating + system families supported by QOperatingSystemVersion. + + \value Android The Google Android operating system. + \value IOS The Apple iOS operating system. + \value MacOS The Apple macOS operating system. + \value TvOS The Apple tvOS operating system. + \value WatchOS The Apple watchOS operating system. + \value Windows The Microsoft Windows operating system. + + \value Unknown An unknown or unsupported operating system. +*/ + +/*! + \fn QOperatingSystemVersion::QOperatingSystemVersion(OSType osType, int vmajor, int vminor = -1, int vmicro = -1) + + Constructs a QOperatingSystemVersion consisting of the OS type \a osType, and + major, minor, and micro version numbers \a vmajor, \a vminor and \a vmicro, respectively. +*/ + +/*! + \fn QOperatingSystemVersion QOperatingSystemVersion::current() + + Returns a QOperatingSystemVersion indicating the current OS and its version number. +*/ +#if !defined(Q_OS_DARWIN) && !defined(Q_OS_WIN) +QOperatingSystemVersion QOperatingSystemVersion::current() +{ + QOperatingSystemVersion version; + version.m_os = currentType(); +#if defined(Q_OS_ANDROID) +#ifndef QT_BOOTSTRAPPED + const QVersionNumber v = QVersionNumber::fromString(QJNIObjectPrivate::getStaticObjectField( + "android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString()); + if (!v.isNull()) { + version.m_major = v.majorVersion(); + version.m_minor = v.minorVersion(); + version.m_micro = v.microVersion(); + return version; + } +#endif + + version.m_major = -1; + version.m_minor = -1; + + static const int versions[][2] = { + { 1, 0 }, // API level 1 + { 1, 1 }, // API level 2 + { 1, 5 }, // API level 3 + { 1, 6 }, // API level 4 + { 2, 0 }, // API level 5 + { 2, 0 }, // API level 6 + { 2, 1 }, // API level 7 + { 2, 2 }, // API level 8 + { 2, 3 }, // API level 9 + { 2, 3 }, // API level 10 + { 3, 0 }, // API level 11 + { 3, 1 }, // API level 12 + { 3, 2 }, // API level 13 + { 4, 0 }, // API level 14 + { 4, 0 }, // API level 15 + { 4, 1 }, // API level 16 + { 4, 2 }, // API level 17 + { 4, 3 }, // API level 18 + { 4, 4 }, // API level 19 + { 4, 4 }, // API level 20 + { 5, 0 }, // API level 21 + { 5, 1 }, // API level 22 + { 6, 0 }, // API level 23 + { 7, 0 }, // API level 24 + { 7, 1 }, // API level 25 + }; + + // This will give us at least the first 2 version components + const size_t versionIdx = size_t(QJNIObjectPrivate::getStaticField<jint>( + "android/os/Build$VERSION", "SDK_INT")) - 1; + if (versionIdx < sizeof(versions) / sizeof(versions[0])) { + version.m_major = versions[versionIdx][0]; + version.m_minor = versions[versionIdx][1]; + } + + // API level 6 was exactly version 2.0.1 + version.m_micro = versionIdx == 5 ? 1 : -1; +#else + version.m_major = -1; + version.m_minor = -1; + version.m_micro = -1; +#endif + return version; +} +#endif + +static inline int compareVersionComponents(int lhs, int rhs) +{ + return lhs >= 0 && rhs >= 0 ? lhs - rhs : 0; +} + +int QOperatingSystemVersion::compare(const QOperatingSystemVersion &v1, + const QOperatingSystemVersion &v2) +{ + if (v1.m_major == v2.m_major) { + if (v1.m_minor == v2.m_minor) { + return compareVersionComponents(v1.m_micro, v2.m_micro); + } + return compareVersionComponents(v1.m_minor, v2.m_minor); + } + return compareVersionComponents(v1.m_major, v2.m_major); +} + +/*! + \fn int QOperatingSystemVersion::majorVersion() const + + Returns the major version number, that is, the first segment of the + operating system's version number. + + See the main class documentation for what the major version number is on a given + operating system. + + -1 indicates an unknown or absent version number component. + + \sa minorVersion(), microVersion() +*/ + +/*! + \fn int QOperatingSystemVersion::minorVersion() const + + Returns the minor version number, that is, the second segment of the + operating system's version number. + + See the main class documentation for what the minor version number is on a given + operating system. + + -1 indicates an unknown or absent version number component. + + \sa majorVersion(), microVersion() +*/ + +/*! + \fn int QOperatingSystemVersion::microVersion() const + + Returns the micro version number, that is, the third segment of the + operating system's version number. + + See the main class documentation for what the micro version number is on a given + operating system. + + -1 indicates an unknown or absent version number component. + + \sa majorVersion(), minorVersion() +*/ + +/*! + \fn int QOperatingSystemVersion::segmentCount() const + + Returns the number of integers stored in the version number. +*/ + +/*! + \fn QOperatingSystemVersion::OSType QOperatingSystemVersion::type() const + + Returns the OS type identified by the QOperatingSystemVersion. + + \sa name() +*/ + +/*! + \fn QString QOperatingSystemVersion::name() const + + Returns a string representation of the OS type identified by the QOperatingSystemVersion. + + \sa type() +*/ +QString QOperatingSystemVersion::name() const +{ + switch (type()) { + case QOperatingSystemVersion::Windows: + return QStringLiteral("Windows"); + case QOperatingSystemVersion::MacOS: { + if (majorVersion() < 10) + return QStringLiteral("Mac OS"); + if (majorVersion() == 10 && minorVersion() < 8) + return QStringLiteral("Mac OS X"); + if (majorVersion() == 10 && minorVersion() < 12) + return QStringLiteral("OS X"); + return QStringLiteral("macOS"); + } + case QOperatingSystemVersion::IOS: { + if (majorVersion() < 4) + return QStringLiteral("iPhone OS"); + return QStringLiteral("iOS"); + } + case QOperatingSystemVersion::TvOS: + return QStringLiteral("tvOS"); + case QOperatingSystemVersion::WatchOS: + return QStringLiteral("watchOS"); + case QOperatingSystemVersion::Android: + return QStringLiteral("Android"); + case QOperatingSystemVersion::Unknown: + default: + return QString(); + } +} + +/*! + \fn bool QOperatingSystemVersion::isAnyOfType(std::initializer_list<OSType> types) const + + Returns whether the OS type identified by the QOperatingSystemVersion + matches any of the OS types in \a types. +*/ +bool QOperatingSystemVersion::isAnyOfType(std::initializer_list<OSType> types) const +{ + for (const auto &t : qAsConst(types)) { + if (type() == t) + return true; + } + return false; +} + +/*! + \variable QOperatingSystemVersion::Windows7 + \brief a version corresponding to Windows 7 (version 6.1). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::Windows7 = + QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 1); + +/*! + \variable QOperatingSystemVersion::Windows8 + \brief a version corresponding to Windows 8 (version 6.2). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::Windows8 = + QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 2); + +/*! + \variable QOperatingSystemVersion::Windows8_1 + \brief a version corresponding to Windows 8.1 (version 6.3). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::Windows8_1 = + QOperatingSystemVersion(QOperatingSystemVersion::Windows, 6, 3); + +/*! + \variable QOperatingSystemVersion::Windows10 + \brief a version corresponding to Windows 10 (version 10.0). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::Windows10 = + QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10); + +/*! + \variable QOperatingSystemVersion::OSXMavericks + \brief a version corresponding to OS X Mavericks (version 10.9). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::OSXMavericks = + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 9); + +/*! + \variable QOperatingSystemVersion::OSXYosemite + \brief a version corresponding to OS X Yosemite (version 10.10). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::OSXYosemite = + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 10); + +/*! + \variable QOperatingSystemVersion::OSXElCapitan + \brief a version corresponding to OS X El Capitan (version 10.11). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::OSXElCapitan = + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 11); + +/*! + \variable QOperatingSystemVersion::MacOSSierra + \brief a version corresponding to macOS Sierra (version 10.12). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::MacOSSierra = + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 12); + +/*! + \variable QOperatingSystemVersion::AndroidJellyBean + \brief a version corresponding to Android Jelly Bean (version 4.1, API level 16). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidJellyBean = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 4, 1); + +/*! + \variable QOperatingSystemVersion::AndroidJellyBean_MR1 + \brief a version corresponding to Android Jelly Bean, maintenance release 1 + (version 4.2, API level 17). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidJellyBean_MR1 = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 4, 2); + +/*! + \variable QOperatingSystemVersion::AndroidJellyBean_MR2 + \brief a version corresponding to Android Jelly Bean, maintenance release 2 + (version 4.3, API level 18). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidJellyBean_MR2 = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 4, 3); + +/*! + \variable QOperatingSystemVersion::AndroidKitKat + \brief a version corresponding to Android KitKat (versions 4.4 & 4.4W, API levels 19 & 20). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidKitKat = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 4, 4); + +/*! + \variable QOperatingSystemVersion::AndroidLollipop + \brief a version corresponding to Android Lollipop (version 5.0, API level 21). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidLollipop = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 5, 0); + +/*! + \variable QOperatingSystemVersion::AndroidLollipop_MR1 + \brief a version corresponding to Android Lollipop, maintenance release 1 + (version 5.1, API level 22). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidLollipop_MR1 = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 5, 1); + +/*! + \variable QOperatingSystemVersion::AndroidMarshmallow + \brief a version corresponding to Android Marshmallow (version 6.0, API level 23). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidMarshmallow = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 6, 0); + +/*! + \variable QOperatingSystemVersion::AndroidNougat + \brief a version corresponding to Android Nougat (version 7.0, API level 24). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidNougat = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 7, 0); + +/*! + \variable QOperatingSystemVersion::AndroidNougat_MR1 + \brief a version corresponding to Android Nougat, maintenance release 1 + (version 7.0, API level 25). + \since 5.9 + */ +const QOperatingSystemVersion QOperatingSystemVersion::AndroidNougat_MR1 = + QOperatingSystemVersion(QOperatingSystemVersion::Android, 7, 1); + +QT_END_NAMESPACE diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h new file mode 100644 index 0000000000..cc14d701e1 --- /dev/null +++ b/src/corelib/global/qoperatingsystemversion.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qglobal.h> + +#ifndef QOPERATINGSYSTEMVERSION_H +#define QOPERATINGSYSTEMVERSION_H + +QT_BEGIN_NAMESPACE + +class QString; +class QVersionNumber; + +class Q_CORE_EXPORT QOperatingSystemVersion +{ +public: + enum OSType { + Unknown = 0, + Windows, + MacOS, + IOS, + TvOS, + WatchOS, + Android + }; + + static const QOperatingSystemVersion Windows7; + static const QOperatingSystemVersion Windows8; + static const QOperatingSystemVersion Windows8_1; + static const QOperatingSystemVersion Windows10; + + static const QOperatingSystemVersion OSXMavericks; + static const QOperatingSystemVersion OSXYosemite; + static const QOperatingSystemVersion OSXElCapitan; + static const QOperatingSystemVersion MacOSSierra; + + static const QOperatingSystemVersion AndroidJellyBean; + static const QOperatingSystemVersion AndroidJellyBean_MR1; + static const QOperatingSystemVersion AndroidJellyBean_MR2; + static const QOperatingSystemVersion AndroidKitKat; + static const QOperatingSystemVersion AndroidLollipop; + static const QOperatingSystemVersion AndroidLollipop_MR1; + static const QOperatingSystemVersion AndroidMarshmallow; + static const QOperatingSystemVersion AndroidNougat; + static const QOperatingSystemVersion AndroidNougat_MR1; + + QOperatingSystemVersion(const QOperatingSystemVersion &other) = default; + Q_DECL_CONSTEXPR QOperatingSystemVersion(OSType osType, + int vmajor, int vminor = -1, int vmicro = -1) + : m_os(osType), + m_major(qMax(-1, vmajor)), + m_minor(vmajor < 0 ? -1 : qMax(-1, vminor)), + m_micro(vmajor < 0 || vminor < 0 ? -1 : qMax(-1, vmicro)) + { } + + static QOperatingSystemVersion current(); + + Q_DECL_CONSTEXPR int majorVersion() const { return m_major; } + Q_DECL_CONSTEXPR int minorVersion() const { return m_minor; } + Q_DECL_CONSTEXPR int microVersion() const { return m_micro; } + + Q_DECL_CONSTEXPR int segmentCount() const + { return m_micro >= 0 ? 3 : m_minor >= 0 ? 2 : m_major >= 0 ? 1 : 0; } + + bool isAnyOfType(std::initializer_list<OSType> types) const; + Q_DECL_CONSTEXPR OSType type() const { return m_os; } + QString name() const; + + friend bool operator>(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs) + { return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) > 0; } + + friend bool operator>=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs) + { return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) >= 0; } + + friend bool operator<(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs) + { return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) < 0; } + + friend bool operator<=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs) + { return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) <= 0; } + +private: + QOperatingSystemVersion() = default; + OSType m_os; + int m_major; + int m_minor; + int m_micro; + + static int compare(const QOperatingSystemVersion &v1, const QOperatingSystemVersion &v2); +}; + +QT_END_NAMESPACE + +#endif // QOPERATINGSYSTEMVERSION_H diff --git a/src/corelib/global/qoperatingsystemversion_darwin.mm b/src/corelib/global/qoperatingsystemversion_darwin.mm new file mode 100644 index 0000000000..d8b927ff5d --- /dev/null +++ b/src/corelib/global/qoperatingsystemversion_darwin.mm @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoperatingsystemversion_p.h" +#import <Foundation/Foundation.h> + +QT_BEGIN_NAMESPACE + +QOperatingSystemVersion QOperatingSystemVersion::current() +{ + NSOperatingSystemVersion osv = NSProcessInfo.processInfo.operatingSystemVersion; + QOperatingSystemVersion v; + v.m_os = currentType(); + v.m_major = osv.majorVersion; + v.m_minor = osv.minorVersion; + v.m_micro = osv.patchVersion; + return v; +} + +QT_END_NAMESPACE diff --git a/src/corelib/global/qoperatingsystemversion_p.h b/src/corelib/global/qoperatingsystemversion_p.h new file mode 100644 index 0000000000..78d0daf0c6 --- /dev/null +++ b/src/corelib/global/qoperatingsystemversion_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOPERATINGSYSTEMVERSION_P_H +#define QOPERATINGSYSTEMVERSION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qoperatingsystemversion.h" + +#ifdef Q_OS_WIN +#include <qt_windows.h> +#endif + +QT_BEGIN_NAMESPACE + +#ifdef Q_OS_WIN +OSVERSIONINFOEX qWindowsVersionInfo(); +#endif + +static inline QOperatingSystemVersion::OSType currentType() +{ +#if defined(Q_OS_WIN) + return QOperatingSystemVersion::Windows; +#elif defined(Q_OS_MACOS) + return QOperatingSystemVersion::MacOS; +#elif defined(Q_OS_IOS) + return QOperatingSystemVersion::IOS; +#elif defined(Q_OS_TVOS) + return QOperatingSystemVersion::TvOS; +#elif defined(Q_OS_WATCHOS) + return QOperatingSystemVersion::WatchOS; +#elif defined(Q_OS_ANDROID) + return QOperatingSystemVersion::Android; +#else + return QOperatingSystemVersion::Unknown; +#endif +} + +QT_END_NAMESPACE + +#endif // QOPERATINGSYSTEMVERSION_P_H diff --git a/src/corelib/global/qoperatingsystemversion_win.cpp b/src/corelib/global/qoperatingsystemversion_win.cpp new file mode 100644 index 0000000000..060ca2f7da --- /dev/null +++ b/src/corelib/global/qoperatingsystemversion_win.cpp @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoperatingsystemversion_p.h" +#include <qt_windows.h> +#include <qbytearray.h> + +QT_BEGIN_NAMESPACE + +#ifdef Q_OS_WINRT +static inline HMODULE moduleHandleForFunction(LPCVOID address) +{ + // This is a widely used, decades-old technique for retrieving the handle + // of a module and is effectively equivalent to GetModuleHandleEx + // (which is unavailable on WinRT) + MEMORY_BASIC_INFORMATION mbi = { 0, 0, 0, 0, 0, 0, 0 }; + if (VirtualQuery(address, &mbi, sizeof(mbi)) == 0) + return 0; + return reinterpret_cast<HMODULE>(mbi.AllocationBase); +} +#endif + +static inline OSVERSIONINFOEX determineWinOsVersion() +{ + OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0}; + +#define GetProcAddressA GetProcAddress + + // GetModuleHandle is not supported in WinRT and linking to it at load time + // will not pass the Windows App Certification Kit... but it exists and is functional, + // so use some unusual but widely used techniques to get a pointer to it +#ifdef Q_OS_WINRT + // 1. Get HMODULE of kernel32.dll, using the address of some function exported by that DLL + HMODULE kernelModule = moduleHandleForFunction(reinterpret_cast<LPCVOID>(VirtualQuery)); + if (Q_UNLIKELY(!kernelModule)) + return result; + + // 2. Get pointer to GetModuleHandle so we can then load other arbitrary modules (DLLs) + typedef HMODULE(WINAPI *GetModuleHandleFunction)(LPCWSTR); + GetModuleHandleFunction pGetModuleHandle = reinterpret_cast<GetModuleHandleFunction>( + GetProcAddressA(kernelModule, "GetModuleHandleW")); + if (Q_UNLIKELY(!pGetModuleHandle)) + return result; +#else +#define pGetModuleHandle GetModuleHandleW +#endif + +#ifndef Q_OS_WINCE + HMODULE ntdll = pGetModuleHandle(L"ntdll.dll"); + if (Q_UNLIKELY(!ntdll)) + return result; + + // NTSTATUS is not defined on WinRT + typedef LONG NTSTATUS; + typedef NTSTATUS (NTAPI *RtlGetVersionFunction)(LPOSVERSIONINFO); + + // RtlGetVersion is documented public API but we must load it dynamically + // because linking to it at load time will not pass the Windows App Certification Kit + // https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910.aspx + RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>( + GetProcAddressA(ntdll, "RtlGetVersion")); + if (Q_UNLIKELY(!pRtlGetVersion)) + return result; + + // GetVersionEx() has been deprecated in Windows 8.1 and will return + // only Windows 8 from that version on, so use the kernel API function. + pRtlGetVersion((LPOSVERSIONINFO) &result); // always returns STATUS_SUCCESS +#else // !Q_OS_WINCE + GetVersionEx(&result); +#endif + return result; +} + +OSVERSIONINFOEX qWindowsVersionInfo() +{ + OSVERSIONINFOEX realResult = determineWinOsVersion(); +#ifdef QT_DEBUG + { + if (Q_UNLIKELY(qEnvironmentVariableIsSet("QT_WINVER_OVERRIDE"))) { + OSVERSIONINFOEX result = realResult; + result.dwMajorVersion = 0; + result.dwMinorVersion = 0; + + // Erase any build number and service pack information + result.dwBuildNumber = 0; + result.szCSDVersion[0] = L'\0'; + result.wServicePackMajor = 0; + result.wServicePackMinor = 0; + + const QByteArray winVerOverride = qgetenv("QT_WINVER_OVERRIDE"); + if (winVerOverride == "WINDOWS7" || winVerOverride == "2008_R2") { + result.dwMajorVersion = 6; + result.dwMinorVersion = 1; + } else if (winVerOverride == "WINDOWS8" || winVerOverride == "2012") { + result.dwMajorVersion = 6; + result.dwMinorVersion = 2; + } else if (winVerOverride == "WINDOWS8_1" || winVerOverride == "2012_R2") { + result.dwMajorVersion = 6; + result.dwMinorVersion = 3; + } else if (winVerOverride == "WINDOWS10" || winVerOverride == "2016") { + result.dwMajorVersion = 10; + } else { + return realResult; + } + + if (winVerOverride == "2008_R2" + || winVerOverride == "2012" + || winVerOverride == "2012_R2" + || winVerOverride == "2016") { + // If the current host OS is a domain controller and the override OS + // is also a server type OS, preserve that information + if (result.wProductType == VER_NT_WORKSTATION) + result.wProductType = VER_NT_SERVER; + } else { + // Any other OS must be a workstation OS type + result.wProductType = VER_NT_WORKSTATION; + } + } + } +#endif + return realResult; +} + +QOperatingSystemVersion QOperatingSystemVersion::current() +{ + QOperatingSystemVersion v; + v.m_os = currentType(); + const OSVERSIONINFOEX osv = qWindowsVersionInfo(); + v.m_major = osv.dwMajorVersion; + v.m_minor = osv.dwMinorVersion; + v.m_micro = osv.dwBuildNumber; + return v; +} + +QT_END_NAMESPACE diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index 55fcb37093..ed11e013f2 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -107,14 +107,17 @@ # define Q_PROCESSOR_ARM __TARGET_ARCH_ARM # elif defined(_M_ARM) && _M_ARM > 1 # define Q_PROCESSOR_ARM _M_ARM -# elif defined(__ARM64_ARCH_8__) || defined(__aarch64__) +# elif defined(__ARM64_ARCH_8__) \ + || defined(__aarch64__) \ + || defined(__CORE_CORTEXAV8__) // GHS-specific for INTEGRITY # define Q_PROCESSOR_ARM 8 # elif defined(__ARM_ARCH_7__) \ || defined(__ARM_ARCH_7A__) \ || defined(__ARM_ARCH_7R__) \ || defined(__ARM_ARCH_7M__) \ || defined(__ARM_ARCH_7S__) \ - || defined(_ARM_ARCH_7) + || defined(_ARM_ARCH_7) \ + || defined(__CORE_CORTEXA__) // GHS-specific for INTEGRITY # define Q_PROCESSOR_ARM 7 # elif defined(__ARM_ARCH_6__) \ || defined(__ARM_ARCH_6J__) \ diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h index 23f412aa6a..f443ab4b93 100644 --- a/src/corelib/global/qsysinfo.h +++ b/src/corelib/global/qsysinfo.h @@ -49,6 +49,23 @@ QT_BEGIN_NAMESPACE System information */ +/* + * GCC (5-7) has a regression that causes it to emit wrong deprecated warnings: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77849 + * + * Try to work around it by defining our own macro. + */ + +#ifdef QT_SYSINFO_DEPRECATED_X +#error "QT_SYSINFO_DEPRECATED_X already defined" +#endif + +#ifdef Q_CC_GNU +#define QT_SYSINFO_DEPRECATED_X(x) +#else +#define QT_SYSINFO_DEPRECATED_X(x) QT_DEPRECATED_X(x) +#endif + class QString; class Q_CORE_EXPORT QSysInfo { public: @@ -79,7 +96,8 @@ public: # endif }; #endif - enum WinVersion { +#if QT_DEPRECATED_SINCE(5, 9) + enum QT_DEPRECATED_X("Use QOperatingSystemVersion") WinVersion { WV_None = 0x0000, WV_32s = 0x0001, @@ -117,19 +135,12 @@ public: WV_CE_6 = 0x0400, WV_CE_based = 0x0f00 }; -#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) - static const WinVersion WindowsVersion; - static WinVersion windowsVersion(); -#else - static const WinVersion WindowsVersion = WV_None; - static WinVersion windowsVersion() { return WV_None; } -#endif #define Q_MV_OSX(major, minor) (major == 10 ? minor + 2 : (major == 9 ? 1 : 0)) #define Q_MV_IOS(major, minor) (QSysInfo::MV_IOS | major << 4 | minor) #define Q_MV_TVOS(major, minor) (QSysInfo::MV_TVOS | major << 4 | minor) #define Q_MV_WATCHOS(major, minor) (QSysInfo::MV_WATCHOS | major << 4 | minor) - enum MacVersion { + enum QT_DEPRECATED_X("Use QOperatingSystemVersion") MacVersion { MV_None = 0xffff, MV_Unknown = 0x0000, @@ -198,13 +209,29 @@ public: MV_WATCHOS_2_2 = Q_MV_WATCHOS(2, 2), MV_WATCHOS_3_0 = Q_MV_WATCHOS(3, 0) }; + +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations") +QT_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") +QT_WARNING_DISABLE_INTEL(1478) +QT_WARNING_DISABLE_INTEL(1786) +QT_WARNING_DISABLE_MSVC(4996) +#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) + QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const WinVersion WindowsVersion; + QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static WinVersion windowsVersion(); +#else + QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const WinVersion WindowsVersion = WV_None; + QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static WinVersion windowsVersion() { return WV_None; } +#endif #if defined(Q_OS_MAC) - static const MacVersion MacintoshVersion; - static MacVersion macVersion(); + QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const MacVersion MacintoshVersion; + QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static MacVersion macVersion(); #else - static const MacVersion MacintoshVersion = MV_None; - static MacVersion macVersion() { return MV_None; } + QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static const MacVersion MacintoshVersion = MV_None; + QT_SYSINFO_DEPRECATED_X("Use QOperatingSystemVersion::current()") static MacVersion macVersion() { return MV_None; } #endif +QT_WARNING_POP +#endif // QT_DEPRECATED_SINCE(5, 9) static QString buildCpuArchitecture(); static QString currentCpuArchitecture(); @@ -219,5 +246,7 @@ public: static QString machineHostName(); }; +#undef QT_SYSINFO_DEPRECATED_X + QT_END_NAMESPACE #endif // QSYSINFO_H diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 3b486b8f6f..3133b4a719 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -134,7 +134,6 @@ # define WINAPI_FAMILY_PC_APP WINAPI_FAMILY_APP # endif # if defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -# define Q_OS_WINPHONE # define Q_OS_WINRT # elif WINAPI_FAMILY==WINAPI_FAMILY_PC_APP # define Q_OS_WINRT diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 8aa5cb4fb4..7031021e16 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -58,9 +58,10 @@ class QTypeInfo { public: enum { + isSpecialized = std::is_enum<T>::value, // don't require every enum to be marked manually isPointer = false, isIntegral = std::is_integral<T>::value, - isComplex = true, + isComplex = !isIntegral && !std::is_enum<T>::value, isStatic = true, isRelocatable = std::is_enum<T>::value, isLarge = (sizeof(T)>sizeof(void*)), @@ -74,6 +75,7 @@ class QTypeInfo<void> { public: enum { + isSpecialized = true, isPointer = false, isIntegral = false, isComplex = false, @@ -90,6 +92,7 @@ class QTypeInfo<T*> { public: enum { + isSpecialized = true, isPointer = true, isIntegral = false, isComplex = false, @@ -124,7 +127,7 @@ struct QTypeInfoQuery : public QTypeInfo<T> // if QTypeInfo<T>::isRelocatable exists, use it template <typename T> -struct QTypeInfoQuery<T, typename QtPrivate::QEnableIf<QTypeInfo<T>::isRelocatable || true>::Type> : public QTypeInfo<T> +struct QTypeInfoQuery<T, typename std::enable_if<QTypeInfo<T>::isRelocatable || true>::type> : public QTypeInfo<T> {}; /*! @@ -152,6 +155,7 @@ class QTypeInfoMerger { public: enum { + isSpecialized = true, isComplex = QTypeInfoQuery<T1>::isComplex || QTypeInfoQuery<T2>::isComplex || QTypeInfoQuery<T3>::isComplex || QTypeInfoQuery<T4>::isComplex, isStatic = QTypeInfoQuery<T1>::isStatic || QTypeInfoQuery<T2>::isStatic @@ -173,6 +177,7 @@ class QTypeInfo< CONTAINER<T> > \ { \ public: \ enum { \ + isSpecialized = true, \ isPointer = false, \ isIntegral = false, \ isComplex = true, \ @@ -201,6 +206,7 @@ class QTypeInfo< CONTAINER<K, V> > \ { \ public: \ enum { \ + isSpecialized = true, \ isPointer = false, \ isIntegral = false, \ isComplex = true, \ @@ -241,6 +247,7 @@ class QTypeInfo<TYPE > \ { \ public: \ enum { \ + isSpecialized = true, \ isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \ isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \ isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE), \ diff --git a/src/corelib/global/qtypetraits.h b/src/corelib/global/qtypetraits.h index 9773db919b..35e407e2de 100644 --- a/src/corelib/global/qtypetraits.h +++ b/src/corelib/global/qtypetraits.h @@ -37,6 +37,12 @@ ** ****************************************************************************/ +// ### Qt 6: remove this header +// +// This header is deliberately empty. Although it did not contain any public API, +// it was accidentally made public in Qt 5. So: do not remove it for the moment +// being, to prevent #include breaks in downstreams. + #include "QtCore/qglobal.h" #ifndef QTYPETRAITS_H @@ -44,53 +50,6 @@ QT_BEGIN_NAMESPACE -namespace QtPrivate { - -// -// Define QIsUnsignedEnum, QIsSignedEnum - -// std::is_signed, std::is_unsigned does not work for enum's -// - -// a metafunction to invert an integral_constant: -template <typename T> -struct not_ - : std::integral_constant<bool, !T::value> {}; - -// Checks whether a type is unsigned (T must be convertible to unsigned int): -template <typename T> -struct QIsUnsignedEnum - : std::integral_constant<bool, (T(0) < T(-1))> {}; - -// Checks whether a type is signed (T must be convertible to int): -template <typename T> -struct QIsSignedEnum - : not_< QIsUnsignedEnum<T> > {}; - -Q_STATIC_ASSERT(( QIsUnsignedEnum<quint8>::value)); -Q_STATIC_ASSERT((!QIsUnsignedEnum<qint8>::value)); - -Q_STATIC_ASSERT((!QIsSignedEnum<quint8>::value)); -Q_STATIC_ASSERT(( QIsSignedEnum<qint8>::value)); - -Q_STATIC_ASSERT(( QIsUnsignedEnum<quint16>::value)); -Q_STATIC_ASSERT((!QIsUnsignedEnum<qint16>::value)); - -Q_STATIC_ASSERT((!QIsSignedEnum<quint16>::value)); -Q_STATIC_ASSERT(( QIsSignedEnum<qint16>::value)); - -Q_STATIC_ASSERT(( QIsUnsignedEnum<quint32>::value)); -Q_STATIC_ASSERT((!QIsUnsignedEnum<qint32>::value)); - -Q_STATIC_ASSERT((!QIsSignedEnum<quint32>::value)); -Q_STATIC_ASSERT(( QIsSignedEnum<qint32>::value)); - -Q_STATIC_ASSERT(( QIsUnsignedEnum<quint64>::value)); -Q_STATIC_ASSERT((!QIsUnsignedEnum<qint64>::value)); - -Q_STATIC_ASSERT((!QIsSignedEnum<quint64>::value)); -Q_STATIC_ASSERT(( QIsSignedEnum<qint64>::value)); - -} // namespace QtPrivate - QT_END_NAMESPACE + #endif // QTYPETRAITS_H |