Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qversionnumber.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#include <QtCore/qversionnumber.h>
7#include <QtCore/qhash.h>
8#include <QtCore/private/qlocale_tools_p.h>
9#include <QtCore/qcollator.h>
10
11#ifndef QT_NO_DATASTREAM
12# include <QtCore/qdatastream.h>
13#endif
14
15#ifndef QT_NO_DEBUG_STREAM
16# include <QtCore/qdebug.h>
17#endif
18
19#include <algorithm>
20#include <limits>
21
23
25
26
150{
151 if (m_segments.isUsingPointer())
152 return *m_segments.pointer_segments;
153
154 QList<int> result;
155 result.resize(segmentCount());
156 for (qsizetype i = 0; i < segmentCount(); ++i)
157 result[i] = segmentAt(i);
158 return result;
159}
160
238{
239 qsizetype i;
240 for (i = m_segments.size(); i; --i)
241 if (m_segments.at(i - 1) != 0)
242 break;
243
244 QVersionNumber result(*this);
245 result.m_segments.resize(i);
246 return result;
247}
248
260{
261 if (segmentCount() > other.segmentCount())
262 return false;
263 for (qsizetype i = 0; i < segmentCount(); ++i) {
264 if (segmentAt(i) != other.segmentAt(i))
265 return false;
266 }
267 return true;
268}
269
284{
285 qsizetype commonlen;
286
287 if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) {
288 // we can't use memcmp because it interprets the data as unsigned bytes
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])
295 return x;
296 } else {
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);
301 }
302 }
303
304 // ran out of segments in v1 and/or v2 and need to check the first trailing
305 // segment to finish the compare
306 if (v1.segmentCount() > commonlen) {
307 // v1 is longer
308 if (v1.segmentAt(commonlen) != 0)
309 return v1.segmentAt(commonlen);
310 else
311 return 1;
312 } else if (v2.segmentCount() > commonlen) {
313 // v2 is longer
314 if (v2.segmentAt(commonlen) != 0)
315 return -v2.segmentAt(commonlen);
316 else
317 return -1;
318 }
319
320 // the two version numbers are the same
321 return 0;
322}
323
333 const QVersionNumber &v2)
334{
335 qsizetype commonlen = qMin(v1.segmentCount(), v2.segmentCount());
336 qsizetype i;
337 for (i = 0; i < commonlen; ++i) {
338 if (v1.segmentAt(i) != v2.segmentAt(i))
339 break;
340 }
341
342 if (i == 0)
343 return QVersionNumber();
344
345 // try to use the one with inline segments, if there's one
346 QVersionNumber result(!v1.m_segments.isUsingPointer() ? v1 : v2);
347 result.m_segments.resize(i);
348 return result;
349}
350
411{
412 QString version;
413 version.reserve(qMax(segmentCount() * 2 - 1, 0));
414 bool first = true;
415 for (qsizetype i = 0; i < segmentCount(); ++i) {
416 if (!first)
417 version += u'.';
418 version += QString::number(segmentAt(i));
419 first = false;
420 }
421 return version;
422}
423
444{
445 // 32 should be more than enough, and, crucially, it means we're allocating
446 // not more (and often less) often when compared with direct QList usage
447 // for all possible segment counts (under the constraint that we don't want
448 // to keep more capacity around for the lifetime of the resulting
449 // QVersionNumber than required), esp. in the common case where the inline
450 // storage can be used.
451 QVarLengthArray<int, 32> seg;
452
453 const char *start = string.begin();
454 const char *lastGoodEnd = start;
455 const char *endOfString = string.end();
456
457 do {
458 // parsing as unsigned so a minus sign is rejected
459 auto [value, used] = qstrntoull(start, endOfString - start, 10);
460 if (used <= 0 || value > qulonglong(std::numeric_limits<int>::max()))
461 break;
462 seg.append(int(value));
463 start += used + 1;
464 lastGoodEnd = start - 1;
465 } while (start < endOfString && *lastGoodEnd == '.');
466
467 if (suffixIndex)
468 *suffixIndex = lastGoodEnd - string.begin();
469
470 return QVersionNumber(seg);
471}
472
473static QVersionNumber from_string(q_no_char8_t::QUtf8StringView string, qsizetype *suffixIndex)
474{
475 return from_string(QLatin1StringView(string.data(), string.size()), suffixIndex);
476}
477
478// in qstring.cpp
479extern void qt_to_latin1(uchar *dst, const char16_t *uc, qsizetype len);
480
482{
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);
487}
488
490{
491 return string.visit([=] (auto string) { return from_string(string, suffixIndex); });
492}
493
494void QVersionNumber::SegmentStorage::setListData(const QList<int> &seg)
495{
496 pointer_segments = new QList<int>(seg);
497}
498
499void QVersionNumber::SegmentStorage::setListData(QList<int> &&seg)
500{
501 pointer_segments = new QList<int>(std::move(seg));
502}
503
504void QVersionNumber::SegmentStorage::setListData(const int *first, const int *last)
505{
506 pointer_segments = new QList<int>(first, last);
507}
508
509void QVersionNumber::SegmentStorage::resize(qsizetype len)
510{
511 if (isUsingPointer())
512 pointer_segments->resize(len);
513 else
514 setInlineSize(len);
515}
516
517void QVersionNumber::SegmentStorage::setVector(int len, int maj, int min, int mic)
518{
519 pointer_segments = new QList<int>;
520 pointer_segments->resize(len);
521 pointer_segments->data()[0] = maj;
522 if (len > 1) {
523 pointer_segments->data()[1] = min;
524 if (len > 2) {
525 pointer_segments->data()[2] = mic;
526 }
527 }
528}
529
530#ifndef QT_NO_DATASTREAM
541{
542 out << version.segments();
543 return out;
544}
545
555{
556 if (!version.m_segments.isUsingPointer())
557 version.m_segments.pointer_segments = new QList<int>;
558 in >> *version.m_segments.pointer_segments;
559 return in;
560}
561#endif
562
563#ifndef QT_NO_DEBUG_STREAM
565{
566 QDebugStateSaver saver(debug);
567 debug.nospace().noquote();
568 debug << "QVersionNumber(" << version.toString() << ")";
569 return debug;
570}
571#endif
572
580size_t qHash(const QVersionNumber &key, size_t seed)
581{
583 for (int i = 0; i < key.segmentCount(); ++i)
584 seed = hash(seed, key.segmentAt(i));
585 return seed;
586}
587
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qdatastream.h:46
\inmodule QtCore
\inmodule QtCore
size_t qHash(const QVersionNumber &key, size_t seed)
Definition qlist.h:75
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
Definition qstring.h:1325
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\inmodule QtCore
QDataStream & operator<<(QDataStream &out, const QVersionNumber &version)
Writes the version number version to stream out.
Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const noexcept
Returns true if the current version number is contained in the other version number,...
friend Q_CORE_EXPORT QDataStream & operator>>(QDataStream &in, QVersionNumber &version)
Reads a version number from stream in and stores it in version.
static Q_CORE_EXPORT QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2)
QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1, ...
QVersionNumber() noexcept
Produces a null version.
static Q_CORE_EXPORT QVersionNumber fromString(QAnyStringView string, qsizetype *suffixIndex=nullptr)
Q_CORE_EXPORT QList< int > segments() const
Returns all of the numerical segments.
qsizetype segmentCount() const noexcept
Returns the number of integers stored in segments().
Q_CORE_EXPORT QString toString() const
Returns a string with all of the segments delimited by a period ({.}).
Q_CORE_EXPORT QVersionNumber normalized() const
Returns an equivalent version number but with all trailing zeros removed.
int segmentAt(qsizetype index) const noexcept
Returns the segment value at index.
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,...
QHash< int, QWidget * > hash
[35multi]
Combined button and popup list for selecting options.
constexpr const T & min(const T &a, const T &b)
Definition qnumeric.h:366
static jboolean copy(JNIEnv *, jobject)
#define Q_LIKELY(x)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
QSimpleParsedNumber< qulonglong > qstrntoull(const char *begin, qsizetype size, int base)
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition qmetatype.h:1390
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLint GLfloat GLfloat GLfloat v2
GLint GLint GLint GLint GLint x
[0]
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum dst
GLint GLfloat GLfloat v1
GLuint start
GLint first
GLuint in
GLuint segments
GLuint64EXT * result
[6]
GLenum GLsizei len
static int segmentCount(const QPainterPath &path, qreal pathLength)
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
unsigned char uchar
Definition qtypes.h:32
quint64 qulonglong
Definition qtypes.h:64
ptrdiff_t qsizetype
Definition qtypes.h:165
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition qtypes.h:45
static QVersionNumber from_string(QLatin1StringView string, qsizetype *suffixIndex)
void qt_to_latin1(uchar *dst, const char16_t *uc, qsizetype len)
Definition qstring.cpp:1183
QTextStream out(stdout)
[7]
QSharedPointer< T > other(t)
[5]