summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@qt.io>2017-01-13 20:20:22 -0800
committerJake Petroules <jake.petroules@qt.io>2017-01-18 05:15:01 +0000
commitae072cd9c4a575e0ed3f073c6ab395ccdf7c2b37 (patch)
treec86dc0ef7d038e98ff271b765ad3086d0befd7ad /src
parent2fe9f30512092cfb1928feaa9d3c56025c74f92a (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp83
-rw-r--r--src/corelib/global/qoperatingsystemversion.h47
2 files changed, 64 insertions, 66 deletions
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
index 8b8f47575d..0cfc70a790 100644
--- a/src/corelib/global/qoperatingsystemversion.cpp
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -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
@@ -340,6 +328,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).
\since 5.9
diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h
index e3318a9c60..cc14d701e1 100644
--- a/src/corelib/global/qoperatingsystemversion.h
+++ b/src/corelib/global/qoperatingsystemversion.h
@@ -84,50 +84,45 @@ 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;
-};
-
-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); }
+ static int compare(const QOperatingSystemVersion &v1, const QOperatingSystemVersion &v2);
+};
QT_END_NAMESPACE