Polish up the QOperatingSystemVersion API and documentation

operator== and operator!= have been disabled, as they are likely to be
misused and are not particularly useful in practice. The same goes for
the QVersionNumber conversion convenience functions.

The constructor normalizes version component values so that invalid
versions like [5, -1, 3] cannot be constructed and made to wreak havoc
on assumed logic.

Change-Id: Iabb6876bd5dc11522032837f78cf825b921a49b2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Jake Petroules 2017-01-13 20:20:22 -08:00
parent 2fe9f30512
commit ae072cd9c4
2 changed files with 64 additions and 66 deletions

View File

@ -98,6 +98,33 @@ QT_BEGIN_NAMESPACE
GetVersionEx that hides the real version number if the
application is not manifested for that version of the OS
\endtable
Because QOperatingSystemVersion stores both a version number and an OS type, the OS type
can be taken into account when performing comparisons. For example, on a macOS system running
macOS Sierra (v10.12), the following expression will return \c false even though the
major version number component of the object on the left hand side of the expression (10) is
greater than that of the object on the right (9):
\code
QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9)
\endcode
This allows expressions for multiple operating systems to be joined with a logical OR operator
and still work as expected. For example:
\code
auto current = QOperatingSystemVersion::current();
if (current >= QOperatingSystemVersion::OSXYosemite ||
current >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) {
// returns true on macOS >= 10.10 and iOS >= 8.0, but false on macOS < 10.10 and iOS < 8.0
}
\encode
A more naive comparison algorithm might incorrectly return true on all versions of macOS,
including Mac OS 9. This behavior is achieved by overloading the comparison operators to return
\c false whenever the OS types of the QOperatingSystemVersion instances being compared do not
match. Be aware that due to this it can be the case \c x >= y and \c x < y are BOTH \c false
for the same instances of \c x and \c y.
*/
/*!
@ -111,7 +138,7 @@ QT_BEGIN_NAMESPACE
\value MacOS The Apple macOS operating system.
\value TvOS The Apple tvOS operating system.
\value WatchOS The Apple watchOS operating system.
\value Windows The Microsoft Windows operating system (in both Win32 and WinRT environments).
\value Windows The Microsoft Windows operating system.
\value Unknown An unknown or unsupported operating system.
*/
@ -200,21 +227,6 @@ static inline int compareVersionComponents(int lhs, int rhs)
return lhs >= 0 && rhs >= 0 ? lhs - rhs : 0;
}
/*!
\fn int QOperatingSystemVersion::compare(const QOperatingSystemVersion &v1,
const QOperatingSystemVersion &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 version number components of
\a v1 and \a v2.
\note This function cannot take the OS type into account; you should use
the overloaded comparison operators to compare QOperatingSystemVersions
in a safe manner.
*/
int QOperatingSystemVersion::compare(const QOperatingSystemVersion &v1,
const QOperatingSystemVersion &v2)
{
@ -227,30 +239,6 @@ int QOperatingSystemVersion::compare(const QOperatingSystemVersion &v1,
return compareVersionComponents(v1.m_major, v2.m_major);
}
#ifndef QT_BOOTSTRAPPED
/*!
\fn QOperatingSystemVersion QOperatingSystemVersion::fromVersionNumber(const QVersionNumber &version,
QOperatingSystemVersion::OSType os)
Returns a QOperatingSystemVersion consisting of the OS type \a os and version number \a version.
*/
QOperatingSystemVersion QOperatingSystemVersion::fromVersionNumber(const QVersionNumber &version,
QOperatingSystemVersion::OSType os)
{
return QOperatingSystemVersion(os, version.majorVersion(), version.minorVersion(), version.microVersion());
}
/*!
\fn QOperatingSystemVersion QOperatingSystemVersion::toVersionNumber() const
Returns the QOperatingSystemVersion's version number as a QVersionNumber.
*/
QVersionNumber QOperatingSystemVersion::toVersionNumber() const
{
return QVersionNumber(m_major, m_minor, m_micro);
}
#endif
/*!
\fn int QOperatingSystemVersion::majorVersion() const
@ -339,6 +327,21 @@ QString QOperatingSystemVersion::name() const
}
}
/*!
\fn bool QOperatingSystemVersion::isAnyOfType(std::initializer_list<OSType> types) const
Returns whether the OS type identified by the QOperatingSystemVersion
matches any of the OS types in \a types.
*/
bool QOperatingSystemVersion::isAnyOfType(std::initializer_list<OSType> types) const
{
for (const auto &t : qAsConst(types)) {
if (type() == t)
return true;
}
return false;
}
/*!
\variable QOperatingSystemVersion::Windows7
\brief a version corresponding to Windows 7 (version 6.1).

View File

@ -84,51 +84,46 @@ public:
Q_DECL_CONSTEXPR QOperatingSystemVersion(OSType osType,
int vmajor, int vminor = -1, int vmicro = -1)
: m_os(osType),
m_major(vmajor),
m_minor(vminor),
m_micro(vmicro)
m_major(qMax(-1, vmajor)),
m_minor(vmajor < 0 ? -1 : qMax(-1, vminor)),
m_micro(vmajor < 0 || vminor < 0 ? -1 : qMax(-1, vmicro))
{ }
static QOperatingSystemVersion current();
static int compare(const QOperatingSystemVersion &v1, const QOperatingSystemVersion &v2);
QOperatingSystemVersion fromVersionNumber(const QVersionNumber &version, OSType os);
QVersionNumber toVersionNumber() const;
Q_DECL_CONSTEXPR int majorVersion() const { return m_major; }
Q_DECL_CONSTEXPR int minorVersion() const { return m_minor; }
Q_DECL_CONSTEXPR int microVersion() const { return m_micro; }
Q_DECL_CONSTEXPR int segmentCount() const
{ return m_micro >= 0 ? 3 : m_minor >= 0 ? 2 : m_major >= 0 ? 1 : 0; }
bool isAnyOfType(std::initializer_list<OSType> types) const;
Q_DECL_CONSTEXPR OSType type() const { return m_os; }
QString name() const;
friend bool operator>(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) > 0; }
friend bool operator>=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) >= 0; }
friend bool operator<(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) < 0; }
friend bool operator<=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) <= 0; }
private:
QOperatingSystemVersion() = default;
OSType m_os;
int m_major;
int m_minor;
int m_micro;
static int compare(const QOperatingSystemVersion &v1, const QOperatingSystemVersion &v2);
};
inline bool operator>(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) > 0; }
inline bool operator>=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) >= 0; }
inline bool operator<(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) < 0; }
inline bool operator<=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) <= 0; }
inline bool operator==(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return lhs.type() == rhs.type() && QOperatingSystemVersion::compare(lhs, rhs) == 0; }
inline bool operator!=(const QOperatingSystemVersion &lhs, const QOperatingSystemVersion &rhs)
{ return !(lhs == rhs); }
QT_END_NAMESPACE
#endif // QOPERATINGSYSTEMVERSION_H