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

source code of qtbase/src/corelib/global/qtypes.h