swift
orderablelist.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2016 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_ORDERABLELIST_H
7 #define SWIFT_MISC_ORDERABLELIST_H
8 
9 #include <QList>
10 
11 namespace swift::misc
12 {
13  class IOrderable;
14 
17  template <class OBJ, class CONTAINER>
19  {
20  static_assert(std::is_base_of_v<IOrderable, OBJ>, "OBJ needs to implement IOrderable");
21 
22  public:
24  void sortAscendingByOrder() { this->container().sort(predicates::MemberLess(&OBJ::getOrder)); }
25 
28  {
29  this->container().sortAscendingByOrder();
30  std::reverse(this->container().begin(), this->container().end());
31  }
32 
34  void resetOrder(int offset = 0)
35  {
36  int c = offset;
37  for (OBJ &obj : container()) { obj.setOrder(c++); }
38  }
39 
41  bool needsOrder() const
42  {
43  return std::any_of(this->container().begin(), this->container().end(),
44  [](const OBJ &obj) { return !obj.hasValidOrder(); });
45  }
46 
49  {
50  QList<int> orders;
51  for (const OBJ &obj : container())
52  {
53  if (!obj.hasValidOrder()) { continue; }
54  orders.append(obj.getOrder());
55  }
56  return orders;
57  }
58 
60  CONTAINER withoutItemsOfSameOrder(const CONTAINER &items) const
61  {
62  const QList<int> orders = items.orderValues();
63  if (orders.isEmpty()) { return this->container(); }
64 
65  CONTAINER newContainer;
66  for (const OBJ &obj : container())
67  {
68  if (orders.contains(obj.getOrder())) { continue; }
69  newContainer.push_back(obj);
70  }
71  return newContainer;
72  }
73 
75  void removeItemsWithSameOrder(const CONTAINER &items)
76  {
77  const QList<int> orders = items.orderValues();
78  if (orders.isEmpty()) { return; }
79 
80  CONTAINER newContainer;
81  for (const OBJ &obj : container())
82  {
83  if (orders.contains(obj.getOrder())) { continue; }
84  newContainer.push_back(obj);
85  }
86  this->container() = newContainer;
87  }
88 
90  void moveTo(const CONTAINER &items, int targetOrder)
91  {
92  if (items.isEmpty()) { return; }
93  CONTAINER newContainer(this->withoutItemsOfSameOrder(items)); // this container without items
94  CONTAINER newItems(items);
95  const int shift = items.size();
96  newContainer.sortAscendingByOrder(); // sorted by old order
97  newContainer.resetOrder();
98  for (OBJ &obj : newContainer)
99  {
100  if (obj.getOrder() < targetOrder) { continue; }
101  obj.setOrder(obj.getOrder() + shift);
102  }
103  newItems.sortAscendingByOrder(); // sort by old order
104  newItems.resetOrder(targetOrder);
105  newContainer.push_back(newItems);
106  this->container() = newContainer;
107  }
108 
110  void freezeOrder()
111  {
112  int c = 0;
113  for (OBJ &obj : container()) { obj.setOrder(c++); }
114  }
115 
118  {
119  int c = this->container().size() - 1;
120  for (OBJ &obj : container()) { obj.setOrder(c--); }
121  }
122 
124  OBJ minOrderOrDefault() const
125  {
126  if (container().isEmpty()) { return OBJ(); }
127  OBJ min = container().front();
128  for (const OBJ &obj : container())
129  {
130  if (!obj.hasValidOrder()) { continue; }
131  if (obj.getOrder() < min.getOrder()) { min = obj; }
132  }
133  return min;
134  }
135 
137  OBJ maxOrderOrDefault() const
138  {
139  if (container().isEmpty()) { return OBJ(); }
140  OBJ max = container().front();
141  for (const OBJ &obj : container())
142  {
143  if (!obj.hasValidOrder()) { continue; }
144  if (obj.getOrder() > max.getOrder()) { max = obj; }
145  }
146  return max;
147  }
148 
149  protected:
151  IOrderableList() = default;
152 
154  const CONTAINER &container() const { return static_cast<const CONTAINER &>(*this); }
155 
157  CONTAINER &container() { return static_cast<CONTAINER &>(*this); }
158  };
159 } // namespace swift::misc
160 
161 #endif // SWIFT_MISC_ORDERABLELIST_H
List of orderable IOrderable objects.
Definition: orderablelist.h:19
void freezeOrderReverse()
Current reverse order of list will be new order values.
void removeItemsWithSameOrder(const CONTAINER &items)
Remove the items based on their order IOrderable::order.
Definition: orderablelist.h:75
IOrderableList()=default
Constructor.
void sortAscendingByOrder()
Sort ascending.
Definition: orderablelist.h:24
void sortDescendingByOrder()
Sort descending.
Definition: orderablelist.h:27
CONTAINER & container()
Container.
void moveTo(const CONTAINER &items, int targetOrder)
Move items to given order.
Definition: orderablelist.h:90
QList< int > orderValues() const
All order values IOrderable::order.
Definition: orderablelist.h:48
OBJ maxOrderOrDefault() const
Object with max.order or default.
OBJ minOrderOrDefault() const
Object with min.order or default.
const CONTAINER & container() const
Container.
CONTAINER withoutItemsOfSameOrder(const CONTAINER &items) const
Items with order will not be included.
Definition: orderablelist.h:60
void resetOrder(int offset=0)
Set order member to current order.
Definition: orderablelist.h:34
void freezeOrder()
Current order of list will be new order values.
bool needsOrder() const
All order values set or missing some?
Definition: orderablelist.h:41
auto MemberLess(Ts... vs)
Predicate which compares the return values of some member functions of two objects.
Definition: predicates.h:43
Free functions in swift::misc.
T::const_iterator begin(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:332
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:338
void append(QList< T > &&value)
bool contains(const AT &value) const const
bool isEmpty() const const
void push_back(QList< T >::parameter_type value)