7#ifndef QVERSIONNUMBER_H
8#define QVERSIONNUMBER_H
10#include <QtCore/qcompare.h>
11#include <QtCore/qcontainertools_impl.h>
12#include <QtCore/qlist.h>
13#include <QtCore/qmetatype.h>
14#include <QtCore/qnamespace.h>
15#include <QtCore/qspan.h>
16#include <QtCore/qstring.h>
17#include <QtCore/qtypeinfo.h>
18#if !defined(QT_LEAN_HEADERS) || QT_LEAN_HEADERS < 2
19#include <QtCore/qtyperevision.h>
25Q_CORE_EXPORT size_t qHash(
const QVersionNumber &key, size_t seed = 0);
27#ifndef QT_NO_DATASTREAM
35
36
37
38
39
40
44 InlineSegmentMarker = Q_BYTE_ORDER == Q_LITTLE_ENDIAN ? 0 :
sizeof(
void *) - 1,
45 InlineSegmentStartIdx = !InlineSegmentMarker,
46 InlineSegmentCount =
sizeof(
void *) - 1
48 static_assert(InlineSegmentCount >= 3);
57 qint8 inline_segments[
sizeof(
void *)];
58 QList<
int> *pointer_segments;
62 SegmentStorage()
noexcept : dummy(1) {}
64 SegmentStorage(
const QList<
int> &seg)
66 if (dataFitsInline(seg.data(), seg.size()))
67 setInlineData(seg.data(), seg.size());
72 Q_CORE_EXPORT
void setListData(
const QList<
int> &seg);
74 SegmentStorage(
const SegmentStorage &other)
76 if (other.isUsingPointer())
77 setListData(*other.pointer_segments);
82 SegmentStorage &operator=(
const SegmentStorage &other)
84 if (isUsingPointer() && other.isUsingPointer()) {
85 *pointer_segments = *other.pointer_segments;
86 }
else if (other.isUsingPointer()) {
87 setListData(*other.pointer_segments);
90 delete pointer_segments;
96 SegmentStorage(SegmentStorage &&other)
noexcept
102 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(SegmentStorage)
104 void swap(SegmentStorage &other)
noexcept
106 std::swap(dummy, other.dummy);
109 explicit SegmentStorage(QList<
int> &&seg)
111 if (dataFitsInline(std::as_const(seg).data(), seg.size()))
112 setInlineData(std::as_const(seg).data(), seg.size());
114 setListData(std::move(seg));
119 explicit SegmentStorage(QSpan<
const int> args)
133 ~SegmentStorage() {
if (isUsingPointer())
delete pointer_segments; }
135 bool isUsingPointer()
const noexcept
136 {
return (inline_segments[InlineSegmentMarker] & 1) == 0; }
138 qsizetype size()
const noexcept
139 {
return isUsingPointer() ? pointer_segments->size() : (inline_segments[InlineSegmentMarker] >> 1); }
141 void setInlineSize(qsizetype len)
143 Q_ASSERT(len <= InlineSegmentCount);
144 inline_segments[InlineSegmentMarker] = qint8(1 + 2 * len);
147 Q_CORE_EXPORT
void resize(qsizetype len);
149 int at(qsizetype index)
const
151 return isUsingPointer() ?
152 pointer_segments->at(index) :
153 inline_segments[InlineSegmentStartIdx + index];
156 void setSegments(
int len,
int maj,
int min = 0,
int mic = 0)
158 if (maj == qint8(maj) && min == qint8(min) && mic == qint8(mic)) {
159 int data[] = { maj, min, mic };
160 setInlineData(data, len);
162 setVector(len, maj, min, mic);
167 static bool dataFitsInline(
const int *data, qsizetype len)
169 if (len > InlineSegmentCount)
171 for (qsizetype i = 0; i < len; ++i)
172 if (data[i] != qint8(data[i]))
176 void setInlineData(
const int *data, qsizetype len)
178 Q_ASSERT(len <= InlineSegmentCount);
180#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
181 for (qsizetype i = 0; i < len; ++i)
182 dummy |= quintptr(data[i] & 0xFF) << (8 * (i + 1));
183#elif Q_BYTE_ORDER == Q_BIG_ENDIAN
184 for (qsizetype i = 0; i < len; ++i)
185 dummy |= quintptr(data[i] & 0xFF) << (8 * (
sizeof(
void *) - i - 1));
189 for (qsizetype i = 0; i < len; ++i)
190 inline_segments[InlineSegmentStartIdx + i] = data[i] & 0xFF;
194 Q_CORE_EXPORT
void setVector(
int len,
int maj,
int min,
int mic);
204 friend class QVersionNumber;
205 explicit constexpr It(
const QVersionNumber *vn, qsizetype idx)
noexcept : v(vn), i(idx) {}
207 friend constexpr bool comparesEqual(
const It &lhs,
const It &rhs)
208 { Q_ASSERT(lhs.v == rhs.v);
return lhs.i == rhs.i; }
209 friend constexpr Qt::strong_ordering compareThreeWay(
const It &lhs,
const It &rhs)
210 { Q_ASSERT(lhs.v == rhs.v);
return Qt::compareThreeWay(lhs.i, rhs.i); }
212 friend constexpr bool operator==(It lhs, It rhs) {
213 return comparesEqual(lhs, rhs);
215#ifdef __cpp_lib_three_way_comparison
216 friend constexpr std::strong_ordering operator<=>(It lhs, It rhs) {
217 return compareThreeWay(lhs, rhs);
220 friend constexpr bool operator!=(It lhs, It rhs) {
221 return !operator==(lhs, rhs);
223 friend constexpr bool operator<(It lhs, It rhs) {
224 return is_lt(compareThreeWay(lhs, rhs));
226 friend constexpr bool operator<=(It lhs, It rhs) {
227 return is_lteq(compareThreeWay(lhs, rhs));
229 friend constexpr bool operator>(It lhs, It rhs) {
230 return is_gt(compareThreeWay(lhs, rhs));
232 friend constexpr bool operator>=(It lhs, It rhs) {
233 return is_gteq(compareThreeWay(lhs, rhs));
241 using iterator_category = std::random_access_iterator_tag;
242 using value_type =
int;
243#ifdef QT_COMPILER_HAS_LWG3346
244 using element_type =
const int;
246 using difference_type = qptrdiff;
247 using size_type = qsizetype;
248 using reference = value_type;
249 using pointer = QtPrivate::ArrowProxy<reference>;
251 reference operator*()
const {
return v->segmentAt(i); }
252 pointer operator->()
const {
return {**
this}; }
254 It &operator++() { ++i;
return *
this; }
255 It operator++(
int) {
auto copy = *
this; ++*
this;
return copy; }
257 It &operator--() { --i;
return *
this; }
258 It operator--(
int) {
auto copy = *
this; --*
this;
return copy; }
260 It &operator+=(difference_type n) { i += n;
return *
this; }
261 friend It operator+(It it, difference_type n) { it += n;
return it; }
262 friend It operator+(difference_type n, It it) {
return it + n; }
264 It &operator-=(difference_type n) { i -= n;
return *
this; }
265 friend It operator-(It it, difference_type n) { it -= n;
return it; }
267 friend difference_type operator-(It lhs, It rhs)
268 { Q_ASSERT(lhs.v == rhs.v);
return lhs.i - rhs.i; }
270 reference operator[](difference_type n)
const {
return *(*
this + n); }
274 using const_iterator = It;
275 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
278 using difference_type = It::difference_type;
279 using size_type = It::size_type;
282 using pointer = It::pointer;
283 using const_pointer = pointer;
285 inline QVersionNumber()
noexcept
296 inline QVersionNumber(std::initializer_list<
int> args)
297 : m_segments(QSpan{args})
300 explicit QVersionNumber(QSpan<
const int> args)
304 inline explicit QVersionNumber(
int maj)
305 { m_segments.setSegments(1, maj); }
307 inline explicit QVersionNumber(
int maj,
int min)
308 { m_segments.setSegments(2, maj, min); }
310 inline explicit QVersionNumber(
int maj,
int min,
int mic)
311 { m_segments.setSegments(3, maj, min, mic); }
313 [[nodiscard]]
inline bool isNull()
const noexcept
314 {
return segmentCount() == 0; }
317 {
return isNull() || segmentAt(segmentCount() - 1) != 0; }
320 {
return segmentAt(0); }
323 {
return segmentAt(1); }
326 {
return segmentAt(2); }
328 [[nodiscard]] Q_CORE_EXPORT QVersionNumber normalized()
const;
330 [[nodiscard]] Q_CORE_EXPORT QList<
int> segments()
const;
332 [[nodiscard]]
inline int segmentAt(qsizetype index)
const noexcept
333 {
return (m_segments.size() > index) ? m_segments.at(index) : 0; }
336 {
return m_segments.size(); }
355 [[nodiscard]] Q_CORE_EXPORT
static QVersionNumber commonPrefix(
const QVersionNumber &v1,
const QVersionNumber &v2);
358 [[nodiscard]] Q_CORE_EXPORT
static QVersionNumber fromString(QAnyStringView string, qsizetype *suffixIndex =
nullptr);
360#if QT_DEPRECATED_SINCE(6
, 4
) && QT_POINTER_SIZE != 4
362 QT_DEPRECATED_VERSION_X_6_4(
"Use the 'qsizetype *suffixIndex' overload.")
363 [[nodiscard]]
static QVersionNumber fromString(QAnyStringView string,
int *suffixIndex)
367 QT_WARNING_DISABLE_GCC(
"-Wmaybe-uninitialized")
369 auto r = fromString(string, &n);
371 Q_ASSERT(
int(n) == n);
372 *suffixIndex =
int(n);
380#if QT_CORE_REMOVED_SINCE(6
, 4
)
381 [[nodiscard]] Q_CORE_EXPORT
static QVersionNumber fromString(
const QString &string,
int *suffixIndex);
382 [[nodiscard]] Q_CORE_EXPORT
static QVersionNumber fromString(QLatin1StringView string,
int *suffixIndex);
383 [[nodiscard]] Q_CORE_EXPORT
static QVersionNumber fromString(QStringView string,
int *suffixIndex);
387 [[nodiscard]]
friend bool comparesEqual(
const QVersionNumber &lhs,
388 const QVersionNumber &rhs)
noexcept
390 return lhs.segmentCount() == rhs.segmentCount() && compare(lhs, rhs) == 0;
395 int c = compare(lhs, rhs);
396 return Qt::compareThreeWay(c, 0);
398 Q_DECLARE_STRONGLY_ORDERED(QVersionNumber)
400#ifndef QT_NO_DATASTREAM
403 friend Q_CORE_EXPORT size_t qHash(
const QVersionNumber &key, size_t seed);
409#ifndef QT_NO_DEBUG_STREAM
415QT_DECL_METATYPE_EXTERN(QVersionNumber, Q_CORE_EXPORT)
\inmodule QtCore\reentrant
constexpr int segmentCount() const
QVersionNumber version() const
friend bool operator<=(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
friend bool operator<(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
QOperatingSystemVersionBase()=default
friend bool operator>=(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
constexpr QOperatingSystemVersionBase(OSType osType, int vmajor, int vminor=-1, int vmicro=-1)
bool isAnyOfType(std::initializer_list< OSType > types) const
constexpr int majorVersion() const
static Q_CORE_EXPORT bool isAnyOfType(std::initializer_list< OSType > types, OSType type)
constexpr int minorVersion() const
constexpr int microVersion() const
friend bool operator>(QOperatingSystemVersionBase lhs, QOperatingSystemVersionBase rhs) noexcept
friend Qt::partial_ordering compareThreeWay(const QOperatingSystemVersionBase &lhs, const QOperatingSystemVersionBase &rhs) noexcept
static constexpr OSType currentType()
constexpr OSType type() const
static Q_CORE_EXPORT int compare(QOperatingSystemVersionBase v1, QOperatingSystemVersionBase v2) noexcept
static constexpr QOperatingSystemVersionBase MacOSSequoia
static constexpr QOperatingSystemVersionBase MacOSTahoe
static constexpr QOperatingSystemVersionBase Windows11_21H2
\variable QOperatingSystemVersion::Windows11_21H2
static constexpr QOperatingSystemVersionBase AndroidNougat
\variable QOperatingSystemVersion::AndroidNougat
static constexpr QOperatingSystemVersionBase Android10
\variable QOperatingSystemVersion::Android10
static constexpr QOperatingSystemVersionBase MacOSSierra
\variable QOperatingSystemVersion::MacOSSierra
static constexpr QOperatingSystemVersionBase MacOSGoldenGate
static constexpr QOperatingSystemVersionBase OSXYosemite
\variable QOperatingSystemVersion::OSXYosemite
static constexpr QOperatingSystemVersionBase Android12L
\variable QOperatingSystemVersion::Android12L
static constexpr QOperatingSystemVersionBase Windows10_1909
\variable QOperatingSystemVersion::Windows10_1909
static constexpr QOperatingSystemVersionBase AndroidKitKat
\variable QOperatingSystemVersion::AndroidKitKat
static constexpr QOperatingSystemVersionBase AndroidJellyBean
\variable QOperatingSystemVersion::MacOSSonoma
static constexpr QOperatingSystemVersionBase AndroidOreo_MR1
\variable QOperatingSystemVersion::AndroidOreo_MR1
static constexpr QOperatingSystemVersionBase Android13
\variable QOperatingSystemVersion::Android13
static constexpr QOperatingSystemVersionBase MacOSCatalina
\variable QOperatingSystemVersion::MacOSCatalina
static constexpr QOperatingSystemVersionBase AndroidLollipop_MR1
\variable QOperatingSystemVersion::AndroidLollipop_MR1
static constexpr QOperatingSystemVersionBase Windows10
\variable QOperatingSystemVersion::Windows10
static constexpr QOperatingSystemVersionBase Windows10_1903
\variable QOperatingSystemVersion::Windows10_1903
static constexpr QOperatingSystemVersionBase Android12
\variable QOperatingSystemVersion::Android12
static constexpr OSType currentType()
Returns the current OS type without constructing a QOperatingSystemVersion instance.
static constexpr QOperatingSystemVersionBase Windows11_23H2
static constexpr QOperatingSystemVersionBase OSXElCapitan
\variable QOperatingSystemVersion::OSXElCapitan
static constexpr QOperatingSystemVersionBase MacOSMojave
\variable QOperatingSystemVersion::MacOSMojave
static constexpr QOperatingSystemVersionBase Windows8
\variable QOperatingSystemVersion::Windows8
static constexpr QOperatingSystemVersionBase AndroidNougat_MR1
\variable QOperatingSystemVersion::AndroidNougat_MR1
static constexpr QOperatingSystemVersionBase Android14
static constexpr QOperatingSystemVersionBase Windows10_2004
\variable QOperatingSystemVersion::Windows10_2004
static constexpr QOperatingSystemVersionBase MacOSHighSierra
\variable QOperatingSystemVersion::MacOSHighSierra
static constexpr QOperatingSystemVersionBase Windows10_21H2
\variable QOperatingSystemVersion::Windows10_21H2
constexpr QOperatingSystemVersion(const QOperatingSystemVersionBase &osversion)
static constexpr QOperatingSystemVersionBase AndroidMarshmallow
\variable QOperatingSystemVersion::AndroidMarshmallow
constexpr QOperatingSystemVersion(OSType osType, int vmajor, int vminor=-1, int vmicro=-1)
Constructs a QOperatingSystemVersion consisting of the OS type osType, and major, minor,...
static constexpr QOperatingSystemVersionBase AndroidJellyBean_MR2
\variable QOperatingSystemVersion::AndroidJellyBean_MR2
static constexpr QOperatingSystemVersionBase Windows10_20H2
\variable QOperatingSystemVersion::Windows10_20H2
static constexpr QOperatingSystemVersionBase AndroidPie
\variable QOperatingSystemVersion::AndroidPie
static constexpr QOperatingSystemVersionBase AndroidOreo
\variable QOperatingSystemVersion::AndroidOreo
static QOperatingSystemVersion current()
Returns a QOperatingSystemVersion indicating the current OS and its version number.
static constexpr QOperatingSystemVersionBase OSXMavericks
\variable QOperatingSystemVersion::Windows11_23H2
static constexpr QOperatingSystemVersionBase MacOSMonterey
\variable QOperatingSystemVersion::MacOSMonterey
static constexpr QOperatingSystemVersionBase Windows7
\variable QOperatingSystemVersion::Windows7
static constexpr QOperatingSystemVersionBase MacOSVentura
\variable QOperatingSystemVersion::MacOSVentura
static constexpr QOperatingSystemVersionBase Windows10_1809
\variable QOperatingSystemVersion::Windows10_1809
static constexpr QOperatingSystemVersionBase AndroidJellyBean_MR1
\variable QOperatingSystemVersion::AndroidJellyBean_MR1
static constexpr QOperatingSystemVersionBase MacOSBigSur
\variable QOperatingSystemVersion::MacOSBigSur
constexpr OSType type() const
Returns the OS type identified by the QOperatingSystemVersion.
static constexpr QOperatingSystemVersionBase AndroidLollipop
\variable QOperatingSystemVersion::AndroidLollipop
static constexpr QOperatingSystemVersionBase Windows8_1
\variable QOperatingSystemVersion::Windows8_1
static constexpr QOperatingSystemVersionBase Windows11_24H2
static constexpr QOperatingSystemVersionBase Windows11_25H2
static constexpr QOperatingSystemVersionBase Windows10_21H1
\variable QOperatingSystemVersion::Windows10_21H1
static constexpr QOperatingSystemVersionBase Windows11_22H2
\variable QOperatingSystemVersion::Windows11_22H2
static constexpr QOperatingSystemVersionBase Windows10_22H2
\variable QOperatingSystemVersion::Windows10_22H2
static constexpr QOperatingSystemVersionBase Android11
\variable QOperatingSystemVersion::Android11
static constexpr QOperatingSystemVersionBase MacOSSonoma
static constexpr QOperatingSystemVersionBase Windows11
\variable QOperatingSystemVersion::Windows11
\macro QT_RESTRICTED_CAST_FROM_ASCII
Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const noexcept
Returns true if the current version number is contained in the other version number,...
const_reverse_iterator crbegin() const noexcept
const_iterator cbegin() const noexcept
bool isNull() const noexcept
Returns true if there are zero numerical segments, otherwise returns false.
int minorVersion() const noexcept
Returns the minor version number, that is, the second segment.
friend Qt::strong_ordering compareThreeWay(const QVersionNumber &lhs, const QVersionNumber &rhs) noexcept
int majorVersion() const noexcept
Returns the major version number, that is, the first segment.
const_iterator end() const noexcept
const_iterator constEnd() const noexcept
It::value_type value_type
const_reverse_iterator crend() const noexcept
const_reverse_iterator rbegin() const noexcept
Q_WEAK_OVERLOAD QVersionNumber(QList< int > &&seg)
Move-constructs a version number from the list of numbers contained in seg.
qsizetype segmentCount() const noexcept
Returns the number of integers stored in segments().
const_reverse_iterator rend() const noexcept
const_iterator constBegin() const noexcept
bool isNormalized() const noexcept
Returns true if the version number does not contain any trailing zeros, otherwise returns false.
const_iterator cend() const noexcept
Q_WEAK_OVERLOAD QVersionNumber(const QList< int > &seg)
Constructs a version number from the list of numbers contained in seg.
reference const_reference
int segmentAt(qsizetype index) const noexcept
Returns the segment value at index.
int microVersion() const noexcept
Returns the micro version number, that is, the third segment.
static Q_CORE_EXPORT int compare(const QVersionNumber &v1, const QVersionNumber &v2) noexcept
Compares v1 with v2 and returns an integer less than, equal to, or greater than zero,...
const_iterator begin() const noexcept
Combined button and popup list for selecting options.
Q_DECLARE_TYPEINFO(QByteArrayView, Q_PRIMITIVE_TYPE)
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
static int compareVersionComponents(int lhs, int rhs) noexcept
Q_DECLARE_TYPEINFO(QOperatingSystemVersion, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(QVersionNumber::SegmentStorage, Q_RELOCATABLE_TYPE)