From 91ab18c0c9c1ef3a44ec4a0dda98f3d44579fd89 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 27 Aug 2014 11:53:47 +0200 Subject: QKeySequence: use QKeySequencePrivate::MaxKeyCount everywhere The MaxKeyCount symbolic constant was introduced for use by QKeySequenceEdit, but never applied to QKeySequence itself. To prevent the two from getting out of sync, use it in the QKeySequence implementation itself, too. This required re-writing most expressions involving QKeySequenceEditPrivate::keys with algorithms, but we already determined in the discussion around 1cf9a139 that GCC generates the same code as the loops unrolled by hand, and if Clang doesn't, it's its own fault. Where using MaxKeysCount was not possible, e.g. in documentation, static_asserts were used to indicate the need for manual changes. Change-Id: I559fffdfd552d488448ba4a5a1ac10708c16a2ae Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/kernel/qkeysequence.cpp | 26 +++++++++----------------- src/gui/kernel/qkeysequence_p.h | 13 ++++++------- 2 files changed, 15 insertions(+), 24 deletions(-) (limited to 'src/gui') diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 275066ab03..2e6bbfd5e1 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -819,6 +819,7 @@ QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat form assign(key, format); } +Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Change docs and ctor impl below"); /*! Constructs a key sequence with up to 4 keys \a k1, \a k2, \a k3 and \a k4. @@ -877,26 +878,19 @@ QKeySequence::~QKeySequence() void QKeySequence::setKey(int key, int index) { - Q_ASSERT_X(index >= 0 && index < 4, "QKeySequence::setKey", "index out of range"); + Q_ASSERT_X(index >= 0 && index < QKeySequencePrivate::MaxKeyCount, "QKeySequence::setKey", "index out of range"); qAtomicDetach(d); d->key[index] = key; } +Q_STATIC_ASSERT_X(QKeySequencePrivate::MaxKeyCount == 4, "Change docs below"); /*! Returns the number of keys in the key sequence. The maximum is 4. */ int QKeySequence::count() const { - if (!d->key[0]) - return 0; - if (!d->key[1]) - return 1; - if (!d->key[2]) - return 2; - if (!d->key[3]) - return 3; - return 4; + return int(std::distance(d->key, std::find(d->key, d->key + QKeySequencePrivate::MaxKeyCount, 0))); } @@ -988,8 +982,8 @@ int QKeySequence::assign(const QString &ks, QKeySequence::SequenceFormat format) int p = 0, diff = 0; // Run through the whole string, but stop - // if we have 4 keys before the end. - while (keyseq.length() && n < 4) { + // if we have MaxKeyCount keys before the end. + while (keyseq.length() && n < QKeySequencePrivate::MaxKeyCount) { // We MUST use something to separate each sequence, and space // does not cut it, since some of the key names have space // in them.. (Let's hope no one translate with a comma in it:) @@ -1367,7 +1361,7 @@ QKeySequence::operator QVariant() const */ int QKeySequence::operator[](uint index) const { - Q_ASSERT_X(index < 4, "QKeySequence::operator[]", "index out of range"); + Q_ASSERT_X(index < QKeySequencePrivate::MaxKeyCount, "QKeySequence::operator[]", "index out of range"); return d->key[index]; } @@ -1435,10 +1429,8 @@ uint qHash(const QKeySequence &key, uint seed) Q_DECL_NOTHROW */ bool QKeySequence::operator< (const QKeySequence &other) const { - for (int i = 0; i < 4; ++i) - if (d->key[i] != other.d->key[i]) - return d->key[i] < other.d->key[i]; - return false; + return std::lexicographical_compare(d->key, d->key + QKeySequencePrivate::MaxKeyCount, + other.d->key, other.d->key + QKeySequencePrivate::MaxKeyCount); } /*! diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h index 97416943d0..3e4c5bae88 100644 --- a/src/gui/kernel/qkeysequence_p.h +++ b/src/gui/kernel/qkeysequence_p.h @@ -47,6 +47,8 @@ #include "qkeysequence.h" +#include + QT_BEGIN_NAMESPACE #ifndef QT_NO_SHORTCUT @@ -61,20 +63,17 @@ struct Q_AUTOTEST_EXPORT QKeyBinding class Q_AUTOTEST_EXPORT QKeySequencePrivate { public: - enum { MaxKeyCount = 4 }; // used in QKeySequenceEdit + enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit inline QKeySequencePrivate() : ref(1) { - key[0] = key[1] = key[2] = key[3] = 0; + std::fill_n(key, uint(MaxKeyCount), 0); } inline QKeySequencePrivate(const QKeySequencePrivate ©) : ref(1) { - key[0] = copy.key[0]; - key[1] = copy.key[1]; - key[2] = copy.key[2]; - key[3] = copy.key[3]; + std::copy(copy.key, copy.key + MaxKeyCount, key); } QAtomicInt ref; - int key[4]; + int key[MaxKeyCount]; static QString encodeString(int key, QKeySequence::SequenceFormat format); static int decodeString(const QString &keyStr, QKeySequence::SequenceFormat format); }; -- cgit v1.2.3