qset.h
上传用户:detong
上传日期:2022-06-22
资源大小:20675k
文件大小:13k
源码类别:

系统编程

开发平台:

Unix_Linux

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  4. ** Contact: Qt Software Information (qt-info@nokia.com)
  5. **
  6. ** This file is part of the QtCore module of the Qt Toolkit.
  7. **
  8. ** Commercial Usage
  9. ** Licensees holding valid Qt Commercial licenses may use this file in
  10. ** accordance with the Qt Commercial License Agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Nokia.
  13. **
  14. **
  15. ** GNU General Public License Usage
  16. ** Alternatively, this file may be used under the terms of the GNU
  17. ** General Public License versions 2.0 or 3.0 as published by the Free
  18. ** Software Foundation and appearing in the file LICENSE.GPL included in
  19. ** the packaging of this file.  Please review the following information
  20. ** to ensure GNU General Public Licensing requirements will be met:
  21. ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
  22. ** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
  23. ** exception, Nokia gives you certain additional rights. These rights
  24. ** are described in the Nokia Qt GPL Exception version 1.3, included in
  25. ** the file GPL_EXCEPTION.txt in this package.
  26. **
  27. ** Qt for Windows(R) Licensees
  28. ** As a special exception, Nokia, as the sole copyright holder for Qt
  29. ** Designer, grants users of the Qt/Eclipse Integration plug-in the
  30. ** right for the Qt/Eclipse Integration to link to functionality
  31. ** provided by Qt Designer and its related libraries.
  32. **
  33. ** If you are unsure which license is appropriate for your use, please
  34. ** contact the sales department at qt-sales@nokia.com.
  35. **
  36. ****************************************************************************/
  37. #ifndef QSET_H
  38. #define QSET_H
  39. #include <QtCore/qhash.h>
  40. QT_BEGIN_HEADER
  41. QT_BEGIN_NAMESPACE
  42. QT_MODULE(Core)
  43. template <class T>
  44. class QSet
  45. {
  46.     typedef QHash<T, QHashDummyValue> Hash;
  47. public:
  48.     inline QSet() {}
  49.     inline QSet(const QSet<T> &other) : q_hash(other.q_hash) {}
  50.     inline QSet<T> &operator=(const QSet<T> &other)
  51.         { q_hash = other.q_hash; return *this; }
  52.     inline bool operator==(const QSet<T> &other) const
  53.         { return q_hash == other.q_hash; }
  54.     inline bool operator!=(const QSet<T> &other) const
  55.         { return q_hash != other.q_hash; }
  56.     inline int size() const { return q_hash.size(); }
  57.     inline bool isEmpty() const { return q_hash.isEmpty(); }
  58.     inline int capacity() const { return q_hash.capacity(); }
  59.     inline void reserve(int size);
  60.     inline void squeeze() { q_hash.squeeze(); }
  61.     inline void detach() { q_hash.detach(); }
  62.     inline bool isDetached() const { return q_hash.isDetached(); }
  63.     inline void setSharable(bool sharable) { q_hash.setSharable(sharable); }
  64.     inline void clear() { q_hash.clear(); }
  65.     inline bool remove(const T &value) { return q_hash.remove(value) != 0; }
  66.     inline bool contains(const T &value) const { return q_hash.contains(value); }
  67.     class const_iterator;
  68.     class iterator
  69.     {
  70.         typedef QHash<T, QHashDummyValue> Hash;
  71.         typename Hash::iterator i;
  72.         friend class const_iterator;
  73.     public:
  74.         typedef std::bidirectional_iterator_tag iterator_category;
  75.         typedef ptrdiff_t difference_type;
  76.         typedef T value_type;
  77.         typedef const T *pointer;
  78.         typedef const T &reference;
  79.         inline iterator() {}
  80.         inline iterator(typename Hash::iterator o) : i(o) {}
  81.         inline iterator(const iterator &o) : i(o.i) {}
  82.         inline iterator &operator=(const iterator &o) { i = o.i; return *this; }
  83.         inline const T &operator*() const { return i.key(); }
  84.         inline const T *operator->() const { return &i.key(); }
  85.         inline bool operator==(const iterator &o) const { return i == o.i; }
  86.         inline bool operator!=(const iterator &o) const { return i != o.i; }
  87.         inline bool operator==(const const_iterator &o) const
  88.             { return i == o.i; }
  89.         inline bool operator!=(const const_iterator &o) const
  90.             { return i != o.i; }
  91.         inline iterator &operator++() { ++i; return *this; }
  92.         inline iterator operator++(int) { iterator r = *this; ++i; return r; }
  93.         inline iterator &operator--() { --i; return *this; }
  94.         inline iterator operator--(int) { iterator r = *this; --i; return r; }
  95.         inline iterator operator+(int j) const { return i + j; }
  96.         inline iterator operator-(int j) const { return i - j; }
  97.         inline iterator &operator+=(int j) { i += j; return *this; }
  98.         inline iterator &operator-=(int j) { i -= j; return *this; }
  99.     };
  100.     class const_iterator
  101.     {
  102.         typedef QHash<T, QHashDummyValue> Hash;
  103.         typename Hash::const_iterator i;
  104.         friend class iterator;
  105.     public:
  106.         typedef std::bidirectional_iterator_tag iterator_category;
  107.         typedef ptrdiff_t difference_type;
  108.         typedef T value_type;
  109.         typedef const T *pointer;
  110.         typedef const T &reference;
  111.         inline const_iterator() {}
  112.         inline const_iterator(typename Hash::const_iterator o) : i(o) {}
  113.         inline const_iterator(const const_iterator &o) : i(o.i) {}
  114.         inline const_iterator(const iterator &o)
  115.             : i(o.i) {}
  116.         inline const_iterator &operator=(const const_iterator &o) { i = o.i; return *this; }
  117.         inline const T &operator*() const { return i.key(); }
  118.         inline const T *operator->() const { return &i.key(); }
  119.         inline bool operator==(const const_iterator &o) const { return i == o.i; }
  120.         inline bool operator!=(const const_iterator &o) const { return i != o.i; }
  121.         inline const_iterator &operator++() { ++i; return *this; }
  122.         inline const_iterator operator++(int) { const_iterator r = *this; ++i; return r; }
  123.         inline const_iterator &operator--() { --i; return *this; }
  124.         inline const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
  125.         inline const_iterator operator+(int j) const { return i + j; }
  126.         inline const_iterator operator-(int j) const { return i - j; }
  127.         inline const_iterator &operator+=(int j) { i += j; return *this; }
  128.         inline const_iterator &operator-=(int j) { i -= j; return *this; }
  129.     };
  130.     // STL style
  131.     inline iterator begin() { return q_hash.begin(); }
  132.     inline const_iterator begin() const { return q_hash.begin(); }
  133.     inline const_iterator constBegin() const { return q_hash.constBegin(); }
  134.     inline iterator end() { return q_hash.end(); }
  135.     inline const_iterator end() const { return q_hash.end(); }
  136.     inline const_iterator constEnd() const { return q_hash.constEnd(); }
  137.     iterator erase(iterator i)
  138.         { return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i)); }
  139.     // more Qt
  140.     typedef iterator Iterator;
  141.     typedef const_iterator ConstIterator;
  142.     inline int count() const { return q_hash.count(); }
  143.     inline const_iterator insert(const T &value) // ### Qt 5: should return an 'iterator'
  144.         { return static_cast<typename Hash::const_iterator>(q_hash.insert(value,
  145.                                                                           QHashDummyValue())); }
  146.     iterator find(const T &value) { return q_hash.find(value); }
  147.     const_iterator find(const T &value) const { return q_hash.find(value); }
  148.     inline const_iterator constFind(const T &value) const { return find(value); }
  149.     QSet<T> &unite(const QSet<T> &other);
  150.     QSet<T> &intersect(const QSet<T> &other);
  151.     QSet<T> &subtract(const QSet<T> &other);
  152.     // STL compatibility
  153.     typedef T key_type;
  154.     typedef T value_type;
  155.     typedef value_type *pointer;
  156.     typedef const value_type *const_pointer;
  157.     typedef value_type &reference;
  158.     typedef const value_type &const_reference;
  159.     typedef ptrdiff_t difference_type;
  160.     typedef int size_type;
  161.     inline bool empty() const { return isEmpty(); }
  162.     // comfort
  163.     inline QSet<T> &operator<<(const T &value) { insert(value); return *this; }
  164.     inline QSet<T> &operator|=(const QSet<T> &other) { unite(other); return *this; }
  165.     inline QSet<T> &operator|=(const T &value) { insert(value); return *this; }
  166.     inline QSet<T> &operator&=(const QSet<T> &other) { intersect(other); return *this; }
  167.     inline QSet<T> &operator&=(const T &value)
  168.         { QSet<T> result; if (contains(value)) result.insert(value); return (*this = result); }
  169.     inline QSet<T> &operator+=(const QSet<T> &other) { unite(other); return *this; }
  170.     inline QSet<T> &operator+=(const T &value) { insert(value); return *this; }
  171.     inline QSet<T> &operator-=(const QSet<T> &other) { subtract(other); return *this; }
  172.     inline QSet<T> &operator-=(const T &value) { remove(value); return *this; }
  173.     inline QSet<T> operator|(const QSet<T> &other) const
  174.         { QSet<T> result = *this; result |= other; return result; }
  175.     inline QSet<T> operator&(const QSet<T> &other) const
  176.         { QSet<T> result = *this; result &= other; return result; }
  177.     inline QSet<T> operator+(const QSet<T> &other) const
  178.         { QSet<T> result = *this; result += other; return result; }
  179.     inline QSet<T> operator-(const QSet<T> &other) const
  180.         { QSet<T> result = *this; result -= other; return result; }
  181. #if QT_VERSION < 0x050000
  182.     // ### Qt 5: remove
  183.     inline QSet<T> operator|(const QSet<T> &other)
  184.         { QSet<T> result = *this; result |= other; return result; }
  185.     inline QSet<T> operator&(const QSet<T> &other)
  186.         { QSet<T> result = *this; result &= other; return result; }
  187.     inline QSet<T> operator+(const QSet<T> &other)
  188.         { QSet<T> result = *this; result += other; return result; }
  189.     inline QSet<T> operator-(const QSet<T> &other)
  190.         { QSet<T> result = *this; result -= other; return result; }
  191. #endif
  192.     QList<T> toList() const;
  193.     inline QList<T> values() const { return toList(); }
  194.     static QSet<T> fromList(const QList<T> &list);
  195. private:
  196.     Hash q_hash;
  197. };
  198. template <class T>
  199. Q_INLINE_TEMPLATE void QSet<T>::reserve(int asize) { q_hash.reserve(asize); }
  200. template <class T>
  201. Q_INLINE_TEMPLATE QSet<T> &QSet<T>::unite(const QSet<T> &other)
  202. {
  203.     QSet<T> copy(other);
  204.     typename QSet<T>::const_iterator i = copy.constEnd();
  205.     while (i != copy.constBegin()) {
  206.         --i;
  207.         insert(*i);
  208.     }
  209.     return *this;
  210. }
  211. template <class T>
  212. Q_INLINE_TEMPLATE QSet<T> &QSet<T>::intersect(const QSet<T> &other)
  213. {
  214.     QSet<T> copy1(*this);
  215.     QSet<T> copy2(other);
  216.     typename QSet<T>::const_iterator i = copy1.constEnd();
  217.     while (i != copy1.constBegin()) {
  218.         --i;
  219.         if (!copy2.contains(*i))
  220.             remove(*i);
  221.     }
  222.     return *this;
  223. }
  224. template <class T>
  225. Q_INLINE_TEMPLATE QSet<T> &QSet<T>::subtract(const QSet<T> &other)
  226. {
  227.     QSet<T> copy1(*this);
  228.     QSet<T> copy2(other);
  229.     typename QSet<T>::const_iterator i = copy1.constEnd();
  230.     while (i != copy1.constBegin()) {
  231.         --i;
  232.         if (copy2.contains(*i))
  233.             remove(*i);
  234.     }
  235.     return *this;
  236. }
  237. template <typename T>
  238. Q_OUTOFLINE_TEMPLATE QList<T> QSet<T>::toList() const
  239. {
  240.     QList<T> result;
  241.     typename QSet<T>::const_iterator i = constBegin();
  242.     while (i != constEnd()) {
  243.         result.append(*i);
  244.         ++i;
  245.     }
  246.     return result;
  247. }
  248. template <typename T>
  249. Q_OUTOFLINE_TEMPLATE QSet<T> QList<T>::toSet() const
  250. {
  251.     QSet<T> result;
  252.     result.reserve(size());
  253.     for (int i = 0; i < size(); ++i)
  254.         result.insert(at(i));
  255.     return result;
  256. }
  257. template <typename T>
  258. QSet<T> QSet<T>::fromList(const QList<T> &list)
  259. {
  260.     return list.toSet();
  261. }
  262. template <typename T>
  263. QList<T> QList<T>::fromSet(const QSet<T> &set)
  264. {
  265.     return set.toList();
  266. }
  267. Q_DECLARE_SEQUENTIAL_ITERATOR(Set)
  268. template <typename T>
  269. class QMutableSetIterator
  270. {
  271.     typedef typename QSet<T>::iterator iterator;
  272.     QSet<T> *c;
  273.     iterator i, n;
  274.     inline bool item_exists() const { return n != c->constEnd(); }
  275. public:
  276.     inline QMutableSetIterator(QSet<T> &container)
  277.         : c(&container)
  278.     { c->setSharable(false); i = c->begin(); n = c->end(); }
  279.     inline ~QMutableSetIterator()
  280.     { c->setSharable(true); }
  281.     inline QMutableSetIterator &operator=(QSet<T> &container)
  282.     { c->setSharable(true); c = &container; c->setSharable(false);
  283.       i = c->begin(); n = c->end(); return *this; }
  284.     inline void toFront() { i = c->begin(); n = c->end(); }
  285.     inline void toBack() { i = c->end(); n = i; }
  286.     inline bool hasNext() const { return c->constEnd() != i; }
  287.     inline const T &next() { n = i++; return *n; }
  288.     inline const T &peekNext() const { return *i; }
  289.     inline bool hasPrevious() const { return c->constBegin() != i; }
  290.     inline const T &previous() { n = --i; return *n; }
  291.     inline const T &peekPrevious() const { iterator p = i; return *--p; }
  292.     inline void remove()
  293.     { if (c->constEnd() != n) { i = c->erase(n); n = c->end(); } }
  294.     inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
  295.     inline bool findNext(const T &t)
  296.     { while (c->constEnd() != (n = i)) if (*i++ == t) return true; return false; }
  297.     inline bool findPrevious(const T &t)
  298.     { while (c->constBegin() != i) if (*(n = --i) == t) return true;
  299.       n = c->end(); return false;  }
  300. };
  301. QT_END_NAMESPACE
  302. QT_END_HEADER
  303. #endif // QSET_H