7#include <QtCore/qversionnumber.h>
8#include <QtCore/qhash.h>
9#include <QtCore/private/qlocale_tools_p.h>
10#include <QtCore/qcollator.h>
12#ifndef QT_NO_DATASTREAM
13# include <QtCore/qdatastream.h>
16#ifndef QT_NO_DEBUG_STREAM
17# include <QtCore/qdebug.h>
25QT_IMPL_METATYPE_EXTERN(QVersionNumber)
28
29
30
31
32
33
34
35
36
39
40
41
42
43
44
47
48
49
50
53
54
55
56
57
60
61
62
63
64
67
68
69
70
73
74
75
76
79
80
81
82
83
86
87
88
89
90
91
92
93
96
97
98
99
100
101
102
105
106
107
108
109
110
111
114
115
116
117
118
119
120
121
124
125
126
127
128
129
130
131
134
135
136
137
138
139
140
141
144
145
146
147
148
149
150QList<
int> QVersionNumber::segments()
const
152 if (m_segments.isUsingPointer())
153 return *m_segments.pointer_segments;
156 result.resize(segmentCount());
157 for (qsizetype i = 0; i < segmentCount(); ++i)
158 result[i] = segmentAt(i);
163
164
165
166
167
168
169
172
173
174
175
176
177
180
181
182
183
184
185
186
187
188
189
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
229
230
231
232
233
234
235
236
237
238QVersionNumber QVersionNumber::normalized()
const
241 for (i = m_segments.size(); i; --i)
242 if (m_segments.at(i - 1) != 0)
245 QVersionNumber result(*
this);
246 result.m_segments.resize(i);
251
252
253
254
255
256
257
258
259
260bool QVersionNumber::isPrefixOf(
const QVersionNumber &other)
const noexcept
262 if (segmentCount() > other.segmentCount())
264 for (qsizetype i = 0; i < segmentCount(); ++i) {
265 if (segmentAt(i) != other.segmentAt(i))
272
273
274
275
276
277
278
279
280
281
282
283
284int QVersionNumber::compare(
const QVersionNumber &v1,
const QVersionNumber &v2)
noexcept
288 if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) {
290 const qint8 *ptr1 = v1.m_segments.inline_segments + InlineSegmentStartIdx;
291 const qint8 *ptr2 = v2.m_segments.inline_segments + InlineSegmentStartIdx;
292 commonlen = qMin(v1.m_segments.size(),
293 v2.m_segments.size());
294 for (qsizetype i = 0; i < commonlen; ++i)
295 if (
int x = ptr1[i] - ptr2[i])
298 commonlen = qMin(v1.segmentCount(), v2.segmentCount());
299 for (qsizetype i = 0; i < commonlen; ++i) {
300 if (v1.segmentAt(i) != v2.segmentAt(i))
301 return v1.segmentAt(i) - v2.segmentAt(i);
307 if (v1.segmentCount() > commonlen) {
309 if (v1.segmentAt(commonlen) != 0)
310 return v1.segmentAt(commonlen);
313 }
else if (v2.segmentCount() > commonlen) {
315 if (v2.segmentAt(commonlen) != 0)
316 return -v2.segmentAt(commonlen);
326
327
328
329
330
331
332
333QVersionNumber QVersionNumber::commonPrefix(
const QVersionNumber &v1,
334 const QVersionNumber &v2)
336 qsizetype commonlen = qMin(v1.segmentCount(), v2.segmentCount());
338 for (i = 0; i < commonlen; ++i) {
339 if (v1.segmentAt(i) != v2.segmentAt(i))
344 return QVersionNumber();
347 QVersionNumber result(!v1.m_segments.isUsingPointer() ? v1 : v2);
348 result.m_segments.resize(i);
353
354
355
356
357
358
361
362
363
364
365
366
367
370
371
372
373
374
375
376
379
380
381
382
383
384
385
388
389
390
391
392
393
396
397
398
399
400
401
402
405
406
407
408
409
410
411QString QVersionNumber::toString()
const
414 version.reserve(qMax(segmentCount() * 2 - 1, 0));
416 for (qsizetype i = 0; i < segmentCount(); ++i) {
419 version += QString::number(segmentAt(i));
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
444static QVersionNumber from_string(QLatin1StringView string, qsizetype *suffixIndex)
452 QVarLengthArray<
int, 32> seg;
454 const char *start = string.begin();
455 const char *lastGoodEnd = start;
456 const char *endOfString = string.end();
460 auto [value, used] = qstrntoull(start, endOfString - start, 10);
461 if (used <= 0 || value > qulonglong(std::numeric_limits<
int>::max()))
463 seg.append(
int(value));
465 lastGoodEnd = start - 1;
466 }
while (start < endOfString && *lastGoodEnd ==
'.');
469 *suffixIndex = lastGoodEnd - string.begin();
471 return QVersionNumber(seg);
474static QVersionNumber from_string(q_no_char8_t::QUtf8StringView string, qsizetype *suffixIndex)
476 return from_string(QLatin1StringView(string.data(), string.size()), suffixIndex);
480extern void qt_to_latin1(uchar *dst,
const char16_t *uc, qsizetype len);
484 QVarLengthArray<
char> copy;
485 copy.resize(string.size());
486 qt_to_latin1(
reinterpret_cast<uchar*>(copy.data()), string.utf16(), string.size());
487 return from_string(QLatin1StringView(copy.data(), copy.size()), suffixIndex);
490QVersionNumber QVersionNumber::fromString(QAnyStringView string, qsizetype *suffixIndex)
492 return string.visit([=] (
auto string) {
return from_string(string, suffixIndex); });
495void QVersionNumber::SegmentStorage::setListData(
const QList<
int> &seg)
497 pointer_segments =
new QList<
int>(seg);
500void QVersionNumber::SegmentStorage::setListData(QList<
int> &&seg)
502 pointer_segments =
new QList<
int>(std::move(seg));
505void QVersionNumber::SegmentStorage::setListData(
const int *first,
const int *last)
507 pointer_segments =
new QList<
int>(first, last);
510void QVersionNumber::SegmentStorage::resize(qsizetype len)
512 if (isUsingPointer())
513 pointer_segments->resize(len);
518void QVersionNumber::SegmentStorage::setVector(
int len,
int maj,
int min,
int mic)
520 pointer_segments =
new QList<
int>;
521 pointer_segments->resize(len);
522 pointer_segments->data()[0] = maj;
524 pointer_segments->data()[1] = min;
526 pointer_segments->data()[2] = mic;
531#ifndef QT_NO_DATASTREAM
533
534
535
536
537
538
539
540
543 out << version.segments();
548
549
550
551
552
553
554
557 if (!version.m_segments.isUsingPointer())
558 version.m_segments.pointer_segments =
new QList<
int>;
559 in >> *version.m_segments.pointer_segments;
564#ifndef QT_NO_DEBUG_STREAM
567 QDebugStateSaver saver(debug);
568 debug.nospace().noquote();
569 debug <<
"QVersionNumber(" << version.toString() <<
")";
575
576
577
580 return qHashRange(key.begin(), key.end(), seed);
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)
QDataStream & operator<<(QDataStream &stream, const QImage &image)
[0]
QDataStream & operator>>(QDataStream &stream, QImage &image)