swift
collection.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_MISC_COLLECTION_H
7 #define SWIFT_MISC_COLLECTION_H
8 
9 #include <algorithm>
10 #include <initializer_list>
11 #include <iterator>
12 #include <type_traits>
13 #include <typeindex>
14 #include <utility>
15 
16 #include <QMap>
17 
18 #include "misc/containerbase.h"
20 #include "misc/mixin/mixinicon.h"
21 
23 #define SWIFT_TEMPLATE_COLLECTION_MIXINS(NS, T, Set, Extern) \
24  namespace NS \
25  { \
26  class Set; \
27  } \
28  namespace swift::misc::private_ns \
29  { \
30  Extern template struct CValueObjectMetaInfo<NS::Set>; \
31  Extern template struct CValueObjectMetaInfo<CCollection<NS::T>>; \
32  Extern template struct MetaTypeHelper<NS::Set>; \
33  Extern template struct MetaTypeHelper<CCollection<NS::T>>; \
34  } \
35  namespace swift::misc::mixin \
36  { \
37  Extern template class MetaType<NS::Set>; \
38  Extern template class MetaType<CCollection<NS::T>>; \
39  Extern template class DBusOperators<CCollection<NS::T>>; \
40  Extern template class JsonOperators<CCollection<NS::T>>; \
41  Extern template class String<CCollection<NS::T>>; \
42  Extern template class DataStreamOperators<CCollection<NS::T>>; \
43  Extern template class Icon<CCollection<NS::T>>; \
44  }
46 
57 #if defined(Q_OS_WIN) && defined(Q_CC_GNU)
58 # define SWIFT_DECLARE_COLLECTION_MIXINS(Namespace, T, Set)
59 # define SWIFT_DEFINE_COLLECTION_MIXINS(Namespace, T, Set)
60 #else
61 # define SWIFT_DECLARE_COLLECTION_MIXINS(Namespace, T, Set) \
62  SWIFT_TEMPLATE_COLLECTION_MIXINS(Namespace, T, Set, extern)
63 # define SWIFT_DEFINE_COLLECTION_MIXINS(Namespace, T, Set) SWIFT_TEMPLATE_COLLECTION_MIXINS(Namespace, T, Set, )
64 #endif
65 
66 namespace swift::misc
67 {
68 
72  template <class T>
73  class QOrderedSet : public QMap<T, T>
74  {
75  public:
77  using value_type = T;
78 
80  typename QMap<T, T>::iterator insert(const T &value) { return QMap<T, T>::insert(value, value); }
81 
83  QOrderedSet() = default;
84 
86  QOrderedSet(std::initializer_list<T> il)
87  {
88  for (const auto &v : il) { insert(v); }
89  }
90 
92  QOrderedSet(const QList<T> &list)
93  {
94  for (const auto &v : list) { insert(v); }
95  }
96  };
97 
102  template <class T>
103  class CCollection :
104  public CContainerBase<CCollection<T>>,
105  public mixin::DataStreamOperators<CCollection<T>>,
106  public mixin::Icon<CCollection<T>>
107  {
108  public:
110  using key_type = T;
111 
113  using value_type = T;
114 
116  using reference = T &;
117 
119  using const_reference = const T &;
120 
122  using pointer = T *;
123 
125  using const_pointer = const T *;
126 
129 
131  using iterator = const_iterator; // can't modify elements in-place
132 
134  using difference_type = ptrdiff_t;
135 
137  using size_type = int;
138 
140  CCollection() = default;
141 
143  CCollection(std::initializer_list<T> il) : m_impl(il) {}
144 
146  CCollection(const CCollection &other) = default;
147 
149  CCollection(const QList<T> &list) : m_impl(list) {}
150 
152  CCollection(CCollection &&other) = default;
153 
155  CCollection &operator=(const CCollection &other) = default;
156 
158  CCollection &operator=(CCollection &&other) = default;
159 
161  ~CCollection() = default;
162 
164  iterator begin() { return m_impl.begin(); }
165 
167  const_iterator begin() const { return m_impl.begin(); }
168 
170  const_iterator cbegin() const { return m_impl.cbegin(); }
171 
173  iterator end() { return m_impl.end(); }
174 
176  const_iterator end() const { return m_impl.end(); }
177 
179  const_iterator cend() const { return m_impl.cend(); }
180 
182  void swap(CCollection &other) noexcept { m_impl.swap(other.m_impl); }
183 
185  size_type size() const { return m_impl.size(); }
186 
188  bool empty() const { return m_impl.isEmpty(); }
189 
191  bool isEmpty() const { return empty(); }
192 
194  void clear() { m_impl.clear(); }
195 
199  iterator insert(const_iterator hint, const T &value)
200  {
201  Q_UNUSED(hint);
202  return insert(value);
203  }
204 
208  iterator insert(const_iterator hint, T &&value)
209  {
210  Q_UNUSED(hint);
211  return insert(std::move(value));
212  }
213 
216  iterator insert(const T &value) { return m_impl.insert(value); }
217 
220  iterator insert(T &&value) { return m_impl.insert(std::move(value)); }
221 
223  void insert(const CCollection &other) { std::copy(other.begin(), other.end(), std::inserter(*this, begin())); }
224 
227  void insert(CCollection &&other) { std::move(other.begin(), other.end(), std::inserter(*this, begin())); }
228 
230  template <typename I>
231  void insert(const CRange<I> &range)
232  {
233  std::copy(range.begin(), range.end(), std::back_inserter(*this));
234  }
235 
238  iterator push_back(const T &value) { return insert(value); }
239 
242  iterator push_back(T &&value) { return insert(std::move(value)); }
243 
245  void push_back(const CCollection &other) { insert(other); }
246 
248  void push_back(CCollection &&other) { insert(std::move(other)); }
249 
251  template <typename I>
252  void push_back(const CRange<I> &range)
253  {
254  std::copy(range.begin(), range.end(), std::back_inserter(*this));
255  }
256 
258  template <class C>
259  CCollection makeUnion(const C &other) const
260  {
261  CCollection result;
262  std::set_union(begin(), end(), other.begin(), other.end(), std::inserter(result, result.begin()));
263  return result;
264  }
265 
267  template <class C>
268  CCollection intersection(const C &other) const
269  {
270  CCollection result;
271  std::set_intersection(begin(), end(), other.begin(), other.end(), std::inserter(result, result.begin()));
272  return result;
273  }
274 
277  template <class C>
278  CCollection difference(const C &other) const
279  {
280  CCollection result;
281  std::set_difference(begin(), end(), other.begin(), other.end(), std::inserter(result, result.begin()));
282  return result;
283  }
284 
287  iterator erase(iterator pos) { return m_impl.erase(pos); }
288 
292  {
293  while (it1 != it2) { it1 = erase(it1); }
294  return it1;
295  }
296 
299  iterator find(const T &value) { return m_impl.find(value); }
300 
303  const_iterator find(const T &value) const { return m_impl.find(value); }
304 
307  void remove(const T &object)
308  {
309  auto it = find(object);
310  if (it != end()) { erase(it); }
311  }
312 
315  void remove(const CCollection &other) { *this = CCollection(*this).difference(other); }
316 
320  template <class Predicate>
321  int removeIf(Predicate p)
322  {
323  int count = 0;
324  for (auto it = begin(); it != end();)
325  {
326  if (p(*it))
327  {
328  it = erase(it);
329  count++;
330  }
331  else { ++it; }
332  }
333  return count;
334  }
335 
337  template <class K0, class V0, class... KeysValues>
338  int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
339  {
340  // using-declaration doesn't play nicely with injected template names
341  return CCollection::CContainerBase::removeIf(k0, v0, keysValues...);
342  }
343 
345  QList<T> toQList() const { return this->to(QList<T>()); }
346 
348  void detach() { m_impl.detach(); }
349 
351  friend bool operator==(const CCollection &a, const CCollection &b) { return a.m_impl == b.m_impl; }
352 
354  friend bool operator!=(const CCollection &a, const CCollection &b) { return a.m_impl != b.m_impl; }
355 
357  void marshalToDataStream(QDataStream &stream) const { stream << m_impl; }
358 
360  void unmarshalFromDataStream(QDataStream &stream) { stream >> m_impl; }
361 
362  private:
363  QOrderedSet<T> m_impl;
364  };
365 
366 } // namespace swift::misc
367 
368 Q_DECLARE_METATYPE(swift::misc::CCollection<int>)
369 Q_DECLARE_METATYPE(swift::misc::CCollection<uint>)
370 Q_DECLARE_METATYPE(swift::misc::CCollection<qlonglong>)
371 Q_DECLARE_METATYPE(swift::misc::CCollection<qulonglong>)
372 // CCollection<double> not instantiated due to it being a dumb idea because of rounding issues
373 
374 #endif // SWIFT_MISC_COLLECTION_H
Generic ordered container with value semantics.
Definition: collection.h:107
friend bool operator==(const CCollection &a, const CCollection &b)
Test for equality.
Definition: collection.h:351
iterator erase(iterator it1, iterator it2)
Remove the range of elements between two iterators.
Definition: collection.h:291
const T & const_reference
STL compatibility.
Definition: collection.h:119
ptrdiff_t difference_type
STL compatibility.
Definition: collection.h:134
void swap(CCollection &other) noexcept
Swap this collection with another.
Definition: collection.h:182
void push_back(const CCollection &other)
Synonym for insert.
Definition: collection.h:245
void insert(CCollection &&other)
Inserts all elements from another collection into this collection. This version moves elements instea...
Definition: collection.h:227
void unmarshalFromDataStream(QDataStream &stream)
Unmarshal a value from a QDataStream.
Definition: collection.h:360
iterator insert(const_iterator hint, T &&value)
For compatibility with std::inserter.
Definition: collection.h:208
CCollection & operator=(CCollection &&other)=default
Move assignment.
const_iterator find(const T &value) const
Efficient find method using the find of the implementation container. Typically O(log n).
Definition: collection.h:303
size_type size() const
Returns number of elements in the collection.
Definition: collection.h:185
CCollection difference(const C &other) const
Returns a collection which contains all the elements from this collection which are not in the other ...
Definition: collection.h:278
void remove(const T &object)
Efficient remove using the find and erase of the implementation container. Typically O(log n).
Definition: collection.h:307
const_iterator cbegin() const
Returns iterator at the beginning of the collection.
Definition: collection.h:170
T * pointer
STL compatibility.
Definition: collection.h:122
iterator insert(const_iterator hint, const T &value)
For compatibility with std::inserter.
Definition: collection.h:199
CCollection()=default
Default constructor.
T & reference
STL compatibility.
Definition: collection.h:116
iterator find(const T &value)
Efficient find method using the find of the implementation container. Typically O(log n).
Definition: collection.h:299
void insert(const CCollection &other)
Inserts all elements from another collection into this collection.
Definition: collection.h:223
T key_type
STL compatibility.
Definition: collection.h:110
T value_type
STL compatibility.
Definition: collection.h:113
CCollection intersection(const C &other) const
Returns a collection which is the intersection of this collection and another.
Definition: collection.h:268
iterator insert(const T &value)
Inserts an element into the collection.
Definition: collection.h:216
bool empty() const
Returns true if the collection is empty.
Definition: collection.h:188
CCollection(const CCollection &other)=default
Copy constructor.
typename QOrderedSet< T >::const_iterator const_iterator
STL compatibility.
Definition: collection.h:128
iterator begin()
Returns iterator at the beginning of the collection.
Definition: collection.h:164
const_iterator end() const
Returns const iterator one past the end of the collection.
Definition: collection.h:176
int size_type
STL compatibility.
Definition: collection.h:137
const_iterator iterator
STL compatibility.
Definition: collection.h:131
void push_back(const CRange< I > &range)
Synonym for insert.
Definition: collection.h:252
bool isEmpty() const
Synonym for empty.
Definition: collection.h:191
int removeIf(Predicate p)
Remove elements for which a given predicate returns true.
Definition: collection.h:321
friend bool operator!=(const CCollection &a, const CCollection &b)
Test for inequality.
Definition: collection.h:354
CCollection(const QList< T > &list)
Constructor from QList.
Definition: collection.h:149
iterator push_back(T &&value)
Synonym for insert.
Definition: collection.h:242
CCollection makeUnion(const C &other) const
Returns a collection which is the union of this collection and another container.
Definition: collection.h:259
void insert(const CRange< I > &range)
Appends all elements from a range at the end of this collection.
Definition: collection.h:231
void push_back(CCollection &&other)
Synonym for insert.
Definition: collection.h:248
const_iterator cend() const
Returns const iterator one past the end of the collection.
Definition: collection.h:179
iterator push_back(const T &value)
Synonym for insert.
Definition: collection.h:238
CCollection(std::initializer_list< T > il)
Initializer list constructor.
Definition: collection.h:143
void clear()
Removes all elements in the collection.
Definition: collection.h:194
iterator erase(iterator pos)
Remove the element pointed to by the given iterator.
Definition: collection.h:287
int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
Remove elements matching some particular key/value pair(s).
Definition: collection.h:338
const T * const_pointer
STL compatibility.
Definition: collection.h:125
QList< T > toQList() const
Convert to a QList.
Definition: collection.h:345
void remove(const CCollection &other)
Removes from this collection all of the elements of another collection.
Definition: collection.h:315
iterator insert(T &&value)
Moves an element into the collection.
Definition: collection.h:220
void marshalToDataStream(QDataStream &stream) const
Marshal a value to a QDataStream.
Definition: collection.h:357
~CCollection()=default
Destructor.
iterator end()
Returns iterator one past the end of the collection.
Definition: collection.h:173
CCollection(CCollection &&other)=default
Move constructor.
const_iterator begin() const
Returns iterator at the beginning of the collection.
Definition: collection.h:167
CCollection & operator=(const CCollection &other)=default
Copy assignment.
Base class for CCollection and CSequence adding mutating operations and CValueObject facility on top ...
Definition: containerbase.h:65
auto to() const
Return a new container of a different type, containing the same elements as this one.
Definition: containerbase.h:83
A range is a conceptual container which does not contain any elements of its own, but is constructed ...
Definition: range.h:190
const_iterator end() const
Begin and end iterators.
Definition: range.h:213
const_iterator begin() const
Begin and end iterators.
Definition: range.h:211
Needed for compatibility with C++ standard algorithms which expect ordered sets.
Definition: collection.h:74
T value_type
Type of values stored in the set.
Definition: collection.h:77
QOrderedSet(std::initializer_list< T > il)
Initializer list constructor.
Definition: collection.h:86
QOrderedSet()=default
Default constructor.
QMap< T, T >::iterator insert(const T &value)
Insert a new value into the set.
Definition: collection.h:80
QOrderedSet(const QList< T > &list)
Constructor from QList.
Definition: collection.h:92
CRTP class template to generate non-member QDataStream streaming operators.
CRTP class template from which a derived class can inherit icon-related functions.
Definition: mixinicon.h:28
Free functions in swift::misc.