6#include <QtCore/qversionnumber.h>
7#include <QtCore/qhash.h>
8#include <QtCore/private/qlocale_tools_p.h>
9#include <QtCore/qcollator.h>
11#ifndef QT_NO_DATASTREAM
12# include <QtCore/qdatastream.h>
15#ifndef QT_NO_DEBUG_STREAM
16# include <QtCore/qdebug.h>
24QT_IMPL_METATYPE_EXTERN(QVersionNumber)
27
28
29
30
31
32
33
34
35
38
39
40
41
42
43
46
47
48
49
52
53
54
55
56
59
60
61
62
63
66
67
68
69
72
73
74
75
78
79
80
81
82
85
86
87
88
89
90
91
92
95
96
97
98
99
100
101
104
105
106
107
108
109
110
113
114
115
116
117
118
119
120
123
124
125
126
127
128
129
130
133
134
135
136
137
138
139
140
143
144
145
146
147
148
149QList<
int> QVersionNumber::segments()
const
151 if (m_segments.isUsingPointer())
152 return *m_segments.pointer_segments;
155 result.resize(segmentCount());
156 for (qsizetype i = 0; i < segmentCount(); ++i)
157 result[i] = segmentAt(i);
162
163
164
165
166
167
168
171
172
173
174
175
176
179
180
181
182
183
184
185
186
187
188
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
228
229
230
231
232
233
234
235
236
237QVersionNumber QVersionNumber::normalized()
const
240 for (i = m_segments.size(); i; --i)
241 if (m_segments.at(i - 1) != 0)
244 QVersionNumber result(*
this);
245 result.m_segments.resize(i);
250
251
252
253
254
255
256
257
258
259bool QVersionNumber::isPrefixOf(
const QVersionNumber &other)
const noexcept
261 if (segmentCount() > other.segmentCount())
263 for (qsizetype i = 0; i < segmentCount(); ++i) {
264 if (segmentAt(i) != other.segmentAt(i))
271
272
273
274
275
276
277
278
279
280
281
282
283int QVersionNumber::compare(
const QVersionNumber &v1,
const QVersionNumber &v2)
noexcept
287 if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) {
289 const qint8 *ptr1 = v1.m_segments.inline_segments + InlineSegmentStartIdx;
290 const qint8 *ptr2 = v2.m_segments.inline_segments + InlineSegmentStartIdx;
291 commonlen = qMin(v1.m_segments.size(),
292 v2.m_segments.size());
293 for (qsizetype i = 0; i < commonlen; ++i)
294 if (
int x = ptr1[i] - ptr2[i])
297 commonlen = qMin(v1.segmentCount(), v2.segmentCount());
298 for (qsizetype i = 0; i < commonlen; ++i) {
299 if (v1.segmentAt(i) != v2.segmentAt(i))
300 return v1.segmentAt(i) - v2.segmentAt(i);
306 if (v1.segmentCount() > commonlen) {
308 if (v1.segmentAt(commonlen) != 0)
309 return v1.segmentAt(commonlen);
312 }
else if (v2.segmentCount() > commonlen) {
314 if (v2.segmentAt(commonlen) != 0)
315 return -v2.segmentAt(commonlen);
325
326
327
328
329
330
331
332QVersionNumber QVersionNumber::commonPrefix(
const QVersionNumber &v1,
333 const QVersionNumber &v2)
335 qsizetype commonlen = qMin(v1.segmentCount(), v2.segmentCount());
337 for (i = 0; i < commonlen; ++i) {
338 if (v1.segmentAt(i) != v2.segmentAt(i))
343 return QVersionNumber();
346 QVersionNumber result(!v1.m_segments.isUsingPointer() ? v1 : v2);
347 result.m_segments.resize(i);
352
353
354
355
356
357
360
361
362
363
364
365
366
369
370
371
372
373
374
375
378
379
380
381
382
383
384
387
388
389
390
391
392
395
396
397
398
399
400
401
404
405
406
407
408
409
410QString QVersionNumber::toString()
const
413 version.reserve(qMax(segmentCount() * 2 - 1, 0));
415 for (qsizetype i = 0; i < segmentCount(); ++i) {
418 version += QString::number(segmentAt(i));
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
443static QVersionNumber from_string(QLatin1StringView string, qsizetype *suffixIndex)
451 QVarLengthArray<
int, 32> seg;
453 const char *start = string.begin();
454 const char *lastGoodEnd = start;
455 const char *endOfString = string.end();
459 auto [value, used] = qstrntoull(start, endOfString - start, 10);
460 if (used <= 0 || value > qulonglong(std::numeric_limits<
int>::max()))
462 seg.append(
int(value));
464 lastGoodEnd = start - 1;
465 }
while (start < endOfString && *lastGoodEnd ==
'.');
468 *suffixIndex = lastGoodEnd - string.begin();
470 return QVersionNumber(seg);
473static QVersionNumber from_string(q_no_char8_t::QUtf8StringView string, qsizetype *suffixIndex)
475 return from_string(QLatin1StringView(string.data(), string.size()), suffixIndex);
479extern void qt_to_latin1(uchar *dst,
const char16_t *uc, qsizetype len);
483 QVarLengthArray<
char> copy;
484 copy.resize(string.size());
485 qt_to_latin1(
reinterpret_cast<uchar*>(copy.data()), string.utf16(), string.size());
486 return from_string(QLatin1StringView(copy.data(), copy.size()), suffixIndex);
489QVersionNumber QVersionNumber::fromString(QAnyStringView string, qsizetype *suffixIndex)
491 return string.visit([=] (
auto string) {
return from_string(string, suffixIndex); });
494void QVersionNumber::SegmentStorage::setListData(
const QList<
int> &seg)
496 pointer_segments =
new QList<
int>(seg);
499void QVersionNumber::SegmentStorage::setListData(QList<
int> &&seg)
501 pointer_segments =
new QList<
int>(std::move(seg));
504void QVersionNumber::SegmentStorage::setListData(
const int *first,
const int *last)
506 pointer_segments =
new QList<
int>(first, last);
509void QVersionNumber::SegmentStorage::resize(qsizetype len)
511 if (isUsingPointer())
512 pointer_segments->resize(len);
517void QVersionNumber::SegmentStorage::setVector(
int len,
int maj,
int min,
int mic)
519 pointer_segments =
new QList<
int>;
520 pointer_segments->resize(len);
521 pointer_segments->data()[0] = maj;
523 pointer_segments->data()[1] = min;
525 pointer_segments->data()[2] = mic;
530#ifndef QT_NO_DATASTREAM
532
533
534
535
536
537
538
539
542 out << version.segments();
547
548
549
550
551
552
553
556 if (!version.m_segments.isUsingPointer())
557 version.m_segments.pointer_segments =
new QList<
int>;
558 in >> *version.m_segments.pointer_segments;
563#ifndef QT_NO_DEBUG_STREAM
566 QDebugStateSaver saver(debug);
567 debug.nospace().noquote();
568 debug <<
"QVersionNumber(" << version.toString() <<
")";
574
575
576
577
578
579
582 QtPrivate::QHashCombine hash;
583 for (
int i = 0; i < key.segmentCount(); ++i)
584 seed = hash(seed, key.segmentAt(i));
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
static QVersionNumber from_string(QStringView string, qsizetype *suffixIndex)