diff options
Diffstat (limited to 'src/corelib/tools/qset.h')
-rw-r--r-- | src/corelib/tools/qset.h | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index e4688711d6..3f4208e8b3 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -39,6 +39,8 @@ #include <initializer_list> #endif +#include <iterator> + QT_BEGIN_NAMESPACE @@ -48,7 +50,7 @@ class QSet typedef QHash<T, QHashDummyValue> Hash; public: - inline QSet() {} + inline QSet() Q_DECL_NOTHROW {} #ifdef Q_COMPILER_INITIALIZER_LISTS inline QSet(std::initializer_list<T> list) { @@ -57,16 +59,10 @@ public: insert(*it); } #endif - inline QSet(const QSet<T> &other) : q_hash(other.q_hash) {} - - inline QSet<T> &operator=(const QSet<T> &other) - { q_hash = other.q_hash; return *this; } -#ifdef Q_COMPILER_RVALUE_REFS - inline QSet(QSet &&other) : q_hash(qMove(other.q_hash)) {} - inline QSet<T> &operator=(QSet<T> &&other) - { qSwap(q_hash, other.q_hash); return *this; } -#endif - inline void swap(QSet<T> &other) { q_hash.swap(other.q_hash); } + // compiler-generated copy/move ctor/assignment operators are fine! + // compiler-generated destructor is fine! + + inline void swap(QSet<T> &other) Q_DECL_NOTHROW { q_hash.swap(other.q_hash); } inline bool operator==(const QSet<T> &other) const { return q_hash == other.q_hash; } @@ -137,6 +133,7 @@ public: typedef QHash<T, QHashDummyValue> Hash; typename Hash::const_iterator i; friend class iterator; + friend class QSet<T>; public: typedef std::bidirectional_iterator_tag iterator_category; @@ -166,14 +163,25 @@ public: }; // STL style + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + inline iterator begin() { return q_hash.begin(); } - inline const_iterator begin() const { return q_hash.begin(); } - inline const_iterator cbegin() const { return q_hash.begin(); } - inline const_iterator constBegin() const { return q_hash.constBegin(); } + inline const_iterator begin() const Q_DECL_NOTHROW { return q_hash.begin(); } + inline const_iterator cbegin() const Q_DECL_NOTHROW { return q_hash.begin(); } + inline const_iterator constBegin() const Q_DECL_NOTHROW { return q_hash.constBegin(); } inline iterator end() { return q_hash.end(); } - inline const_iterator end() const { return q_hash.end(); } - inline const_iterator cend() const { return q_hash.end(); } - inline const_iterator constEnd() const { return q_hash.constEnd(); } + inline const_iterator end() const Q_DECL_NOTHROW { return q_hash.end(); } + inline const_iterator cend() const Q_DECL_NOTHROW { return q_hash.end(); } + inline const_iterator constEnd() const Q_DECL_NOTHROW { return q_hash.constEnd(); } + + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); } + const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); } + const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); } + const_reverse_iterator crend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); } + iterator erase(iterator i) { Q_ASSERT_X(isValidIterator(i), "QSet::erase", "The specified const_iterator argument 'i' is invalid"); @@ -191,6 +199,7 @@ public: inline const_iterator constFind(const T &value) const { return find(value); } QSet<T> &unite(const QSet<T> &other); QSet<T> &intersect(const QSet<T> &other); + bool intersects(const QSet<T> &other) const; QSet<T> &subtract(const QSet<T> &other); // STL compatibility @@ -284,6 +293,34 @@ Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other) } template <class T> +Q_INLINE_TEMPLATE bool QSet<T>::intersects(const QSet<T> &other) const +{ + const bool otherIsBigger = other.size() > size(); + const QSet &smallestSet = otherIsBigger ? *this : other; + const QSet &biggestSet = otherIsBigger ? other : *this; + const bool equalSeeds = q_hash.d->seed == other.q_hash.d->seed; + typename QSet::const_iterator i = smallestSet.cbegin(); + typename QSet::const_iterator e = smallestSet.cend(); + + if (Q_LIKELY(equalSeeds)) { + // If seeds are equal we take the fast path so no hash is recalculated. + while (i != e) { + if (*biggestSet.q_hash.findNode(*i, i.i.i->h) != biggestSet.q_hash.e) + return true; + ++i; + } + } else { + while (i != e) { + if (biggestSet.contains(*i)) + return true; + ++i; + } + } + + return false; +} + +template <class T> Q_INLINE_TEMPLATE QSet<T> &QSet<T>::subtract(const QSet<T> &other) { QSet<T> copy1(*this); |