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