Long live QVersionNumber!
The class provides compare operators, stream operators, and hashing functions. This class aims to be compatible with (but not restricted to) the Semantic Versioning 2.0 standard (semver.org). [ChangeLog][QtCore] Added QVersionNumber class Done-with: Marc Mutz <marc.mutz@kdab.com> Change-Id: I244c8ccc002909af03987a2df052734d1a8621a9 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
This commit is contained in:
parent
3750c677ee
commit
a332322de9
109
src/corelib/doc/snippets/qversionnumber/main.cpp
Normal file
109
src/corelib/doc/snippets/qversionnumber/main.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QVersionNumber>
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
static void genericExample();
|
||||
static void equalityExample();
|
||||
static void isPrefixOf();
|
||||
static void parse();
|
||||
static void equivalent();
|
||||
};
|
||||
|
||||
void Object::genericExample()
|
||||
{
|
||||
//! [0]
|
||||
QVersionNumber version(1, 2, 3); // 1.2.3
|
||||
//! [0]
|
||||
}
|
||||
|
||||
void Object::equalityExample()
|
||||
{
|
||||
//! [1]
|
||||
QVersionNumber v1(1, 2);
|
||||
QVersionNumber v2(1, 2, 0);
|
||||
int compare = QVersionNumber::compare(v1, v2); // compare == -1
|
||||
//! [1]
|
||||
}
|
||||
|
||||
void Object::isPrefixOf()
|
||||
{
|
||||
//! [2]
|
||||
QVersionNumber v1(5, 3);
|
||||
QVersionNumber v2(5, 3, 1);
|
||||
bool value = v1.isPrefixOf(v2); // true
|
||||
//! [2]
|
||||
}
|
||||
|
||||
void QObject::parse()
|
||||
{
|
||||
//! [3]
|
||||
QString string("5.4.0-alpha");
|
||||
int suffixIndex;
|
||||
QVersionNumber version = QVersionNumber::fromString(string, &suffixIndex);
|
||||
// version is 5.4.0
|
||||
// suffixIndex is 5
|
||||
//! [3]
|
||||
}
|
||||
|
||||
void Object::equivalent()
|
||||
{
|
||||
//! [4]
|
||||
QVersionNumber v1(5, 4);
|
||||
QVersionNumber v2(5, 4, 0);
|
||||
bool equivalent = v1.normalized() == v2.normalized();
|
||||
bool equal = v1 == v2;
|
||||
// equivalent is true
|
||||
// equal is false
|
||||
//! [4]
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Object::genericExample();
|
||||
Object::equalityExample();
|
||||
Object::isPrefixOf();
|
||||
Object::parse();
|
||||
Object::equivalent();
|
||||
}
|
484
src/corelib/tools/qversionnumber.cpp
Normal file
484
src/corelib/tools/qversionnumber.cpp
Normal file
@ -0,0 +1,484 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/qversionnumber.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/private/qlocale_tools_p.h>
|
||||
#include <QtCore/qcollator.h>
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
# include <QtCore/qdatastream.h>
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
# include <QtCore/qdebug.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QVersionNumber
|
||||
\inmodule QtCore
|
||||
\since 5.4
|
||||
\brief The QVersionNumber class contains a version number with an arbitrary
|
||||
number of segments.
|
||||
|
||||
\snippet qversionnumber/main.cpp 0
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber::QVersionNumber()
|
||||
|
||||
Produces a null version.
|
||||
|
||||
\sa isNull()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber::QVersionNumber(int maj)
|
||||
|
||||
Constructs a QVersionNumber consisting of just the major version number \a maj.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber::QVersionNumber(int maj, int min)
|
||||
|
||||
Constructs a QVersionNumber consisting of the major and minor
|
||||
version numbers \a maj and \a min, respectively.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber::QVersionNumber(int maj, int min, int mic)
|
||||
|
||||
Constructs a QVersionNumber consisting of the major, minor, and
|
||||
micro version numbers \a maj, \a min and \a mic, respectively.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber::QVersionNumber(const QVector<int> &seg)
|
||||
|
||||
Constructs a version number from the list of numbers contained in \a seg.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber::QVersionNumber(QVector<int> &&seg)
|
||||
|
||||
Move-constructs a version number from the list of numbers contained in \a seg.
|
||||
|
||||
This constructor is only enabled if the compiler supports C++11 move semantics.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber::QVersionNumber(std::initializer_list<int> args)
|
||||
|
||||
Construct a version number from the std::initializer_list specified by
|
||||
\a args.
|
||||
|
||||
This constructor is only enabled if the compiler supports C++11 initializer
|
||||
lists.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QVersionNumber::isNull() const
|
||||
|
||||
Returns \c true if there are zero numerical segments, otherwise returns
|
||||
\c false.
|
||||
|
||||
\sa segments()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QVersionNumber::isNormalized() const
|
||||
|
||||
Returns \c true if the version number does not contain any trailing zeros,
|
||||
otherwise returns \c false.
|
||||
|
||||
\sa normalized()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int QVersionNumber::majorVersion() const
|
||||
|
||||
Returns the major version number, that is, the first segment.
|
||||
This function is equivalent to segmentAt(0). If this QVersionNumber object
|
||||
is null, this function returns 0.
|
||||
|
||||
\sa isNull(), segmentAt()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int QVersionNumber::minorVersion() const
|
||||
|
||||
Returns the minor version number, that is, the second segment.
|
||||
This function is equivalent to segmentAt(1). If this QVersionNumber object
|
||||
does not contain a minor number, this function returns 0.
|
||||
|
||||
\sa isNull(), segmentAt()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int QVersionNumber::microVersion() const
|
||||
|
||||
Returns the micro version number, that is, the third segment.
|
||||
This function is equivalent to segmentAt(2). If this QVersionNumber object
|
||||
does not contain a micro number, this function returns 0.
|
||||
|
||||
\sa isNull(), segmentAt()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const QVector<int>& QVersionNumber::segments() const
|
||||
|
||||
Returns all of the numerical segments.
|
||||
|
||||
\sa majorVersion(), minorVersion(), microVersion()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int QVersionNumber::segmentAt(int index) const
|
||||
|
||||
Returns the segement value at \a index. If the index does not exist,
|
||||
returns 0.
|
||||
|
||||
\sa segments(), segmentCount()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int QVersionNumber::segmentCount() const
|
||||
|
||||
Returns the number of integers stored in segments().
|
||||
|
||||
\sa segments()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber QVersionNumber::normalized() const
|
||||
|
||||
Returns an equivalent version number but with all trailing zeros removed.
|
||||
|
||||
To check if two numbers are equivalent, use normalized() on both version
|
||||
numbers before perforing the compare.
|
||||
|
||||
\snippet qversionnumber/main.cpp 4
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const
|
||||
|
||||
Returns \c true if the current version number is contained in the \a other
|
||||
version number, otherwise returns \c false.
|
||||
|
||||
\snippet qversionnumber/main.cpp 2
|
||||
|
||||
\sa commonPrefix()
|
||||
*/
|
||||
bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW
|
||||
{
|
||||
return m_segments.size() <= other.m_segments.size() &&
|
||||
std::equal(m_segments.begin(), m_segments.end(), other.m_segments.begin());
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn int QVersionNumber::compare(const QVersionNumber &v1,
|
||||
const QVersionNumber &v2)
|
||||
|
||||
Compares \a v1 with \a v2 and returns an integer less than, equal to, or
|
||||
greater than zero, depending on whether \a v1 is less than, equal to, or
|
||||
greater than \a v2, respectively.
|
||||
|
||||
Comparisons are performed by comparing the segments of \a v1 and \a v2
|
||||
starting at index 0 and working towards the end of the longer list.
|
||||
|
||||
\snippet qversionnumber/main.cpp 1
|
||||
*/
|
||||
int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW
|
||||
{
|
||||
QVector<int>::const_iterator i1 = v1.m_segments.constBegin();
|
||||
const QVector<int>::const_iterator e1 = v1.m_segments.constEnd();
|
||||
QVector<int>::const_iterator i2 = v2.m_segments.constBegin();
|
||||
const QVector<int>::const_iterator e2 = v2.m_segments.constEnd();
|
||||
|
||||
while (i1 != e1 && i2 != e2) {
|
||||
if (*i1 != *i2)
|
||||
return (*i1 - *i2);
|
||||
++i1;
|
||||
++i2;
|
||||
}
|
||||
|
||||
// ran out of segments in v1 and/or v2 and need to check the first trailing
|
||||
// segment to finish the compare
|
||||
if (i1 != e1) {
|
||||
// v1 is longer
|
||||
if (*i1 != 0)
|
||||
return *i1;
|
||||
else
|
||||
return 1;
|
||||
} else if (i2 != e2) {
|
||||
// v2 is longer
|
||||
if (*i2 != 0)
|
||||
return -*i2;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// the two version numbers are the same
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1,
|
||||
const QVersionNumber &v2)
|
||||
|
||||
Returns a version number that is a parent version of both \a v1 and \a v2.
|
||||
|
||||
\sa isPrefixOf()
|
||||
*/
|
||||
QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1,
|
||||
const QVersionNumber &v2)
|
||||
{
|
||||
int min = qMin(v1.m_segments.size(), v2.m_segments.size());
|
||||
QVector<int>::const_iterator i1 = v1.m_segments.begin();
|
||||
QVector<int>::const_iterator e1;
|
||||
e1 = std::mismatch(i1,
|
||||
v1.m_segments.begin() + min,
|
||||
v2.m_segments.begin()).first;
|
||||
return QVersionNumber(v1.m_segments.mid(0, e1 - i1));
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool operator<(const QVersionNumber &lhs, const QVersionNumber &rhs)
|
||||
\relates QVersionNumber
|
||||
|
||||
Returns \c true if \a lhs is less than \a rhs; otherwise returns \c false.
|
||||
|
||||
\sa QVersionNumber::compare()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator<=(const QVersionNumber &lhs, const QVersionNumber &rhs)
|
||||
\relates QVersionNumber
|
||||
|
||||
Returns \c true if \a lhs is less than or equal to \a rhs; otherwise
|
||||
returns \c false.
|
||||
|
||||
\sa QVersionNumber::compare()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator>(const QVersionNumber &lhs, const QVersionNumber &rhs)
|
||||
\relates QVersionNumber
|
||||
|
||||
Returns \c true if \a lhs is greater than \a rhs; otherwise returns \c
|
||||
false.
|
||||
|
||||
\sa QVersionNumber::compare()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator>=(const QVersionNumber &lhs, const QVersionNumber &rhs)
|
||||
\relates QVersionNumber
|
||||
|
||||
Returns \c true if \a lhs is greater than or equal to \a rhs; otherwise
|
||||
returns \c false.
|
||||
|
||||
\sa QVersionNumber::compare()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator==(const QVersionNumber &lhs, const QVersionNumber &rhs)
|
||||
\relates QVersionNumber
|
||||
|
||||
Returns \c true if \a lhs is equal to \a rhs; otherwise returns \c false.
|
||||
|
||||
\sa QVersionNumber::compare()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs)
|
||||
\relates QVersionNumber
|
||||
|
||||
Returns \c true if \a lhs is not equal to \a rhs; otherwise returns
|
||||
\c false.
|
||||
|
||||
\sa QVersionNumber::compare()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QString QVersionNumber::toString() const
|
||||
|
||||
Returns a string with all of the segments delimited by a '.'.
|
||||
|
||||
\sa majorVersion(), minorVersion(), microVersion(), segments()
|
||||
*/
|
||||
QString QVersionNumber::toString() const
|
||||
{
|
||||
QString version;
|
||||
version.reserve(qMax(m_segments.size() * 2 - 1, 0));
|
||||
bool first = true;
|
||||
for (QVector<int>::const_iterator it = m_segments.begin(), end = m_segments.end(); it != end; ++it) {
|
||||
if (!first)
|
||||
version += QLatin1Char('.');
|
||||
version += QString::number(*it);
|
||||
first = false;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber QVersionNumber::fromString(const QString &string,
|
||||
int *suffixIndex)
|
||||
|
||||
Constructs a QVersionNumber from a specially formatted \a string of
|
||||
non-negative decimal numbers delimited by '.'.
|
||||
|
||||
Once the numerical segments have been parsed, the remainder of the string
|
||||
is considered to be the suffix string. The start index of that string will be
|
||||
stored in \a suffixIndex if it is not null.
|
||||
|
||||
\snippet qversionnumber/main.cpp 3
|
||||
|
||||
\sa isNull()
|
||||
*/
|
||||
QVersionNumber QVersionNumber::fromString(const QString &string, int *suffixIndex)
|
||||
{
|
||||
QVector<int> seg;
|
||||
|
||||
const QByteArray cString(string.toLatin1());
|
||||
|
||||
const char *start = cString.constData();
|
||||
const char *end = start;
|
||||
const char *lastGoodEnd = start;
|
||||
const char *endOfString = cString.constData() + cString.size();
|
||||
int value;
|
||||
|
||||
do {
|
||||
bool ok = false;
|
||||
value = int(qstrtoull(start, &end, 10, &ok));
|
||||
if (!ok)
|
||||
break;
|
||||
seg.append(value);
|
||||
start = end + 1;
|
||||
lastGoodEnd = end;
|
||||
} while (start < endOfString && (end < endOfString && *end == '.'));
|
||||
|
||||
if (suffixIndex)
|
||||
*suffixIndex = int(lastGoodEnd - cString.constData());
|
||||
|
||||
return QVersionNumber(qMove(seg));
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber QVersionNumber::normalizedImpl(QVector<int> &segs)
|
||||
|
||||
Implementation of the normalized() function. Takes the movable list \a segs
|
||||
and normalizes them.
|
||||
|
||||
\internal
|
||||
*/
|
||||
QVersionNumber QVersionNumber::normalizedImpl(QVector<int> &segs)
|
||||
{
|
||||
while (segs.size() && segs.last() == 0)
|
||||
segs.pop_back();
|
||||
return QVersionNumber(qMove(segs));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
/*!
|
||||
\fn QDataStream& operator<<(QDataStream &out,
|
||||
const QVersionNumber &version)
|
||||
\relates QVersionNumber
|
||||
|
||||
Writes the version number \a version to stream \a out.
|
||||
|
||||
Note that this has nothing to do with QDataStream::version().
|
||||
*/
|
||||
QDataStream& operator<<(QDataStream &out, const QVersionNumber &version)
|
||||
{
|
||||
out << version.segments();
|
||||
return out;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QDataStream& operator>>(QDataStream &in, QVersionNumber &version)
|
||||
\relates QVersionNumber
|
||||
|
||||
Reads a version number from stream \a in and stores it in \a version.
|
||||
|
||||
Note that this has nothing to do with QDataStream::version().
|
||||
*/
|
||||
QDataStream& operator>>(QDataStream &in, QVersionNumber &version)
|
||||
{
|
||||
in >> version.m_segments;
|
||||
return in;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug debug, const QVersionNumber &version)
|
||||
{
|
||||
debug.noquote() << version.toString();
|
||||
return debug.quote();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\fn uint qHash(const QVersionNumber &key, uint seed)
|
||||
\relates QHash
|
||||
\since 5.4
|
||||
|
||||
Returns the hash value for the \a key, using \a seed to seed the
|
||||
calculation.
|
||||
*/
|
||||
uint qHash(const QVersionNumber &key, uint seed)
|
||||
{
|
||||
uint hash = seed;
|
||||
for (QVector<int>::const_iterator it = key.m_segments.begin(), end = key.m_segments.end(); it != end; ++it) {
|
||||
// used to preserve order
|
||||
// see N3876 for more information
|
||||
hash ^= qHash(*it) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
201
src/corelib/tools/qversionnumber.h
Normal file
201
src/corelib/tools/qversionnumber.h
Normal file
@ -0,0 +1,201 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QVERSIONNUMBER_H
|
||||
#define QVERSIONNUMBER_H
|
||||
|
||||
#include <QtCore/qnamespace.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qvector.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qtypeinfo.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QVersionNumber;
|
||||
Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed = 0);
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
Q_CORE_EXPORT QDataStream& operator<<(QDataStream &out, const QVersionNumber &version);
|
||||
Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version);
|
||||
#endif
|
||||
|
||||
class Q_CORE_EXPORT QVersionNumber
|
||||
{
|
||||
public:
|
||||
inline QVersionNumber() Q_DECL_NOTHROW
|
||||
: m_segments()
|
||||
{}
|
||||
// compiler-generated copy/move ctor/assignment operators are ok
|
||||
|
||||
inline explicit QVersionNumber(const QVector<int> &seg) Q_DECL_NOTHROW
|
||||
: m_segments(seg)
|
||||
{}
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
inline explicit QVersionNumber(QVector<int> &&seg) Q_DECL_NOTHROW
|
||||
: m_segments(qMove(seg))
|
||||
{}
|
||||
#endif
|
||||
#ifdef Q_COMPILER_INITIALIZER_LISTS
|
||||
inline QVersionNumber(std::initializer_list<int> args)
|
||||
: m_segments(args)
|
||||
{}
|
||||
#endif
|
||||
|
||||
inline explicit QVersionNumber(int maj)
|
||||
{ m_segments.reserve(1); m_segments << maj; }
|
||||
|
||||
inline explicit QVersionNumber(int maj, int min)
|
||||
{ m_segments.reserve(2); m_segments << maj << min; }
|
||||
|
||||
inline explicit QVersionNumber(int maj, int min, int mic)
|
||||
{ m_segments.reserve(3); m_segments << maj << min << mic; }
|
||||
|
||||
inline bool isNull() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return m_segments.isEmpty(); }
|
||||
|
||||
inline bool isNormalized() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return isNull() || m_segments.last() != 0; }
|
||||
|
||||
inline int majorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return segmentAt(0); }
|
||||
|
||||
inline int minorVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return segmentAt(1); }
|
||||
|
||||
inline int microVersion() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return segmentAt(2); }
|
||||
|
||||
#if defined(Q_COMPILER_REF_QUALIFIERS)
|
||||
# if defined(Q_CC_GNU)
|
||||
// required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941
|
||||
# pragma push_macro("Q_REQUIRED_RESULT")
|
||||
# undef Q_REQUIRED_RESULT
|
||||
# define Q_REQUIRED_RESULT
|
||||
# define Q_REQUIRED_RESULT_pushed
|
||||
# endif
|
||||
inline QVersionNumber normalized() const & Q_REQUIRED_RESULT
|
||||
{
|
||||
QVector<int> segs(m_segments);
|
||||
return normalizedImpl(segs);
|
||||
}
|
||||
|
||||
inline QVersionNumber normalized() && Q_REQUIRED_RESULT
|
||||
{
|
||||
return normalizedImpl(m_segments);
|
||||
}
|
||||
|
||||
inline QVector<int> segments() const & Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return m_segments; }
|
||||
|
||||
inline QVector<int> segments() && Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return qMove(m_segments); }
|
||||
|
||||
# ifdef Q_REQUIRED_RESULT_pushed
|
||||
# pragma pop_macro("Q_REQUIRED_RESULT")
|
||||
# endif
|
||||
#else
|
||||
inline QVersionNumber normalized() const Q_REQUIRED_RESULT
|
||||
{
|
||||
QVector<int> segs(m_segments);
|
||||
return normalizedImpl(segs);
|
||||
}
|
||||
|
||||
inline QVector<int> segments() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return m_segments; }
|
||||
#endif
|
||||
|
||||
inline int segmentAt(int index) const Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return (m_segments.size() > index) ? m_segments.at(index) : 0; }
|
||||
|
||||
inline int segmentCount() const Q_DECL_NOTHROW Q_REQUIRED_RESULT
|
||||
{ return m_segments.size(); }
|
||||
|
||||
bool isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW Q_REQUIRED_RESULT;
|
||||
|
||||
static int compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW Q_REQUIRED_RESULT;
|
||||
|
||||
static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2) Q_REQUIRED_RESULT;
|
||||
|
||||
QString toString() const Q_REQUIRED_RESULT;
|
||||
static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = 0) Q_REQUIRED_RESULT;
|
||||
|
||||
private:
|
||||
static QVersionNumber normalizedImpl(QVector<int> &segs) Q_REQUIRED_RESULT;
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
friend Q_CORE_EXPORT QDataStream& operator>>(QDataStream &in, QVersionNumber &version);
|
||||
#endif
|
||||
friend Q_CORE_EXPORT uint qHash(const QVersionNumber &key, uint seed);
|
||||
|
||||
QVector<int> m_segments;
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QVersionNumber, Q_MOVABLE_TYPE);
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QVersionNumber &version);
|
||||
#endif
|
||||
|
||||
Q_REQUIRED_RESULT inline bool operator> (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
|
||||
{ return QVersionNumber::compare(lhs, rhs) > 0; }
|
||||
|
||||
Q_REQUIRED_RESULT inline bool operator>=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
|
||||
{ return QVersionNumber::compare(lhs, rhs) >= 0; }
|
||||
|
||||
Q_REQUIRED_RESULT inline bool operator< (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
|
||||
{ return QVersionNumber::compare(lhs, rhs) < 0; }
|
||||
|
||||
Q_REQUIRED_RESULT inline bool operator<=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
|
||||
{ return QVersionNumber::compare(lhs, rhs) <= 0; }
|
||||
|
||||
Q_REQUIRED_RESULT inline bool operator==(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
|
||||
{ return QVersionNumber::compare(lhs, rhs) == 0; }
|
||||
|
||||
Q_REQUIRED_RESULT inline bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW
|
||||
{ return QVersionNumber::compare(lhs, rhs) != 0; }
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_METATYPE(QVersionNumber)
|
||||
|
||||
#endif //QVERSIONNUMBER_H
|
@ -69,7 +69,8 @@ HEADERS += \
|
||||
tools/qunicodetables_p.h \
|
||||
tools/qunicodetools_p.h \
|
||||
tools/qvarlengtharray.h \
|
||||
tools/qvector.h
|
||||
tools/qvector.h \
|
||||
tools/qversionnumber.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
@ -113,7 +114,8 @@ SOURCES += \
|
||||
tools/qtimezoneprivate.cpp \
|
||||
tools/qunicodetools.cpp \
|
||||
tools/qvector.cpp \
|
||||
tools/qvsnprintf.cpp
|
||||
tools/qvsnprintf.cpp \
|
||||
tools/qversionnumber.cpp
|
||||
|
||||
NO_PCH_SOURCES = tools/qstring_compat.cpp
|
||||
msvc: NO_PCH_SOURCES += tools/qvector_msvc.cpp
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qversionnumber.h>
|
||||
|
||||
#include <QtCore/qpoint.h>
|
||||
#include <QtCore/qsize.h>
|
||||
@ -171,6 +172,11 @@ template<> inline char *toString(const QVariant &v)
|
||||
return qstrdup(vstring.constData());
|
||||
}
|
||||
|
||||
template<> inline char *toString(const QVersionNumber &version)
|
||||
{
|
||||
return toString(version.toString());
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool qCompare(QString const &t1, QLatin1String const &t2, const char *actual,
|
||||
const char *expected, const char *file, int line)
|
||||
|
@ -1034,6 +1034,13 @@ QT_BEGIN_NAMESPACE
|
||||
Returns a textual representation of the given \a variant.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn char *QTest::toString(const QVersionNumber &version)
|
||||
\overload
|
||||
|
||||
Returns a textual representation of the given \a version.
|
||||
*/
|
||||
|
||||
/*! \fn void QTest::qWait(int ms)
|
||||
|
||||
Waits for \a ms milliseconds. While waiting, events will be processed and
|
||||
|
@ -0,0 +1,4 @@
|
||||
CONFIG += testcase parallel_test
|
||||
TARGET = tst_qversionnumber
|
||||
QT = core testlib
|
||||
SOURCES = tst_qversionnumber.cpp
|
577
tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp
Normal file
577
tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp
Normal file
@ -0,0 +1,577 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Copyright (C) 2014 Keith Gardner <kreios4004@gmail.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <qversionnumber.h>
|
||||
|
||||
class tst_QVersionNumber : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
void singleInstanceData();
|
||||
void comparisonData();
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void constructorDefault();
|
||||
void constructorVersioned_data();
|
||||
void constructorVersioned();
|
||||
void constructorExplicit();
|
||||
void constructorCopy_data();
|
||||
void constructorCopy();
|
||||
void compareGreater_data();
|
||||
void compareGreater();
|
||||
void compareGreaterEqual_data();
|
||||
void compareGreaterEqual();
|
||||
void compareLess_data();
|
||||
void compareLess();
|
||||
void compareLessEqual_data();
|
||||
void compareLessEqual();
|
||||
void compareEqual_data();
|
||||
void compareEqual();
|
||||
void compareNotEqual_data();
|
||||
void compareNotEqual();
|
||||
void compare_data();
|
||||
void compare();
|
||||
void isPrefixOf_data();
|
||||
void isPrefixOf();
|
||||
void commonPrefix_data();
|
||||
void commonPrefix();
|
||||
void normalized_data();
|
||||
void normalized();
|
||||
void isNormalized_data();
|
||||
void isNormalized();
|
||||
void assignment_data();
|
||||
void assignment();
|
||||
void fromString_data();
|
||||
void fromString();
|
||||
void toString_data();
|
||||
void toString();
|
||||
void isNull_data();
|
||||
void isNull();
|
||||
void serialize_data();
|
||||
void serialize();
|
||||
void moveSemantics();
|
||||
};
|
||||
|
||||
void tst_QVersionNumber::singleInstanceData()
|
||||
{
|
||||
QTest::addColumn<QVector<int> >("segments");
|
||||
QTest::addColumn<QVersionNumber>("expectedVersion");
|
||||
QTest::addColumn<QString>("expectedString");
|
||||
QTest::addColumn<QString>("constructionString");
|
||||
QTest::addColumn<int>("suffixIndex");
|
||||
QTest::addColumn<bool>("isNull");
|
||||
|
||||
// segments expectedVersion expectedString constructionString suffixIndex null
|
||||
QTest::newRow("null") << QVector<int>() << QVersionNumber(QVector<int>()) << QString() << QString() << 0 << true;
|
||||
QTest::newRow("text") << QVector<int>() << QVersionNumber(QVector<int>()) << QString() << QStringLiteral("text") << 0 << true;
|
||||
QTest::newRow(" text") << QVector<int>() << QVersionNumber(QVector<int>()) << QString() << QStringLiteral(" text") << 0 << true;
|
||||
QTest::newRow("Empty String") << QVector<int>() << QVersionNumber(QVector<int>()) << QString() << QStringLiteral("Empty String") << 0 << true;
|
||||
QTest::newRow("-1.-2") << (QVector<int>()) << QVersionNumber() << QStringLiteral("") << QStringLiteral("-1.-2") << 0 << true;
|
||||
QTest::newRow("1.-2-3") << (QVector<int>() << 1) << QVersionNumber(QVector<int>() << 1) << QStringLiteral("1") << QStringLiteral("1.-2-3") << 1 << false;
|
||||
QTest::newRow("1.2-3") << (QVector<int>() << 1 << 2) << QVersionNumber(QVector<int>() << 1 << 2) << QStringLiteral("1.2") << QStringLiteral("1.2-3") << 3 << false;
|
||||
QTest::newRow("0") << (QVector<int>() << 0) << QVersionNumber(QVector<int>() << 0) << QStringLiteral("0") << QStringLiteral("0") << 1 << false;
|
||||
QTest::newRow("0.1") << (QVector<int>() << 0 << 1) << QVersionNumber(QVector<int>() << 0 << 1) << QStringLiteral("0.1") << QStringLiteral("0.1") << 3 << false;
|
||||
QTest::newRow("0.1.2") << (QVector<int>() << 0 << 1 << 2) << QVersionNumber(0, 1, 2) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2") << 5 << false;
|
||||
QTest::newRow("0.1.2alpha") << (QVector<int>() << 0 << 1 << 2) << QVersionNumber(0, 1, 2) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2alpha") << 5 << false;
|
||||
QTest::newRow("0.1.2-alpha") << (QVector<int>() << 0 << 1 << 2) << QVersionNumber(0, 1, 2) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2-alpha") << 5 << false;
|
||||
QTest::newRow("0.1.2.alpha") << (QVector<int>() << 0 << 1 << 2) << QVersionNumber(0, 1, 2) << QStringLiteral("0.1.2") << QStringLiteral("0.1.2.alpha") << 5 << false;
|
||||
QTest::newRow("0.1.2.3.4.alpha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4.alpha") << 9 << false;
|
||||
QTest::newRow("0.1.2.3.4 alpha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4 alpha") << 9 << false;
|
||||
QTest::newRow("0.1.2.3.4 alp ha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4 alp ha") << 9 << false;
|
||||
QTest::newRow("0.1.2.3.4alp ha") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4alp ha") << 9 << false;
|
||||
QTest::newRow("0.1.2.3.4alpha ") << (QVector<int>() << 0 << 1 << 2 << 3 << 4) << QVersionNumber(QVector<int>() << 0 << 1 << 2 << 3 << 4) << QStringLiteral("0.1.2.3.4") << QStringLiteral("0.1.2.3.4alpha ") << 9 << false;
|
||||
QTest::newRow("10.09") << (QVector<int>() << 10 << 9) << QVersionNumber(QVector<int>() << 10 << 9) << QStringLiteral("10.9") << QStringLiteral("10.09") << 5 << false;
|
||||
QTest::newRow("10.0x") << (QVector<int>() << 10 << 0) << QVersionNumber(QVector<int>() << 10 << 0) << QStringLiteral("10.0") << QStringLiteral("10.0x") << 4 << false;
|
||||
QTest::newRow("10.0xTest") << (QVector<int>() << 10 << 0) << QVersionNumber(QVector<int>() << 10 << 0) << QStringLiteral("10.0") << QStringLiteral("10.0xTest") << 4 << false;
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::comparisonData()
|
||||
{
|
||||
QTest::addColumn<QVersionNumber>("lhs");
|
||||
QTest::addColumn<QVersionNumber>("rhs");
|
||||
QTest::addColumn<bool>("equal");
|
||||
QTest::addColumn<bool>("notEqual");
|
||||
QTest::addColumn<bool>("lessThan");
|
||||
QTest::addColumn<bool>("lessThanOrEqual");
|
||||
QTest::addColumn<bool>("greaterThan");
|
||||
QTest::addColumn<bool>("greaterThanOrEqual");
|
||||
QTest::addColumn<int>("compareResult");
|
||||
QTest::addColumn<bool>("isPrefix");
|
||||
QTest::addColumn<QVersionNumber>("common");
|
||||
|
||||
// LHS RHS == != < <= > >= compareResult isPrefixOf commonPrefix
|
||||
QTest::newRow("null, null") << QVersionNumber() << QVersionNumber() << true << false << false << true << false << true << 0 << true << QVersionNumber();
|
||||
QTest::newRow("null, 0") << QVersionNumber() << QVersionNumber(0) << false << true << true << true << false << false << -1 << true << QVersionNumber();
|
||||
QTest::newRow("0, null") << QVersionNumber(0) << QVersionNumber() << false << true << false << false << true << true << 1 << false << QVersionNumber();
|
||||
QTest::newRow("0, 0") << QVersionNumber(0) << QVersionNumber(0) << true << false << false << true << false << true << 0 << true << QVersionNumber(0);
|
||||
QTest::newRow("1.0, 1.0") << QVersionNumber(1, 0) << QVersionNumber(1, 0) << true << false << false << true << false << true << 0 << true << QVersionNumber(1, 0);
|
||||
QTest::newRow("1, 1.0") << QVersionNumber(1) << QVersionNumber(1, 0) << false << true << true << true << false << false << -1 << true << QVersionNumber(1);
|
||||
QTest::newRow("1.0, 1") << QVersionNumber(1, 0) << QVersionNumber(1) << false << true << false << false << true << true << 1 << false << QVersionNumber(1);
|
||||
QTest::newRow("0.1.2, 0.1") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1) << false << true << false << false << true << true << 2 << false << QVersionNumber(0, 1);
|
||||
QTest::newRow("0.1, 0.1.2") << QVersionNumber(0, 1) << QVersionNumber(0, 1, 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(0, 1);
|
||||
QTest::newRow("0.1.2, 0.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1, 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(0, 1, 2);
|
||||
QTest::newRow("0.1.2, 1.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(1, 1, 2) << false << true << true << true << false << false << -1 << false << QVersionNumber();
|
||||
QTest::newRow("1.1.2, 0.1.2") << QVersionNumber(1, 1, 2) << QVersionNumber(0, 1, 2) << false << true << false << false << true << true << 1 << false << QVersionNumber();
|
||||
QTest::newRow("1, -1") << QVersionNumber(1) << QVersionNumber(-1) << false << true << false << false << true << true << 2 << false << QVersionNumber();
|
||||
QTest::newRow("-1, 1") << QVersionNumber(-1) << QVersionNumber(1) << false << true << true << true << false << false << -2 << false << QVersionNumber();
|
||||
QTest::newRow("0.1, 0.-1") << QVersionNumber(0, 1) << QVersionNumber(0, -1) << false << true << false << false << true << true << 2 << false << QVersionNumber(0);
|
||||
QTest::newRow("0.-1, 0.1") << QVersionNumber(0, -1) << QVersionNumber(0, 1) << false << true << true << true << false << false << -2 << false << QVersionNumber(0);
|
||||
QTest::newRow("0.-1, 0") << QVersionNumber(0, -1) << QVersionNumber(0) << false << true << true << true << false << false << -1 << false << QVersionNumber(0);
|
||||
QTest::newRow("0, 0.-1") << QVersionNumber(0) << QVersionNumber(0, -1) << false << true << false << false << true << true << 1 << true << QVersionNumber(0);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::initTestCase()
|
||||
{
|
||||
qRegisterMetaType<QVector<int> >();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::constructorDefault()
|
||||
{
|
||||
QVersionNumber version;
|
||||
|
||||
QCOMPARE(version.majorVersion(), 0);
|
||||
QCOMPARE(version.minorVersion(), 0);
|
||||
QCOMPARE(version.microVersion(), 0);
|
||||
QCOMPARE(version.segments(), QVector<int>());
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::constructorVersioned_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::constructorVersioned()
|
||||
{
|
||||
QFETCH(QVector<int>, segments);
|
||||
QFETCH(QVersionNumber, expectedVersion);
|
||||
|
||||
QVersionNumber version(segments);
|
||||
QCOMPARE(version.majorVersion(), expectedVersion.majorVersion());
|
||||
QCOMPARE(version.minorVersion(), expectedVersion.minorVersion());
|
||||
QCOMPARE(version.microVersion(), expectedVersion.microVersion());
|
||||
QCOMPARE(version.segments(), expectedVersion.segments());
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::constructorExplicit()
|
||||
{
|
||||
QVersionNumber v1(1);
|
||||
QVersionNumber v2(QVector<int>() << 1);
|
||||
|
||||
QCOMPARE(v1.segments(), v2.segments());
|
||||
|
||||
QVersionNumber v3(1, 2);
|
||||
QVersionNumber v4(QVector<int>() << 1 << 2);
|
||||
|
||||
QCOMPARE(v3.segments(), v4.segments());
|
||||
|
||||
QVersionNumber v5(1, 2, 3);
|
||||
QVersionNumber v6(QVector<int>() << 1 << 2 << 3);
|
||||
|
||||
QCOMPARE(v5.segments(), v6.segments());
|
||||
|
||||
#ifdef Q_COMPILER_INITIALIZER_LISTS
|
||||
QVersionNumber v7(4, 5, 6);
|
||||
QVersionNumber v8 = {4, 5, 6};
|
||||
|
||||
QCOMPARE(v7.segments(), v8.segments());
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::constructorCopy_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::constructorCopy()
|
||||
{
|
||||
QFETCH(QVector<int>, segments);
|
||||
QFETCH(QVersionNumber, expectedVersion);
|
||||
|
||||
QVersionNumber original(segments);
|
||||
QVersionNumber version(original);
|
||||
|
||||
QCOMPARE(version.majorVersion(), expectedVersion.majorVersion());
|
||||
QCOMPARE(version.minorVersion(), expectedVersion.minorVersion());
|
||||
QCOMPARE(version.microVersion(), expectedVersion.microVersion());
|
||||
QCOMPARE(version.segments(), expectedVersion.segments());
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareGreater_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareGreater()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(bool, greaterThan);
|
||||
|
||||
QCOMPARE(lhs > rhs, greaterThan);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareGreaterEqual_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareGreaterEqual()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(bool, greaterThanOrEqual);
|
||||
|
||||
QCOMPARE(lhs >= rhs, greaterThanOrEqual);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareLess_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareLess()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(bool, lessThan);
|
||||
|
||||
QCOMPARE(lhs < rhs, lessThan);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareLessEqual_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareLessEqual()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(bool, lessThanOrEqual);
|
||||
|
||||
QCOMPARE(lhs <= rhs, lessThanOrEqual);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareEqual_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareEqual()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(bool, equal);
|
||||
|
||||
QCOMPARE(lhs == rhs, equal);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareNotEqual_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compareNotEqual()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(bool, notEqual);
|
||||
|
||||
QCOMPARE(lhs != rhs, notEqual);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compare_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::compare()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(int, compareResult);
|
||||
|
||||
QCOMPARE(QVersionNumber::compare(lhs, rhs), compareResult);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::isPrefixOf_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::isPrefixOf()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(bool, isPrefix);
|
||||
|
||||
QCOMPARE(lhs.isPrefixOf(rhs), isPrefix);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::commonPrefix_data()
|
||||
{
|
||||
comparisonData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::commonPrefix()
|
||||
{
|
||||
QFETCH(QVersionNumber, lhs);
|
||||
QFETCH(QVersionNumber, rhs);
|
||||
QFETCH(QVersionNumber, common);
|
||||
|
||||
QVersionNumber calculatedPrefix = QVersionNumber::commonPrefix(lhs, rhs);
|
||||
QCOMPARE(calculatedPrefix, common);
|
||||
QCOMPARE(calculatedPrefix.segments(), common.segments());
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::normalized_data()
|
||||
{
|
||||
QTest::addColumn<QVersionNumber>("version");
|
||||
QTest::addColumn<QVersionNumber>("expected");
|
||||
|
||||
QTest::newRow("0") << QVersionNumber(0) << QVersionNumber();
|
||||
QTest::newRow("1") << QVersionNumber(1) << QVersionNumber(1);
|
||||
QTest::newRow("1.2") << QVersionNumber(1, 2) << QVersionNumber(1, 2);
|
||||
QTest::newRow("1.0") << QVersionNumber(1, 0) << QVersionNumber(1);
|
||||
QTest::newRow("1.0.0") << QVersionNumber(1, 0, 0) << QVersionNumber(1);
|
||||
QTest::newRow("1.0.1") << QVersionNumber(1, 0, 1) << QVersionNumber(1, 0, 1);
|
||||
QTest::newRow("1.0.1.0") << QVersionNumber(QVector<int>() << 1 << 0 << 1 << 0) << QVersionNumber(1, 0, 1);
|
||||
QTest::newRow("0.0.1.0") << QVersionNumber(QVector<int>() << 0 << 0 << 1 << 0) << QVersionNumber(0, 0, 1);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::normalized()
|
||||
{
|
||||
QFETCH(QVersionNumber, version);
|
||||
QFETCH(QVersionNumber, expected);
|
||||
|
||||
QCOMPARE(version.normalized(), expected);
|
||||
QCOMPARE(qMove(version).normalized(), expected);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::isNormalized_data()
|
||||
{
|
||||
QTest::addColumn<QVersionNumber>("version");
|
||||
QTest::addColumn<bool>("expected");
|
||||
|
||||
QTest::newRow("null") << QVersionNumber() << true;
|
||||
QTest::newRow("0") << QVersionNumber(0) << false;
|
||||
QTest::newRow("1") << QVersionNumber(1) << true;
|
||||
QTest::newRow("1.2") << QVersionNumber(1, 2) << true;
|
||||
QTest::newRow("1.0") << QVersionNumber(1, 0) << false;
|
||||
QTest::newRow("1.0.0") << QVersionNumber(1, 0, 0) << false;
|
||||
QTest::newRow("1.0.1") << QVersionNumber(1, 0, 1) << true;
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::isNormalized()
|
||||
{
|
||||
QFETCH(QVersionNumber, version);
|
||||
QFETCH(bool, expected);
|
||||
|
||||
QCOMPARE(version.isNormalized(), expected);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::assignment_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::assignment()
|
||||
{
|
||||
QFETCH(QVector<int>, segments);
|
||||
QFETCH(QVersionNumber, expectedVersion);
|
||||
|
||||
QVersionNumber original(segments);
|
||||
QVersionNumber version;
|
||||
version = original;
|
||||
|
||||
QCOMPARE(version.majorVersion(), expectedVersion.majorVersion());
|
||||
QCOMPARE(version.minorVersion(), expectedVersion.minorVersion());
|
||||
QCOMPARE(version.microVersion(), expectedVersion.microVersion());
|
||||
QCOMPARE(version.segments(), expectedVersion.segments());
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::fromString_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::fromString()
|
||||
{
|
||||
QFETCH(QString, constructionString);
|
||||
QFETCH(QVersionNumber, expectedVersion);
|
||||
QFETCH(int, suffixIndex);
|
||||
|
||||
int index;
|
||||
QCOMPARE(QVersionNumber::fromString(constructionString), expectedVersion);
|
||||
QCOMPARE(QVersionNumber::fromString(constructionString, &index), expectedVersion);
|
||||
QCOMPARE(index, suffixIndex);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::toString_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
|
||||
// segments expectedVersion expectedString constructionString suffixIndex null
|
||||
QTest::newRow("-1") << (QVector<int>() << -1) << QVersionNumber(-1) << QString("-1") << QString() << 0 << true;
|
||||
QTest::newRow("-1.0") << (QVector<int>() << -1 << 0) << QVersionNumber(-1, 0) << QString("-1.0") << QString() << 0 << true;
|
||||
QTest::newRow("1.-2") << (QVector<int>() << 1 << -2) << QVersionNumber(1, -2) << QString("1.-2") << QString() << 0 << true;
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::toString()
|
||||
{
|
||||
QFETCH(QVersionNumber, expectedVersion);
|
||||
QFETCH(QString, expectedString);
|
||||
|
||||
QCOMPARE(expectedVersion.toString(), expectedString);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::isNull_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::isNull()
|
||||
{
|
||||
QFETCH(QVector<int>, segments);
|
||||
QFETCH(bool, isNull);
|
||||
|
||||
QVersionNumber version(segments);
|
||||
|
||||
QCOMPARE(version.isNull(), isNull);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::serialize_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::serialize()
|
||||
{
|
||||
QFETCH(QVector<int>, segments);
|
||||
|
||||
QVersionNumber original(segments);
|
||||
QVersionNumber version;
|
||||
|
||||
QByteArray buffer;
|
||||
{
|
||||
QDataStream ostream(&buffer, QIODevice::WriteOnly);
|
||||
ostream << original;
|
||||
}
|
||||
{
|
||||
QDataStream istream(buffer);
|
||||
istream >> version;
|
||||
}
|
||||
|
||||
QCOMPARE(version.majorVersion(), original.majorVersion());
|
||||
QCOMPARE(version.minorVersion(), original.minorVersion());
|
||||
QCOMPARE(version.microVersion(), original.microVersion());
|
||||
QCOMPARE(version.segments(), original.segments());
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::moveSemantics()
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1600
|
||||
# define Q_MSVC_2010
|
||||
#endif
|
||||
#if defined(Q_COMPILER_RVALUE_REFS) && !defined(Q_MSVC_2010)
|
||||
// QVersionNumber(QVersionNumber &&)
|
||||
{
|
||||
QVersionNumber v1(1, 2, 3);
|
||||
QVersionNumber v2 = qMove(v1);
|
||||
QCOMPARE(v2, QVersionNumber(1, 2, 3));
|
||||
}
|
||||
// QVersionNumber &operator=(QVersionNumber &&)
|
||||
{
|
||||
QVersionNumber v1(1, 2, 3);
|
||||
QVersionNumber v2;
|
||||
v2 = qMove(v1);
|
||||
QCOMPARE(v2, QVersionNumber(1, 2, 3));
|
||||
}
|
||||
// QVersionNumber(QVector<int> &&)
|
||||
{
|
||||
QVector<int> segments = QVector<int>() << 1 << 2 << 3;
|
||||
QVersionNumber v1(segments);
|
||||
QVersionNumber v2(qMove(segments));
|
||||
QVERIFY(!v1.isNull());
|
||||
QVERIFY(!v2.isNull());
|
||||
QCOMPARE(v1, v2);
|
||||
}
|
||||
#endif
|
||||
#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(Q_MSVC_2010)
|
||||
// normalized()
|
||||
{
|
||||
QVersionNumber v(1, 0, 0);
|
||||
QVERIFY(!v.isNull());
|
||||
QVersionNumber nv;
|
||||
nv = v.normalized();
|
||||
QVERIFY(!v.isNull());
|
||||
QVERIFY(!nv.isNull());
|
||||
QVERIFY(nv.isNormalized());
|
||||
nv = qMove(v).normalized();
|
||||
QVERIFY(!nv.isNull());
|
||||
QVERIFY(nv.isNormalized());
|
||||
}
|
||||
// segments()
|
||||
{
|
||||
QVersionNumber v(1, 2, 3);
|
||||
QVERIFY(!v.isNull());
|
||||
QVector<int> segments;
|
||||
segments = v.segments();
|
||||
QVERIFY(!v.isNull());
|
||||
QVERIFY(!segments.empty());
|
||||
segments = qMove(v).segments();
|
||||
QVERIFY(!segments.empty());
|
||||
}
|
||||
#endif
|
||||
#if !defined(Q_COMPILER_RVALUE_REFS) && !defined(Q_COMPILER_REF_QUALIFIERS) && !defined(Q_MSVC_2010)
|
||||
QSKIP("This test requires C++11 move semantics support in the compiler.");
|
||||
#elif defined(Q_MSVC_2010)
|
||||
QSKIP("This test requires compiler generated move constructors and operators.");
|
||||
#endif
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QVersionNumber)
|
||||
|
||||
#include "tst_qversionnumber.moc"
|
@ -59,4 +59,6 @@ SUBDIRS=\
|
||||
qtimeline \
|
||||
qvarlengtharray \
|
||||
qvector \
|
||||
qvector_strictiterators
|
||||
qvector_strictiterators \
|
||||
qversionnumber
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user