Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtypes.h
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2022 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QTYPES_H
6#define QTYPES_H
7
8#include <QtCore/qprocessordetection.h>
9#include <QtCore/qsystemdetection.h>
10#include <QtCore/qtconfigmacros.h>
11#include <QtCore/qassert.h>
12
13#ifdef __cplusplus
14# include <cstddef>
15# if defined(_HAS_STD_BYTE) && _HAS_STD_BYTE == 0
16# error "Qt requires std::byte, but _HAS_STD_BYTE has been set to 0"
17# endif
18# include <cstdint>
19# if defined(__STDCPP_FLOAT16_T__) && __has_include(<stdfloat>)
20// P1467 implementation - https://wg21.link/p1467
21# include <stdfloat>
22# endif // defined(__STDCPP_FLOAT16_T__) && __has_include(<stdfloat>)
23# include <type_traits>
24#else
25# include <assert.h>
26#endif
27
28#if 0
29#pragma qt_class(QtTypes)
30#pragma qt_class(QIntegerForSize)
31#pragma qt_sync_stop_processing
32#endif
33
34/*
35 Useful type definitions for Qt
36*/
37typedef unsigned char uchar;
38typedef unsigned short ushort;
39typedef unsigned int uint;
40typedef unsigned long ulong;
41
43
44/*
45 Size-dependent types (architecture-dependent byte order)
46
47 Make sure to update QMetaType when changing these typedefs
48*/
49
50typedef signed char qint8; /* 8 bit signed */
51typedef unsigned char quint8; /* 8 bit unsigned */
52typedef short qint16; /* 16 bit signed */
53typedef unsigned short quint16; /* 16 bit unsigned */
54typedef int qint32; /* 32 bit signed */
55typedef unsigned int quint32; /* 32 bit unsigned */
56// Unlike LL / ULL in C++, for historical reasons, we force the
57// result to be of the requested type.
58#ifdef __cplusplus
59# define Q_INT64_C(c) static_cast<long long>(c ## LL) /* signed 64 bit constant */
60# define Q_UINT64_C(c) static_cast<unsigned long long>(c ## ULL) /* unsigned 64 bit constant */
61#else
62# define Q_INT64_C(c) ((long long)(c ## LL)) /* signed 64 bit constant */
63# define Q_UINT64_C(c) ((unsigned long long)(c ## ULL)) /* unsigned 64 bit constant */
64#endif
65typedef long long qint64; /* 64 bit signed */
66typedef unsigned long long quint64; /* 64 bit unsigned */
67
70
71#ifdef Q_QDOC // QDoc always needs to see the typedefs
72# define QT_SUPPORTS_INT128 16
73#elif defined(QT_COMPILER_SUPPORTS_INT128) && !defined(QT_NO_INT128)
74# define QT_SUPPORTS_INT128 QT_COMPILER_SUPPORTS_INT128
75# if defined(__GLIBCXX__) && defined(__STRICT_ANSI__) // -ansi/-std=c++NN instead of gnu++NN
76# undef QT_SUPPORTS_INT128 // breaks <type_traits> on libstdc++
77# endif
78# if defined(__clang__) && defined(_MSVC_STL_VERSION) // Clang with MSVC's STL
79# undef QT_SUPPORTS_INT128 // MSVC's STL doesn't support int128
80# endif
81#else
82# undef QT_SUPPORTS_INT128
83#endif
84
85#if defined(QT_SUPPORTS_INT128)
86__extension__ typedef __int128_t qint128;
87__extension__ typedef __uint128_t quint128;
88
89#ifdef __cplusplus
90static_assert(std::is_signed_v<qint128>,
91 "Qt requires <type_traits> and <limits> to work for q(u)int128.");
92#endif
93
94// limits:
95# ifdef __cplusplus /* need to avoid c-style-casts in C++ mode */
96# define QT_C_STYLE_CAST(type, x) static_cast<type>(x)
97# else /* but C doesn't have constructor-style casts */
98# define QT_C_STYLE_CAST(type, x) ((type)(x))
99# endif
100# ifndef Q_UINT128_MAX /* allow qcompilerdetection.h/user override */
101# define Q_UINT128_MAX QT_C_STYLE_CAST(quint128, -1)
102# endif
103# define Q_INT128_MAX QT_C_STYLE_CAST(qint128, Q_UINT128_MAX / 2)
104# define Q_INT128_MIN (-Q_INT128_MAX - 1)
105
106# ifdef __cplusplus
107 namespace QtPrivate::NumberLiterals {
108 namespace detail {
109 template <quint128 accu, int base>
110 constexpr quint128 construct() { return accu; }
111
112 template <quint128 accu, int base, char C, char...Cs>
113 constexpr quint128 construct()
114 {
115 if constexpr (C != '\'') { // ignore digit separators
116 const int digitValue = '0' <= C && C <= '9' ? C - '0' :
117 'a' <= C && C <= 'z' ? C - 'a' + 10 :
118 'A' <= C && C <= 'Z' ? C - 'A' + 10 :
119 /* else */ -1 ;
120 static_assert(digitValue >= 0 && digitValue < base,
121 "Invalid character");
122 // accu * base + digitValue <= MAX, but without overflow:
123 static_assert(accu <= (Q_UINT128_MAX - digitValue) / base,
124 "Overflow occurred");
125 return construct<accu * base + digitValue, base, Cs...>();
126 } else {
127 return construct<accu, base, Cs...>();
128 }
129 }
130
131 template <char C, char...Cs>
132 constexpr quint128 parse0xb()
133 {
134 constexpr quint128 accu = 0;
135 if constexpr (C == 'x' || C == 'X')
136 return construct<accu, 16, Cs...>(); // base 16, skip 'x'
137 else if constexpr (C == 'b' || C == 'B')
138 return construct<accu, 2, Cs...>(); // base 2, skip 'b'
139 else
140 return construct<accu, 8, C, Cs...>(); // base 8, include C
141 }
142
143 template <char...Cs>
144 constexpr quint128 parse0()
145 {
146 if constexpr (sizeof...(Cs) == 0) // this was just a literal 0
147 return 0;
148 else
149 return parse0xb<Cs...>();
150 }
151
152 template <char C, char...Cs>
153 constexpr quint128 parse()
154 {
155 if constexpr (C == '0')
156 return parse0<Cs...>(); // base 2, 8, or 16 (or just a literal 0), skip '0'
157 else
158 return construct<0, 10, C, Cs...>(); // initial accu 0, base 10, include C
159 }
160 } // namespace detail
161 template <char...Cs>
162 constexpr quint128 operator""_quint128() noexcept
163 { return QtPrivate::NumberLiterals::detail::parse<Cs...>(); }
164 template <char...Cs>
165 constexpr qint128 operator""_qint128() noexcept
166 { return qint128(QtPrivate::NumberLiterals::detail::parse<Cs...>()); }
167
168 #ifndef Q_UINT128_C // allow qcompilerdetection.h/user override
169 # define Q_UINT128_C(c) ([]{ using namespace QtPrivate::NumberLiterals; return c ## _quint128; }())
170 #endif
171 #ifndef Q_INT128_C // allow qcompilerdetection.h/user override
172 # define Q_INT128_C(c) ([]{ using namespace QtPrivate::NumberLiterals; return c ## _qint128; }())
173 #endif
174
175 } // namespace QtPrivate::NumberLiterals
176# endif // __cplusplus
177#endif // QT_SUPPORTS_INT128
178
179#ifndef __cplusplus
180// In C++ mode, we define below using QIntegerForSize template
181static_assert(sizeof(ptrdiff_t) == sizeof(size_t), "Weird ptrdiff_t and size_t definitions");
182typedef ptrdiff_t qptrdiff;
183typedef ptrdiff_t qsizetype;
184typedef ptrdiff_t qintptr;
185typedef size_t quintptr;
186
187#define PRIdQPTRDIFF "td"
188#define PRIiQPTRDIFF "ti"
189
190#define PRIdQSIZETYPE "td"
191#define PRIiQSIZETYPE "ti"
192
193#define PRIdQINTPTR "td"
194#define PRIiQINTPTR "ti"
195
196#define PRIuQUINTPTR "zu"
197#define PRIoQUINTPTR "zo"
198#define PRIxQUINTPTR "zx"
199#define PRIXQUINTPTR "zX"
200#endif
201
202#if defined(QT_COORD_TYPE)
203typedef QT_COORD_TYPE qreal;
204#else
205typedef double qreal;
206#endif
207
208#if defined(__cplusplus)
209/*
210 quintptr and qptrdiff are guaranteed to be the same size as a pointer, i.e.
211
212 sizeof(void *) == sizeof(quintptr)
213 && sizeof(void *) == sizeof(qptrdiff)
214
215 While size_t and qsizetype are not guaranteed to be the same size as a pointer,
216 they usually are and we do check for that in qtypes.cpp, just to be sure.
217*/
218template <int> struct QIntegerForSize;
219template <> struct QIntegerForSize<1> { typedef quint8 Unsigned; typedef qint8 Signed; };
220template <> struct QIntegerForSize<2> { typedef quint16 Unsigned; typedef qint16 Signed; };
221template <> struct QIntegerForSize<4> { typedef quint32 Unsigned; typedef qint32 Signed; };
222template <> struct QIntegerForSize<8> { typedef quint64 Unsigned; typedef qint64 Signed; };
223#if defined(QT_SUPPORTS_INT128)
224template <> struct QIntegerForSize<16> { typedef quint128 Unsigned; typedef qint128 Signed; };
225#endif
226template <class T> struct QIntegerForSizeof: QIntegerForSize<sizeof(T)> { };
227typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Signed qregisterint;
228typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Unsigned qregisteruint;
229typedef QIntegerForSizeof<void *>::Unsigned quintptr;
230typedef QIntegerForSizeof<void *>::Signed qptrdiff;
231typedef qptrdiff qintptr;
232using qsizetype = QIntegerForSizeof<std::size_t>::Signed;
233
234// These custom definitions are necessary as we're not defining our
235// datatypes in terms of the language ones, but in terms of integer
236// types that have the sime size. For instance, on a 32-bit platform,
237// qptrdiff is int, while ptrdiff_t may be aliased to long; therefore
238// using %td to print a qptrdiff would be wrong (and raise -Wformat
239// warnings), although both int and long have same bit size on that
240// platform.
241//
242// We know that sizeof(size_t) == sizeof(void *) == sizeof(qptrdiff).
243#if SIZE_MAX == 0xffffffffULL
244#define PRIuQUINTPTR "u"
245#define PRIoQUINTPTR "o"
246#define PRIxQUINTPTR "x"
247#define PRIXQUINTPTR "X"
248
249#define PRIdQPTRDIFF "d"
250#define PRIiQPTRDIFF "i"
251
252#define PRIdQINTPTR "d"
253#define PRIiQINTPTR "i"
254
255#define PRIdQSIZETYPE "d"
256#define PRIiQSIZETYPE "i"
257#elif SIZE_MAX == 0xffffffffffffffffULL
258#define PRIuQUINTPTR "llu"
259#define PRIoQUINTPTR "llo"
260#define PRIxQUINTPTR "llx"
261#define PRIXQUINTPTR "llX"
262
263#define PRIdQPTRDIFF "lld"
264#define PRIiQPTRDIFF "lli"
265
266#define PRIdQINTPTR "lld"
267#define PRIiQINTPTR "lli"
268
269#define PRIdQSIZETYPE "lld"
270#define PRIiQSIZETYPE "lli"
271#else
272#error Unsupported platform (unknown value for SIZE_MAX)
273#endif
274
275// Define a native float16 type
276namespace QtPrivate {
277#if defined(__STDCPP_FLOAT16_T__)
278# define QFLOAT16_IS_NATIVE 1
280#elif defined(Q_CC_CLANG) && defined(__FLT16_MAX__) && 0
281// disabled due to https://github.com/llvm/llvm-project/issues/56963
282# define QFLOAT16_IS_NATIVE 1
283using NativeFloat16Type = decltype(__FLT16_MAX__);
284#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) && defined(__ARM_FP16_FORMAT_IEEE)
285# define QFLOAT16_IS_NATIVE 1
286using NativeFloat16Type = __fp16;
287#elif defined(Q_CC_GNU_ONLY) && defined(__FLT16_MAX__) && defined(__SSE2__)
288# define QFLOAT16_IS_NATIVE 1
289using NativeFloat16Type = _Float16;
290#else
291# define QFLOAT16_IS_NATIVE 0
292using NativeFloat16Type = void;
293#endif
294} // QtPrivate
295
296#endif // __cplusplus
297
298QT_END_NAMESPACE
299
300#endif // QTYPES_H
\macro QT_NO_KEYWORDS >
Definition qcompare.h:24
#define __has_include(x)
unsigned int quint32
Definition qtypes.h:55
unsigned int uint
Definition qtypes.h:39
unsigned char uchar
Definition qtypes.h:37
short qint16
Definition qtypes.h:52
unsigned short quint16
Definition qtypes.h:53
int qint32
Definition qtypes.h:54
unsigned long ulong
Definition qtypes.h:40
quint64 qulonglong
Definition qtypes.h:69
unsigned long long quint64
Definition qtypes.h:66
long long qint64
Definition qtypes.h:65
unsigned short ushort
Definition qtypes.h:38
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition qtypes.h:50
double qreal
Definition qtypes.h:205
unsigned char quint8
Definition qtypes.h:51
qint64 qlonglong
Definition qtypes.h:68