ordered_set.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include <QtCore/QMap>
  9. // ordered set template based on QMap
  10. template <typename T>
  11. class OrderedSet {
  12. struct NullType {
  13. };
  14. using Self = OrderedSet<T>;
  15. using Impl = QMap<T, NullType>;
  16. using IteratorImpl = typename Impl::iterator;
  17. using ConstIteratorImpl = typename Impl::const_iterator;
  18. Impl impl_;
  19. public:
  20. OrderedSet() = default;
  21. OrderedSet(const OrderedSet &other) = default;
  22. OrderedSet(OrderedSet &&other) = default;
  23. OrderedSet &operator=(const OrderedSet &other) = default;
  24. OrderedSet &operator=(OrderedSet &&other) = default;
  25. ~OrderedSet() = default;
  26. inline bool operator==(const Self &other) const { return impl_ == other.impl_; }
  27. inline bool operator!=(const Self &other) const { return impl_ != other.impl_; }
  28. inline int size() const { return impl_.size(); }
  29. inline bool isEmpty() const { return impl_.isEmpty(); }
  30. inline void detach() { return impl_.detach(); }
  31. inline bool isDetached() const { return impl_.isDetached(); }
  32. inline void clear() { return impl_.clear(); }
  33. inline QList<T> values() const { return impl_.keys(); }
  34. inline const T &first() const { return impl_.firstKey(); }
  35. inline const T &last() const { return impl_.lastKey(); }
  36. class const_iterator;
  37. class iterator {
  38. public:
  39. typedef typename IteratorImpl::iterator_category iterator_category;
  40. typedef typename IteratorImpl::difference_type difference_type;
  41. typedef T value_type;
  42. typedef T *pointer;
  43. typedef T &reference;
  44. iterator() = default;
  45. iterator(const iterator &other) = default;
  46. iterator &operator=(const iterator &other) = default;
  47. inline const T &operator*() const { return impl_.key(); }
  48. inline const T *operator->() const { return &impl_.key(); }
  49. inline bool operator==(const iterator &other) const { return impl_ == other.impl_; }
  50. inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; }
  51. inline iterator &operator++() { ++impl_; return *this; }
  52. inline iterator operator++(int) { return iterator(impl_++); }
  53. inline iterator &operator--() { --impl_; return *this; }
  54. inline iterator operator--(int) { return iterator(impl_--); }
  55. inline iterator operator+(int j) const { return iterator(impl_ + j); }
  56. inline iterator operator-(int j) const { return iterator(impl_ - j); }
  57. inline iterator &operator+=(int j) { impl_ += j; return *this; }
  58. inline iterator &operator-=(int j) { impl_ -= j; return *this; }
  59. friend class const_iterator;
  60. inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; }
  61. inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; }
  62. private:
  63. explicit iterator(const IteratorImpl &impl) : impl_(impl) {
  64. }
  65. IteratorImpl impl_;
  66. friend class OrderedSet<T>;
  67. };
  68. friend class iterator;
  69. class const_iterator {
  70. public:
  71. typedef typename IteratorImpl::iterator_category iterator_category;
  72. typedef typename IteratorImpl::difference_type difference_type;
  73. typedef T value_type;
  74. typedef T *pointer;
  75. typedef T &reference;
  76. const_iterator() = default;
  77. const_iterator(const const_iterator &other) = default;
  78. const_iterator &operator=(const const_iterator &other) = default;
  79. const_iterator(const iterator &other) : impl_(other.impl_) {
  80. }
  81. const_iterator &operator=(const iterator &other) {
  82. impl_ = other.impl_;
  83. return *this;
  84. }
  85. inline const T &operator*() const { return impl_.key(); }
  86. inline const T *operator->() const { return &impl_.key(); }
  87. inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; }
  88. inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; }
  89. inline const_iterator &operator++() { ++impl_; return *this; }
  90. inline const_iterator operator++(int) { return const_iterator(impl_++); }
  91. inline const_iterator &operator--() { --impl_; return *this; }
  92. inline const_iterator operator--(int) { return const_iterator(impl_--); }
  93. inline const_iterator operator+(int j) const { return const_iterator(impl_ + j); }
  94. inline const_iterator operator-(int j) const { return const_iterator(impl_ - j); }
  95. inline const_iterator &operator+=(int j) { impl_ += j; return *this; }
  96. inline const_iterator &operator-=(int j) { impl_ -= j; return *this; }
  97. friend class iterator;
  98. inline bool operator==(const iterator &other) const { return impl_ == other.impl_; }
  99. inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; }
  100. private:
  101. explicit const_iterator(const ConstIteratorImpl &impl) : impl_(impl) {
  102. }
  103. ConstIteratorImpl impl_;
  104. friend class OrderedSet<T>;
  105. };
  106. friend class const_iterator;
  107. // STL style
  108. inline iterator begin() { return iterator(impl_.begin()); }
  109. inline const_iterator begin() const { return const_iterator(impl_.cbegin()); }
  110. inline const_iterator constBegin() const { return const_iterator(impl_.cbegin()); }
  111. inline const_iterator cbegin() const { return const_iterator(impl_.cbegin()); }
  112. inline iterator end() { detach(); return iterator(impl_.end()); }
  113. inline const_iterator end() const { return const_iterator(impl_.cend()); }
  114. inline const_iterator constEnd() const { return const_iterator(impl_.cend()); }
  115. inline const_iterator cend() const { return const_iterator(impl_.cend()); }
  116. inline iterator erase(iterator it) { return iterator(impl_.erase(it.impl_)); }
  117. inline iterator insert(const T &value) { return iterator(impl_.insert(value, NullType())); }
  118. inline iterator insert(const_iterator pos, const T &value) { return iterator(impl_.insert(pos.impl_, value, NullType())); }
  119. inline int remove(const T &value) { return impl_.remove(value); }
  120. inline bool contains(const T &value) const { return impl_.contains(value); }
  121. // more Qt
  122. typedef iterator Iterator;
  123. typedef const_iterator ConstIterator;
  124. inline int count() const { return impl_.count(); }
  125. inline iterator find(const T &value) { return iterator(impl_.find(value)); }
  126. inline const_iterator find(const T &value) const { return const_iterator(impl_.constFind(value)); }
  127. inline const_iterator constFind(const T &value) const { return const_iterator(impl_.constFind(value)); }
  128. inline Self &unite(const Self &other) { impl_.unite(other.impl_); return *this; }
  129. // STL compatibility
  130. typedef typename Impl::difference_type difference_type;
  131. typedef typename Impl::size_type size_type;
  132. inline bool empty() const { return impl_.empty(); }
  133. };