diff options
-rw-r--r-- | src/corelib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 316 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 135 | ||||
-rw-r--r-- | src/corelib/global/qprocessordetection.h | 3 | ||||
-rw-r--r-- | src/corelib/global/qtypes.cpp | 332 | ||||
-rw-r--r-- | src/corelib/global/qtypes.h | 163 |
6 files changed, 497 insertions, 453 deletions
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 6b18d0e506..575bb1b0f4 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -79,6 +79,7 @@ qt_internal_add_module(Core global/qtranslation.h global/qtversionchecks.h global/qtypeinfo.h + global/qtypes.cpp global/qtypes.h global/qvolatile_p.h global/q20algorithm.h global/q20functional.h diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 2852beaaab..d8d618e92b 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -19,7 +19,6 @@ #include "qnativeinterface_p.h" #include <stdlib.h> -#include <limits.h> #include <stdarg.h> #include <string.h> @@ -88,62 +87,6 @@ QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; -// Statically check assumptions about the environment we're running -// in. The idea here is to error or warn if otherwise implicit Qt -// assumptions are not fulfilled on new hardware or compilers -// (if this list becomes too long, consider factoring into a separate file) -static_assert(UCHAR_MAX == 255, "Qt assumes that char is 8 bits"); -static_assert(sizeof(int) == 4, "Qt assumes that int is 32 bits"); -static_assert(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined incorrectly"); -static_assert(sizeof(float) == 4, "Qt assumes that float is 32 bits"); -static_assert(sizeof(char16_t) == 2, "Qt assumes that char16_t is 16 bits"); -static_assert(sizeof(char32_t) == 4, "Qt assumes that char32_t is 32 bits"); -#if defined(Q_OS_WIN) -static_assert(sizeof(wchar_t) == sizeof(char16_t)); -#endif -static_assert(std::numeric_limits<int>::radix == 2, - "Qt assumes binary integers"); -static_assert((std::numeric_limits<int>::max() + std::numeric_limits<int>::lowest()) == -1, - "Qt assumes two's complement integers"); -static_assert(sizeof(wchar_t) == sizeof(char32_t) || sizeof(wchar_t) == sizeof(char16_t), - "Qt assumes wchar_t is compatible with either char32_t or char16_t"); - -// While we'd like to check for __STDC_IEC_559__, as per ISO/IEC 9899:2011 -// Annex F (C11, normative for C++11), there are a few corner cases regarding -// denormals where GHS compiler is relying hardware behavior that is not IEC -// 559 compliant. So split the check in several subchecks. - -// On GHS the compiler reports std::numeric_limits<float>::is_iec559 as false. -// This is all right according to our needs. -#if !defined(Q_CC_GHS) -static_assert(std::numeric_limits<float>::is_iec559, - "Qt assumes IEEE 754 floating point"); -#endif - -// Technically, presence of NaN and infinities are implied from the above check, -// but double checking our environment doesn't hurt... -static_assert(std::numeric_limits<float>::has_infinity && - std::numeric_limits<float>::has_quiet_NaN, - "Qt assumes IEEE 754 floating point"); - -// is_iec559 checks for ISO/IEC/IEEE 60559:2011 (aka IEEE 754-2008) compliance, -// but that allows for a non-binary radix. We need to recheck that. -// Note how __STDC_IEC_559__ would instead check for IEC 60559:1989, aka -// ANSI/IEEE 754−1985, which specifically implies binary floating point numbers. -static_assert(std::numeric_limits<float>::radix == 2, - "Qt assumes binary IEEE 754 floating point"); - -// not required by the definition of size_t, but we depend on this -static_assert(sizeof(size_t) == sizeof(void *), "size_t and a pointer don't have the same size"); -static_assert(sizeof(size_t) == sizeof(qsizetype)); // implied by the definition -static_assert((std::is_same<qsizetype, qptrdiff>::value)); - -// Check that our own typedefs are not broken. -static_assert(sizeof(qint8) == 1, "Internal error, qint8 is misdefined"); -static_assert(sizeof(qint16)== 2, "Internal error, qint16 is misdefined"); -static_assert(sizeof(qint32) == 4, "Internal error, qint32 is misdefined"); -static_assert(sizeof(qint64) == 8, "Internal error, qint64 is misdefined"); - /*! \class QFlag \inmodule QtCore @@ -773,265 +716,6 @@ static_assert(sizeof(qint64) == 8, "Internal error, qint64 is misdefined"); */ /*! - \typedef qreal - \relates <QtGlobal> - - Typedef for \c double unless Qt is configured with the - \c{-qreal float} option. -*/ - -/*! \typedef uchar - \relates <QtGlobal> - - Convenience typedef for \c{unsigned char}. -*/ - -/*! \typedef ushort - \relates <QtGlobal> - - Convenience typedef for \c{unsigned short}. -*/ - -/*! \typedef uint - \relates <QtGlobal> - - Convenience typedef for \c{unsigned int}. -*/ - -/*! \typedef ulong - \relates <QtGlobal> - - Convenience typedef for \c{unsigned long}. -*/ - -/*! \typedef qint8 - \relates <QtGlobal> - - Typedef for \c{signed char}. This type is guaranteed to be 8-bit - on all platforms supported by Qt. -*/ - -/*! - \typedef quint8 - \relates <QtGlobal> - - Typedef for \c{unsigned char}. This type is guaranteed to - be 8-bit on all platforms supported by Qt. -*/ - -/*! \typedef qint16 - \relates <QtGlobal> - - Typedef for \c{signed short}. This type is guaranteed to be - 16-bit on all platforms supported by Qt. -*/ - -/*! - \typedef quint16 - \relates <QtGlobal> - - Typedef for \c{unsigned short}. This type is guaranteed to - be 16-bit on all platforms supported by Qt. -*/ - -/*! \typedef qint32 - \relates <QtGlobal> - - Typedef for \c{signed int}. This type is guaranteed to be 32-bit - on all platforms supported by Qt. -*/ - -/*! - \typedef quint32 - \relates <QtGlobal> - - Typedef for \c{unsigned int}. This type is guaranteed to - be 32-bit on all platforms supported by Qt. -*/ - -/*! \typedef qint64 - \relates <QtGlobal> - - Typedef for \c{long long int}. This type is guaranteed to be 64-bit - on all platforms supported by Qt. - - Literals of this type can be created using the Q_INT64_C() macro: - - \snippet code/src_corelib_global_qglobal.cpp 5 - - \sa Q_INT64_C(), quint64, qlonglong -*/ - -/*! - \typedef quint64 - \relates <QtGlobal> - - Typedef for \c{unsigned long long int}. This type is guaranteed to - be 64-bit on all platforms supported by Qt. - - Literals of this type can be created using the Q_UINT64_C() - macro: - - \snippet code/src_corelib_global_qglobal.cpp 6 - - \sa Q_UINT64_C(), qint64, qulonglong -*/ - -/*! - \typedef qintptr - \relates <QtGlobal> - - Integral type for representing pointers in a signed integer (useful for - hashing, etc.). - - Typedef for either qint32 or qint64. This type is guaranteed to - be the same size as a pointer on all platforms supported by Qt. On - a system with 32-bit pointers, qintptr is a typedef for qint32; - on a system with 64-bit pointers, qintptr is a typedef for - qint64. - - Note that qintptr is signed. Use quintptr for unsigned values. - - In order to print values of this type by using formatted-output - facilities such as \c{printf()}, qDebug(), QString::asprintf() and - so on, you can use the \c{PRIdQINTPTR} and \c{PRIiQINTPTR} - macros as format specifiers. They will both print the value as a - base 10 number. - - \code - qintptr p = 123; - printf("The pointer is %" PRIdQINTPTR "\n", p); - \endcode - - \sa qptrdiff, qint32, qint64 -*/ - -/*! - \macro PRIdQINTPTR - \macro PRIiQINTPTR - \since 6.2 - \relates <QtGlobal> - - See qintptr. -*/ - -/*! - \typedef quintptr - \relates <QtGlobal> - - Integral type for representing pointers in an unsigned integer (useful for - hashing, etc.). - - Typedef for either quint32 or quint64. This type is guaranteed to - be the same size as a pointer on all platforms supported by Qt. On - a system with 32-bit pointers, quintptr is a typedef for quint32; - on a system with 64-bit pointers, quintptr is a typedef for - quint64. - - Note that quintptr is unsigned. Use qptrdiff for signed values. - - In order to print values of this type by using formatted-output - facilities such as \c{printf()}, qDebug(), QString::asprintf() and - so on, you can use the following macros as format specifiers: - - \list - \li \c{PRIuQUINTPTR}: prints the value as a base 10 number. - \li \c{PRIoQUINTPTR}: prints the value as a base 8 number. - \li \c{PRIxQUINTPTR}: prints the value as a base 16 number, using lowercase \c{a-f} letters. - \li \c{PRIXQUINTPTR}: prints the value as a base 16 number, using uppercase \c{A-F} letters. - \endlist - - \code - quintptr p = 123u; - printf("The pointer value is 0x%" PRIXQUINTPTR "\n", p); - \endcode - - \sa qptrdiff, quint32, quint64 -*/ - -/*! - \macro PRIoQUINTPTR - \macro PRIuQUINTPTR - \macro PRIxQUINTPTR - \macro PRIXQUINTPTR - \since 6.2 - \relates <QtGlobal> - - See quintptr. -*/ - -/*! - \typedef qptrdiff - \relates <QtGlobal> - - Integral type for representing pointer differences. - - Typedef for either qint32 or qint64. This type is guaranteed to be - the same size as a pointer on all platforms supported by Qt. On a - system with 32-bit pointers, quintptr is a typedef for quint32; on - a system with 64-bit pointers, quintptr is a typedef for quint64. - - Note that qptrdiff is signed. Use quintptr for unsigned values. - - In order to print values of this type by using formatted-output - facilities such as \c{printf()}, qDebug(), QString::asprintf() and - so on, you can use the \c{PRIdQPTRDIFF} and \c{PRIiQPTRDIFF} - macros as format specifiers. They will both print the value as a - base 10 number. - - \code - qptrdiff d = 123; - printf("The difference is %" PRIdQPTRDIFF "\n", d); - \endcode - - \sa quintptr, qint32, qint64 -*/ - -/*! - \macro PRIdQPTRDIFF - \macro PRIiQPTRDIFF - \since 6.2 - \relates <QtGlobal> - - See qptrdiff. -*/ - -/*! - \typedef qsizetype - \relates <QtGlobal> - \since 5.10 - - Integral type providing Posix' \c ssize_t for all platforms. - - This type is guaranteed to be the same size as a \c size_t on all - platforms supported by Qt. - - Note that qsizetype is signed. Use \c size_t for unsigned values. - - In order to print values of this type by using formatted-output - facilities such as \c{printf()}, qDebug(), QString::asprintf() and - so on, you can use the \c{PRIdQSIZETYPE} and \c{PRIiQSIZETYPE} - macros as format specifiers. They will both print the value as a - base 10 number. - - \code - qsizetype s = 123; - printf("The size is %" PRIdQSIZETYPE "\n", s); - \endcode - - \sa qptrdiff -*/ - -/*! - \macro PRIdQSIZETYPE - \macro PRIiQSIZETYPE - \since 6.2 - \relates <QtGlobal> - - See qsizetype. -*/ - -/*! \enum QtMsgType \relates <QtGlobal> diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index b475c9cc64..82c6e5e037 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -7,7 +7,6 @@ #if 0 #pragma qt_class(QtGlobal) -#pragma qt_class(QIntegerForSize) #endif #ifdef __cplusplus @@ -98,6 +97,7 @@ inline void qt_noop(void) {} #include <QtCore/qcompilerdetection.h> #include <QtCore/qassert.h> +#include <QtCore/qtypes.h> #if defined (__ELF__) # define Q_OF_ELF @@ -115,73 +115,6 @@ inline void qt_noop(void) {} QT_BEGIN_NAMESPACE /* - Size-dependent types (architechture-dependent byte order) - - Make sure to update QMetaType when changing these typedefs -*/ - -typedef signed char qint8; /* 8 bit signed */ -typedef unsigned char quint8; /* 8 bit unsigned */ -typedef short qint16; /* 16 bit signed */ -typedef unsigned short quint16; /* 16 bit unsigned */ -typedef int qint32; /* 32 bit signed */ -typedef unsigned int quint32; /* 32 bit unsigned */ -// Unlike LL / ULL in C++, for historical reasons, we force the -// result to be of the requested type. -#ifdef __cplusplus -# define Q_INT64_C(c) static_cast<long long>(c ## LL) /* signed 64 bit constant */ -# define Q_UINT64_C(c) static_cast<unsigned long long>(c ## ULL) /* unsigned 64 bit constant */ -#else -# define Q_INT64_C(c) ((long long)(c ## LL)) /* signed 64 bit constant */ -# define Q_UINT64_C(c) ((unsigned long long)(c ## ULL)) /* unsigned 64 bit constant */ -#endif -typedef long long qint64; /* 64 bit signed */ -typedef unsigned long long quint64; /* 64 bit unsigned */ - -typedef qint64 qlonglong; -typedef quint64 qulonglong; - -#ifndef __cplusplus -// In C++ mode, we define below using QIntegerForSize template -Q_STATIC_ASSERT_X(sizeof(ptrdiff_t) == sizeof(size_t), "Weird ptrdiff_t and size_t definitions"); -typedef ptrdiff_t qptrdiff; -typedef ptrdiff_t qsizetype; -typedef ptrdiff_t qintptr; -typedef size_t quintptr; - -#define PRIdQPTRDIFF "td" -#define PRIiQPTRDIFF "ti" - -#define PRIdQSIZETYPE "td" -#define PRIiQSIZETYPE "ti" - -#define PRIdQINTPTR "td" -#define PRIiQINTPTR "ti" - -#define PRIuQUINTPTR "zu" -#define PRIoQUINTPTR "zo" -#define PRIxQUINTPTR "zx" -#define PRIXQUINTPTR "zX" -#endif - -/* - Useful type definitions for Qt -*/ - -QT_BEGIN_INCLUDE_NAMESPACE -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; -QT_END_INCLUDE_NAMESPACE - -#if defined(QT_COORD_TYPE) -typedef QT_COORD_TYPE qreal; -#else -typedef double qreal; -#endif - -/* Some classes do not permit copies to be made of an object. These classes contains a private copy constructor and assignment operator to disable copying (the compiler gives an error message). @@ -297,72 +230,6 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION const char *qVersion(void) Q_DECL_NOEXCEPT; # define Q_DESTRUCTOR_FUNCTION(AFUNC) Q_DESTRUCTOR_FUNCTION0(AFUNC) #endif -/* - quintptr and qptrdiff is guaranteed to be the same size as a pointer, i.e. - - sizeof(void *) == sizeof(quintptr) - && sizeof(void *) == sizeof(qptrdiff) - - size_t and qsizetype are not guaranteed to be the same size as a pointer, but - they usually are. We actually check for that in qglobal.cpp. -*/ -template <int> struct QIntegerForSize; -template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qint8 Signed; }; -template <> struct QIntegerForSize<2> { typedef quint16 Unsigned; typedef qint16 Signed; }; -template <> struct QIntegerForSize<4> { typedef quint32 Unsigned; typedef qint32 Signed; }; -template <> struct QIntegerForSize<8> { typedef quint64 Unsigned; typedef qint64 Signed; }; -#if defined(Q_CC_GNU) && defined(__SIZEOF_INT128__) -template <> struct QIntegerForSize<16> { __extension__ typedef unsigned __int128 Unsigned; __extension__ typedef __int128 Signed; }; -#endif -template <class T> struct QIntegerForSizeof: QIntegerForSize<sizeof(T)> { }; -typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Signed qregisterint; -typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Unsigned qregisteruint; -typedef QIntegerForSizeof<void *>::Unsigned quintptr; -typedef QIntegerForSizeof<void *>::Signed qptrdiff; -typedef qptrdiff qintptr; -using qsizetype = QIntegerForSizeof<std::size_t>::Signed; - -// These custom definitions are necessary as we're not defining our -// datatypes in terms of the language ones, but in terms of integer -// types that have the sime size. For instance, on a 32-bit platform, -// qptrdiff is int, while ptrdiff_t may be aliased to long; therefore -// using %td to print a qptrdiff would be wrong (and raise -Wformat -// warnings), although both int and long have same bit size on that -// platform. -// -// We know that sizeof(size_t) == sizeof(void *) == sizeof(qptrdiff). -#if SIZE_MAX == 4294967295ULL -#define PRIuQUINTPTR "u" -#define PRIoQUINTPTR "o" -#define PRIxQUINTPTR "x" -#define PRIXQUINTPTR "X" - -#define PRIdQPTRDIFF "d" -#define PRIiQPTRDIFF "i" - -#define PRIdQINTPTR "d" -#define PRIiQINTPTR "i" - -#define PRIdQSIZETYPE "d" -#define PRIiQSIZETYPE "i" -#elif SIZE_MAX == 18446744073709551615ULL -#define PRIuQUINTPTR "llu" -#define PRIoQUINTPTR "llo" -#define PRIxQUINTPTR "llx" -#define PRIXQUINTPTR "llX" - -#define PRIdQPTRDIFF "lld" -#define PRIiQPTRDIFF "lli" - -#define PRIdQINTPTR "lld" -#define PRIiQINTPTR "lli" - -#define PRIdQSIZETYPE "lld" -#define PRIiQSIZETYPE "lli" -#else -#error Unsupported platform (unknown value for SIZE_MAX) -#endif - /* moc compats (signals/slots) */ #ifndef QT_MOC_COMPAT # define QT_MOC_COMPAT diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index 417b6cb508..e643192d53 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -2,9 +2,6 @@ // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#ifndef QGLOBAL_H -# include <QtCore/qglobal.h> -#endif #if 0 #pragma qt_sync_skip_header_check diff --git a/src/corelib/global/qtypes.cpp b/src/corelib/global/qtypes.cpp new file mode 100644 index 0000000000..8441b9806b --- /dev/null +++ b/src/corelib/global/qtypes.cpp @@ -0,0 +1,332 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// Copyright (C) 2022 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qtypes.h" + +#include <QtCore/qcompilerdetection.h> +#include <QtCore/qsystemdetection.h> +#include <QtCore/qprocessordetection.h> + +#include <climits> +#include <limits> +#include <type_traits> + +QT_BEGIN_NAMESPACE + +/*! + \typedef qreal + \relates <QtTypes> + + Typedef for \c double unless Qt is configured with the + \c{-qreal float} option. +*/ + +/*! \typedef uchar + \relates <QtTypes> + + Convenience typedef for \c{unsigned char}. +*/ + +/*! \typedef ushort + \relates <QtTypes> + + Convenience typedef for \c{unsigned short}. +*/ + +/*! \typedef uint + \relates <QtTypes> + + Convenience typedef for \c{unsigned int}. +*/ + +/*! \typedef ulong + \relates <QtTypes> + + Convenience typedef for \c{unsigned long}. +*/ + +/*! \typedef qint8 + \relates <QtTypes> + + Typedef for \c{signed char}. This type is guaranteed to be 8-bit + on all platforms supported by Qt. +*/ + +/*! + \typedef quint8 + \relates <QtTypes> + + Typedef for \c{unsigned char}. This type is guaranteed to + be 8-bit on all platforms supported by Qt. +*/ + +/*! \typedef qint16 + \relates <QtTypes> + + Typedef for \c{signed short}. This type is guaranteed to be + 16-bit on all platforms supported by Qt. +*/ + +/*! + \typedef quint16 + \relates <QtTypes> + + Typedef for \c{unsigned short}. This type is guaranteed to + be 16-bit on all platforms supported by Qt. +*/ + +/*! \typedef qint32 + \relates <QtTypes> + + Typedef for \c{signed int}. This type is guaranteed to be 32-bit + on all platforms supported by Qt. +*/ + +/*! + \typedef quint32 + \relates <QtTypes> + + Typedef for \c{unsigned int}. This type is guaranteed to + be 32-bit on all platforms supported by Qt. +*/ + +/*! \typedef qint64 + \relates <QtTypes> + + Typedef for \c{long long int}. This type is guaranteed to be 64-bit + on all platforms supported by Qt. + + Literals of this type can be created using the Q_INT64_C() macro: + + \snippet code/src_corelib_global_qglobal.cpp 5 + + \sa Q_INT64_C(), quint64, qlonglong +*/ + +/*! + \typedef quint64 + \relates <QtTypes> + + Typedef for \c{unsigned long long int}. This type is guaranteed to + be 64-bit on all platforms supported by Qt. + + Literals of this type can be created using the Q_UINT64_C() + macro: + + \snippet code/src_corelib_global_qglobal.cpp 6 + + \sa Q_UINT64_C(), qint64, qulonglong +*/ + +/*! + \typedef qintptr + \relates <QtTypes> + + Integral type for representing pointers in a signed integer (useful for + hashing, etc.). + + Typedef for either qint32 or qint64. This type is guaranteed to + be the same size as a pointer on all platforms supported by Qt. On + a system with 32-bit pointers, qintptr is a typedef for qint32; + on a system with 64-bit pointers, qintptr is a typedef for + qint64. + + Note that qintptr is signed. Use quintptr for unsigned values. + + In order to print values of this type by using formatted-output + facilities such as \c{printf()}, qDebug(), QString::asprintf() and + so on, you can use the \c{PRIdQINTPTR} and \c{PRIiQINTPTR} + macros as format specifiers. They will both print the value as a + base 10 number. + + \code + qintptr p = 123; + printf("The pointer is %" PRIdQINTPTR "\n", p); + \endcode + + \sa qptrdiff, qint32, qint64 +*/ + +/*! + \macro PRIdQINTPTR + \macro PRIiQINTPTR + \since 6.2 + \relates <QtTypes> + + See \l qintptr. +*/ + +/*! + \typedef quintptr + \relates <QtTypes> + + Integral type for representing pointers in an unsigned integer (useful for + hashing, etc.). + + Typedef for either quint32 or quint64. This type is guaranteed to + be the same size as a pointer on all platforms supported by Qt. On + a system with 32-bit pointers, quintptr is a typedef for quint32; + on a system with 64-bit pointers, quintptr is a typedef for + quint64. + + Note that quintptr is unsigned. Use qptrdiff for signed values. + + In order to print values of this type by using formatted-output + facilities such as \c{printf()}, qDebug(), QString::asprintf() and + so on, you can use the following macros as format specifiers: + + \list + \li \c{PRIuQUINTPTR}: prints the value as a base 10 number. + \li \c{PRIoQUINTPTR}: prints the value as a base 8 number. + \li \c{PRIxQUINTPTR}: prints the value as a base 16 number, using lowercase \c{a-f} letters. + \li \c{PRIXQUINTPTR}: prints the value as a base 16 number, using uppercase \c{A-F} letters. + \endlist + + \code + quintptr p = 123u; + printf("The pointer value is 0x%" PRIXQUINTPTR "\n", p); + \endcode + + \sa qptrdiff, quint32, quint64 +*/ + +/*! + \macro PRIoQUINTPTR + \macro PRIuQUINTPTR + \macro PRIxQUINTPTR + \macro PRIXQUINTPTR + \since 6.2 + \relates <QtTypes> + + See quintptr. +*/ + +/*! + \typedef qptrdiff + \relates <QtTypes> + + Integral type for representing pointer differences. + + Typedef for either qint32 or qint64. This type is guaranteed to be + the same size as a pointer on all platforms supported by Qt. On a + system with 32-bit pointers, quintptr is a typedef for quint32; on + a system with 64-bit pointers, quintptr is a typedef for quint64. + + Note that qptrdiff is signed. Use quintptr for unsigned values. + + In order to print values of this type by using formatted-output + facilities such as \c{printf()}, qDebug(), QString::asprintf() and + so on, you can use the \c{PRIdQPTRDIFF} and \c{PRIiQPTRDIFF} + macros as format specifiers. They will both print the value as a + base 10 number. + + \code + qptrdiff d = 123; + printf("The difference is %" PRIdQPTRDIFF "\n", d); + \endcode + + \sa quintptr, qint32, qint64 +*/ + +/*! + \macro PRIdQPTRDIFF + \macro PRIiQPTRDIFF + \since 6.2 + \relates <QtTypes> + + See qptrdiff. +*/ + +/*! + \typedef qsizetype + \relates <QtTypes> + \since 5.10 + + Integral type providing Posix' \c ssize_t for all platforms. + + This type is guaranteed to be the same size as a \c size_t on all + platforms supported by Qt. + + Note that qsizetype is signed. Use \c size_t for unsigned values. + + In order to print values of this type by using formatted-output + facilities such as \c{printf()}, qDebug(), QString::asprintf() and + so on, you can use the \c{PRIdQSIZETYPE} and \c{PRIiQSIZETYPE} + macros as format specifiers. They will both print the value as a + base 10 number. + + \code + qsizetype s = 123; + printf("The size is %" PRIdQSIZETYPE "\n", s); + \endcode + + \sa qptrdiff +*/ + +/*! + \macro PRIdQSIZETYPE + \macro PRIiQSIZETYPE + \since 6.2 + \relates <QtTypes> + + See qsizetype. +*/ + +// Statically check assumptions about the environment we're running +// in. The idea here is to error or warn if otherwise implicit Qt +// assumptions are not fulfilled on new hardware or compilers +// (if this list becomes too long, consider factoring into a separate file) +static_assert(UCHAR_MAX == 255, "Qt assumes that char is 8 bits"); +static_assert(sizeof(int) == 4, "Qt assumes that int is 32 bits"); +static_assert(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined incorrectly"); +static_assert(sizeof(float) == 4, "Qt assumes that float is 32 bits"); +static_assert(sizeof(char16_t) == 2, "Qt assumes that char16_t is 16 bits"); +static_assert(sizeof(char32_t) == 4, "Qt assumes that char32_t is 32 bits"); +#if defined(Q_OS_WIN) +static_assert(sizeof(wchar_t) == sizeof(char16_t)); +#endif +static_assert(std::numeric_limits<int>::radix == 2, + "Qt assumes binary integers"); +static_assert((std::numeric_limits<int>::max() + std::numeric_limits<int>::lowest()) == -1, + "Qt assumes two's complement integers"); +static_assert(sizeof(wchar_t) == sizeof(char32_t) || sizeof(wchar_t) == sizeof(char16_t), + "Qt assumes wchar_t is compatible with either char32_t or char16_t"); + +// While we'd like to check for __STDC_IEC_559__, as per ISO/IEC 9899:2011 +// Annex F (C11, normative for C++11), there are a few corner cases regarding +// denormals where GHS compiler is relying hardware behavior that is not IEC +// 559 compliant. So split the check in several subchecks. + +// On GHS the compiler reports std::numeric_limits<float>::is_iec559 as false. +// This is all right according to our needs. +#if !defined(Q_CC_GHS) +static_assert(std::numeric_limits<float>::is_iec559, + "Qt assumes IEEE 754 floating point"); +#endif + +// Technically, presence of NaN and infinities are implied from the above check, +// but double checking our environment doesn't hurt... +static_assert(std::numeric_limits<float>::has_infinity && + std::numeric_limits<float>::has_quiet_NaN, + "Qt assumes IEEE 754 floating point"); + +// is_iec559 checks for ISO/IEC/IEEE 60559:2011 (aka IEEE 754-2008) compliance, +// but that allows for a non-binary radix. We need to recheck that. +// Note how __STDC_IEC_559__ would instead check for IEC 60559:1989, aka +// ANSI/IEEE 754−1985, which specifically implies binary floating point numbers. +static_assert(std::numeric_limits<float>::radix == 2, + "Qt assumes binary IEEE 754 floating point"); + +// not required by the definition of size_t, but we depend on this +static_assert(sizeof(size_t) == sizeof(void *), "size_t and a pointer don't have the same size"); +static_assert(sizeof(size_t) == sizeof(qsizetype)); // implied by the definition +static_assert((std::is_same<qsizetype, qptrdiff>::value)); + +// Check that our own typedefs are not broken. +static_assert(sizeof(qint8) == 1, "Internal error, qint8 is misdefined"); +static_assert(sizeof(qint16)== 2, "Internal error, qint16 is misdefined"); +static_assert(sizeof(qint32) == 4, "Internal error, qint32 is misdefined"); +static_assert(sizeof(qint64) == 8, "Internal error, qint64 is misdefined"); + +QT_END_NAMESPACE diff --git a/src/corelib/global/qtypes.h b/src/corelib/global/qtypes.h new file mode 100644 index 0000000000..f7757b4311 --- /dev/null +++ b/src/corelib/global/qtypes.h @@ -0,0 +1,163 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// Copyright (C) 2022 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QTYPES_H +#define QTYPES_H + +#include <QtCore/qprocessordetection.h> +#include <QtCore/qtconfigmacros.h> + +#ifdef __cplusplus +# include <cstddef> +# include <cstdint> +#endif + +#if 0 +#pragma qt_class(QtTypes) +#pragma qt_class(QIntegerForSize) +#pragma qt_sync_stop_processing +#endif + +#ifndef __ASSEMBLER__ + +/* + Useful type definitions for Qt +*/ +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +QT_BEGIN_NAMESPACE + +/* + Size-dependent types (architecture-dependent byte order) + + Make sure to update QMetaType when changing these typedefs +*/ + +typedef signed char qint8; /* 8 bit signed */ +typedef unsigned char quint8; /* 8 bit unsigned */ +typedef short qint16; /* 16 bit signed */ +typedef unsigned short quint16; /* 16 bit unsigned */ +typedef int qint32; /* 32 bit signed */ +typedef unsigned int quint32; /* 32 bit unsigned */ +// Unlike LL / ULL in C++, for historical reasons, we force the +// result to be of the requested type. +#ifdef __cplusplus +# define Q_INT64_C(c) static_cast<long long>(c ## LL) /* signed 64 bit constant */ +# define Q_UINT64_C(c) static_cast<unsigned long long>(c ## ULL) /* unsigned 64 bit constant */ +#else +# define Q_INT64_C(c) ((long long)(c ## LL)) /* signed 64 bit constant */ +# define Q_UINT64_C(c) ((unsigned long long)(c ## ULL)) /* unsigned 64 bit constant */ +#endif +typedef long long qint64; /* 64 bit signed */ +typedef unsigned long long quint64; /* 64 bit unsigned */ + +typedef qint64 qlonglong; +typedef quint64 qulonglong; + +#ifndef __cplusplus +// In C++ mode, we define below using QIntegerForSize template +Q_STATIC_ASSERT_X(sizeof(ptrdiff_t) == sizeof(size_t), "Weird ptrdiff_t and size_t definitions"); +typedef ptrdiff_t qptrdiff; +typedef ptrdiff_t qsizetype; +typedef ptrdiff_t qintptr; +typedef size_t quintptr; + +#define PRIdQPTRDIFF "td" +#define PRIiQPTRDIFF "ti" + +#define PRIdQSIZETYPE "td" +#define PRIiQSIZETYPE "ti" + +#define PRIdQINTPTR "td" +#define PRIiQINTPTR "ti" + +#define PRIuQUINTPTR "zu" +#define PRIoQUINTPTR "zo" +#define PRIxQUINTPTR "zx" +#define PRIXQUINTPTR "zX" +#endif + +#if defined(QT_COORD_TYPE) +typedef QT_COORD_TYPE qreal; +#else +typedef double qreal; +#endif + +#if defined(__cplusplus) +/* + quintptr are qptrdiff is guaranteed to be the same size as a pointer, i.e. + + sizeof(void *) == sizeof(quintptr) + && sizeof(void *) == sizeof(qptrdiff) + + While size_t and qsizetype are not guaranteed to be the same size as a pointer, + they usually are and we do check for that in qtypes.cpp, just to be sure. +*/ +template <int> struct QIntegerForSize; +template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qint8 Signed; }; +template <> struct QIntegerForSize<2> { typedef quint16 Unsigned; typedef qint16 Signed; }; +template <> struct QIntegerForSize<4> { typedef quint32 Unsigned; typedef qint32 Signed; }; +template <> struct QIntegerForSize<8> { typedef quint64 Unsigned; typedef qint64 Signed; }; +#if defined(Q_CC_GNU) && defined(__SIZEOF_INT128__) +template <> struct QIntegerForSize<16> { __extension__ typedef unsigned __int128 Unsigned; __extension__ typedef __int128 Signed; }; +#endif +template <class T> struct QIntegerForSizeof: QIntegerForSize<sizeof(T)> { }; +typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Signed qregisterint; +typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Unsigned qregisteruint; +typedef QIntegerForSizeof<void *>::Unsigned quintptr; +typedef QIntegerForSizeof<void *>::Signed qptrdiff; +typedef qptrdiff qintptr; +using qsizetype = QIntegerForSizeof<std::size_t>::Signed; + +// These custom definitions are necessary as we're not defining our +// datatypes in terms of the language ones, but in terms of integer +// types that have the sime size. For instance, on a 32-bit platform, +// qptrdiff is int, while ptrdiff_t may be aliased to long; therefore +// using %td to print a qptrdiff would be wrong (and raise -Wformat +// warnings), although both int and long have same bit size on that +// platform. +// +// We know that sizeof(size_t) == sizeof(void *) == sizeof(qptrdiff). +#if SIZE_MAX == 0xffffffffULL +#define PRIuQUINTPTR "u" +#define PRIoQUINTPTR "o" +#define PRIxQUINTPTR "x" +#define PRIXQUINTPTR "X" + +#define PRIdQPTRDIFF "d" +#define PRIiQPTRDIFF "i" + +#define PRIdQINTPTR "d" +#define PRIiQINTPTR "i" + +#define PRIdQSIZETYPE "d" +#define PRIiQSIZETYPE "i" +#elif SIZE_MAX == 0xffffffffffffffffULL +#define PRIuQUINTPTR "llu" +#define PRIoQUINTPTR "llo" +#define PRIxQUINTPTR "llx" +#define PRIXQUINTPTR "llX" + +#define PRIdQPTRDIFF "lld" +#define PRIiQPTRDIFF "lli" + +#define PRIdQINTPTR "lld" +#define PRIiQINTPTR "lli" + +#define PRIdQSIZETYPE "lld" +#define PRIiQSIZETYPE "lli" +#else +#error Unsupported platform (unknown value for SIZE_MAX) +#endif + +#endif // __cplusplus + +QT_END_NAMESPACE + +#endif // __ASSEMBLER__ + +#endif // QTYPES_H |