QtBase  v6.3.1
qversionnumber.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
6 ** Contact: https://www.qt.io/licensing/
7 **
8 ** This file is part of the QtCore module of the Qt Toolkit.
9 **
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** Commercial License Usage
12 ** Licensees holding valid commercial Qt licenses may use this file in
13 ** accordance with the commercial license agreement provided with the
14 ** Software or, alternatively, in accordance with the terms contained in
15 ** a written agreement between you and The Qt Company. For licensing terms
16 ** and conditions see https://www.qt.io/terms-conditions. For further
17 ** information use the contact form at https://www.qt.io/contact-us.
18 **
19 ** GNU Lesser General Public License Usage
20 ** Alternatively, this file may be used under the terms of the GNU Lesser
21 ** General Public License version 3 as published by the Free Software
22 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
23 ** packaging of this file. Please review the following information to
24 ** ensure the GNU Lesser General Public License version 3 requirements
25 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26 **
27 ** GNU General Public License Usage
28 ** Alternatively, this file may be used under the terms of the GNU
29 ** General Public License version 2.0 or (at your option) the GNU General
30 ** Public license version 3 or any later version approved by the KDE Free
31 ** Qt Foundation. The licenses are as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33 ** included in the packaging of this file. Please review the following
34 ** information to ensure the GNU General Public License requirements will
35 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36 ** https://www.gnu.org/licenses/gpl-3.0.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QtCore/qversionnumber.h>
43 #include <QtCore/qhash.h>
44 #include <QtCore/private/qlocale_tools_p.h>
45 #include <QtCore/qcollator.h>
46 
47 #ifndef QT_NO_DATASTREAM
48 # include <QtCore/qdatastream.h>
49 #endif
50 
51 #ifndef QT_NO_DEBUG_STREAM
52 # include <QtCore/qdebug.h>
53 #endif
54 
55 #include <algorithm>
56 #include <limits>
57 
59 
62 
63 
181 {
182  if (m_segments.isUsingPointer())
183  return *m_segments.pointer_segments;
184 
186  result.resize(segmentCount());
187  for (int i = 0; i < segmentCount(); ++i)
188  result[i] = segmentAt(i);
189  return result;
190 }
191 
220 {
221  int i;
222  for (i = m_segments.size(); i; --i)
223  if (m_segments.at(i - 1) != 0)
224  break;
225 
226  QVersionNumber result(*this);
227  result.m_segments.resize(i);
228  return result;
229 }
230 
242 {
243  if (segmentCount() > other.segmentCount())
244  return false;
245  for (int i = 0; i < segmentCount(); ++i) {
246  if (segmentAt(i) != other.segmentAt(i))
247  return false;
248  }
249  return true;
250 }
251 
266 {
267  int commonlen;
268 
269  if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) {
270  // we can't use memcmp because it interprets the data as unsigned bytes
271  const qint8 *ptr1 = v1.m_segments.inline_segments + InlineSegmentStartIdx;
272  const qint8 *ptr2 = v2.m_segments.inline_segments + InlineSegmentStartIdx;
273  commonlen = qMin(v1.m_segments.size(),
274  v2.m_segments.size());
275  for (int i = 0; i < commonlen; ++i)
276  if (int x = ptr1[i] - ptr2[i])
277  return x;
278  } else {
279  commonlen = qMin(v1.segmentCount(), v2.segmentCount());
280  for (int i = 0; i < commonlen; ++i) {
281  if (v1.segmentAt(i) != v2.segmentAt(i))
282  return v1.segmentAt(i) - v2.segmentAt(i);
283  }
284  }
285 
286  // ran out of segments in v1 and/or v2 and need to check the first trailing
287  // segment to finish the compare
288  if (v1.segmentCount() > commonlen) {
289  // v1 is longer
290  if (v1.segmentAt(commonlen) != 0)
291  return v1.segmentAt(commonlen);
292  else
293  return 1;
294  } else if (v2.segmentCount() > commonlen) {
295  // v2 is longer
296  if (v2.segmentAt(commonlen) != 0)
297  return -v2.segmentAt(commonlen);
298  else
299  return -1;
300  }
301 
302  // the two version numbers are the same
303  return 0;
304 }
305 
315  const QVersionNumber &v2)
316 {
317  int commonlen = qMin(v1.segmentCount(), v2.segmentCount());
318  int i;
319  for (i = 0; i < commonlen; ++i) {
320  if (v1.segmentAt(i) != v2.segmentAt(i))
321  break;
322  }
323 
324  if (i == 0)
325  return QVersionNumber();
326 
327  // try to use the one with inline segments, if there's one
328  QVersionNumber result(!v1.m_segments.isUsingPointer() ? v1 : v2);
329  result.m_segments.resize(i);
330  return result;
331 }
332 
393 {
395  version.reserve(qMax(segmentCount() * 2 - 1, 0));
396  bool first = true;
397  for (int i = 0; i < segmentCount(); ++i) {
398  if (!first)
399  version += QLatin1Char('.');
401  first = false;
402  }
403  return version;
404 }
405 
406 #if QT_STRINGVIEW_LEVEL < 2
419 QVersionNumber QVersionNumber::fromString(const QString &string, int *suffixIndex)
420 {
421  return fromString(QLatin1String(string.toLatin1()), suffixIndex);
422 }
423 #endif
424 
441 {
442  return fromString(QLatin1String(string.toLatin1()), suffixIndex);
443 }
444 
461 {
462  QList<int> seg;
463 
464  const char *start = string.begin();
465  const char *end = start;
466  const char *lastGoodEnd = start;
467  const char *endOfString = string.end();
468 
469  do {
470  bool ok = false;
471  const qulonglong value = qstrntoull(start, endOfString - start, &end, 10, &ok);
472  if (!ok || value > qulonglong(std::numeric_limits<int>::max()))
473  break;
474  seg.append(int(value));
475  start = end + 1;
476  lastGoodEnd = end;
477  } while (start < endOfString && (end < endOfString && *end == '.'));
478 
479  if (suffixIndex)
480  *suffixIndex = int(lastGoodEnd - string.begin());
481 
482  return QVersionNumber(std::move(seg));
483 }
484 
485 void QVersionNumber::SegmentStorage::setVector(int len, int maj, int min, int mic)
486 {
487  pointer_segments = new QList<int>;
488  pointer_segments->resize(len);
489  pointer_segments->data()[0] = maj;
490  if (len > 1) {
491  pointer_segments->data()[1] = min;
492  if (len > 2) {
493  pointer_segments->data()[2] = mic;
494  }
495  }
496 }
497 
498 #ifndef QT_NO_DATASTREAM
509 {
510  out << version.segments();
511  return out;
512 }
513 
523 {
524  if (!version.m_segments.isUsingPointer())
525  version.m_segments.pointer_segments = new QList<int>;
526  in >> *version.m_segments.pointer_segments;
527  return in;
528 }
529 #endif
530 
531 #ifndef QT_NO_DEBUG_STREAM
533 {
534  QDebugStateSaver saver(debug);
535  debug.nospace().noquote();
536  debug << "QVersionNumber(" << version.toString() << ")";
537  return debug;
538 }
539 #endif
540 
549 size_t qHash(const QVersionNumber &key, size_t seed)
550 {
552  for (int i = 0; i < key.segmentCount(); ++i)
553  seed = hash(seed, key.segmentAt(i));
554  return seed;
555 }
556 
691 #ifndef QT_NO_DATASTREAM
700 {
701  return out << revision.toEncodedVersion<quint16>();
702 }
703 
712 {
713  quint16 value;
714  in >> value;
716  return in;
717 }
718 #endif
719 
720 #ifndef QT_NO_DEBUG_STREAM
722 {
723  QDebugStateSaver saver(debug);
724  if (revision.hasMajorVersion()) {
725  if (revision.hasMinorVersion())
726  debug.nospace() << revision.majorVersion() << '.' << revision.minorVersion();
727  else
728  debug.nospace().noquote() << revision.majorVersion() << ".x";
729  } else {
730  if (revision.hasMinorVersion())
731  debug << revision.minorVersion();
732  else
733  debug.noquote() << "invalid";
734  }
735  return debug;
736 }
737 #endif
738 
747 size_t qHash(const QTypeRevision &key, size_t seed)
748 {
749  return qHash(key.toEncodedVersion<quint16>(), seed);
750 }
751 
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
operator>>(QDataStream &ds, qfloat16 &f)
Definition: qfloat16.cpp:344
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:65
Convenience class for custom QDebug operators.
Definition: qdebug.h:176
template< typename Enum > size_t qHash(QFlags< Enum > flags, size_t seed=0) noexcept
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
Definition: qlist.h:108
iterator begin()
Definition: qlist.h:623
void resize(qsizetype size)
Definition: qlist.h:420
void append(parameter_type t)
Definition: qlist.h:469
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString number(int, int base=10)
Definition: qstring.cpp:7538
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
Definition: qstringview.h:122
The QTypeRevision class contains a lightweight representation of a version number with two 8-bit segm...
static constexpr QTypeRevision fromEncodedVersion(Integer value)
constexpr bool hasMinorVersion() const
constexpr bool hasMajorVersion() const
constexpr Integer toEncodedVersion() const
constexpr quint8 minorVersion() const
constexpr quint8 majorVersion() const
The QVersionNumber class contains a version number with an arbitrary number of segments.
Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const noexcept
static Q_CORE_EXPORT QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2)
QVersionNumber() noexcept
static Q_CORE_EXPORT QVersionNumber fromString(const QString &string, int *suffixIndex=nullptr)
Q_CORE_EXPORT QString toString() const
int segmentCount() const noexcept
Q_CORE_EXPORT QVersionNumber normalized() const
int segmentAt(int index) const noexcept
static Q_CORE_EXPORT int compare(const QVersionNumber &v1, const QVersionNumber &v2) noexcept
QHash< int, QWidget * > hash
[35multi]
int const char * version
Definition: zlib.h:814
#define Q_LIKELY(x)
EGLOutputLayerEXT EGLint EGLAttrib value
unsigned short quint16
Definition: qglobal.h:286
quint64 qulonglong
Definition: qglobal.h:302
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition: qglobal.h:283
unsigned long long qstrntoull(const char *begin, qsizetype size, const char **endptr, int base, bool *ok)
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition: qmetatype.h:1287
GLint GLfloat GLfloat GLfloat v2
GLint GLint GLint GLint GLint x
[0]
GLuint64 key
GLuint GLuint end
GLint GLfloat GLfloat v1
GLuint start
GLint first
GLenum GLsizei len
Definition: qopenglext.h:3292
GLuint in
Definition: qopenglext.h:8870
GLuint segments
Definition: qopenglext.h:9598
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QTextStream out(stdout)
[7]
QSharedPointer< T > other(t)
[5]
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:53