LibrePCB Developers Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
serializableobjectlist.h
Go to the documentation of this file.
1 /*
2  * LibrePCB - Professional EDA for everyone!
3  * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4  * https://librepcb.org/
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LIBREPCB_SERIALIZABLEOBJECTLIST_H
21 #define LIBREPCB_SERIALIZABLEOBJECTLIST_H
22 
23 /*******************************************************************************
24  * Includes
25  ******************************************************************************/
26 #include "../signalslot.h"
27 #include "../uuid.h"
28 #include "serializableobject.h"
29 
30 #include <QtCore>
31 
32 #include <algorithm>
33 #include <memory>
34 
35 /*******************************************************************************
36  * Namespace / Forward Declarations
37  ******************************************************************************/
38 namespace librepcb {
39 
40 /*******************************************************************************
41  * Class SerializableObjectList
42  ******************************************************************************/
43 
93 template <typename T, typename P, typename... OnEditedArgs>
95  Q_DECLARE_TR_FUNCTIONS(SerializableObjectList)
96 
97 public:
98  // Iterator Types
99  template <typename I, typename O>
100  class Iterator {
101  I it;
102 
103  public:
104  Iterator() = delete;
105  Iterator(const Iterator& other) noexcept : it(other.it) {}
106  Iterator(const I& it) noexcept : it(it) {}
107  bool operator!=(const Iterator& rhs) const noexcept { return it != rhs.it; }
109  ++it;
110  return *this;
111  }
112  O& operator*() { return **it; }
113  std::shared_ptr<O> ptr() noexcept {
114  return std::const_pointer_cast<O>(*it);
115  }
117  };
118  using iterator = Iterator<typename QVector<std::shared_ptr<T>>::iterator, T>;
119  using const_iterator =
120  Iterator<typename QVector<std::shared_ptr<T>>::const_iterator, const T>;
121 
122  // Signals
123  enum class Event {
124  ElementAdded,
127  };
128  Signal<SerializableObjectList<T, P, OnEditedArgs...>, int,
129  const std::shared_ptr<const T>&, Event>
131  typedef Slot<SerializableObjectList<T, P, OnEditedArgs...>, int,
132  const std::shared_ptr<const T>&, Event>
134  Signal<SerializableObjectList<T, P, OnEditedArgs...>, int,
135  const std::shared_ptr<const T>&, OnEditedArgs...>
137  typedef Slot<SerializableObjectList<T, P, OnEditedArgs...>, int,
138  const std::shared_ptr<const T>&, OnEditedArgs...>
140 
141  // Constructors / Destructor
143  : onEdited(*this),
144  onElementEdited(*this),
146  T, P, OnEditedArgs...>::elementEditedHandler) {}
148  const SerializableObjectList<T, P, OnEditedArgs...>& other) noexcept
149  : onEdited(*this),
150  onElementEdited(*this),
152  T, P, OnEditedArgs...>::elementEditedHandler) {
153  *this = other; // copy all elements
154  }
157  : onEdited(*this),
158  onElementEdited(*this),
160  T, P, OnEditedArgs...>::elementEditedHandler) {
161  while (!other.isEmpty()) {
162  append(other.take(0)); // copy all pointers (NOT the objects!)
163  }
164  }
166  std::initializer_list<std::shared_ptr<T>> elements) noexcept
167  : onEdited(*this),
168  onElementEdited(*this),
170  T, P, OnEditedArgs...>::elementEditedHandler) {
171  foreach (const std::shared_ptr<T>& obj, elements) { append(obj); }
172  }
173  explicit SerializableObjectList(const SExpression& node)
174  : onEdited(*this),
175  onElementEdited(*this),
177  T, P, OnEditedArgs...>::elementEditedHandler) {
178  loadFromSExpression(node); // can throw
179  }
180  virtual ~SerializableObjectList() noexcept {}
181 
182  // Getters
183  bool isEmpty() const noexcept { return mObjects.empty(); }
184  int count() const noexcept { return mObjects.count(); }
185  std::vector<Uuid> getUuids() const noexcept {
186  std::vector<Uuid> uuids;
187  uuids.reserve(mObjects.count());
188  foreach (const std::shared_ptr<T>& obj, mObjects) {
189  uuids.push_back(obj->getUuid());
190  }
191  return uuids;
192  }
193  QSet<Uuid> getUuidSet() const noexcept {
194  QSet<Uuid> uuids;
195  uuids.reserve(mObjects.count());
196  foreach (const std::shared_ptr<T>& obj, mObjects) {
197  uuids.insert(obj->getUuid());
198  }
199  return uuids;
200  }
201 
202  // Element Query
203  int indexOf(const T* obj) const noexcept {
204  for (int i = 0; i < count(); ++i) {
205  if (mObjects[i].get() == obj) {
206  return i;
207  }
208  }
209  return -1;
210  }
211  int indexOf(const Uuid& key) const noexcept {
212  for (int i = 0; i < count(); ++i) {
213  if (mObjects[i]->getUuid() == key) {
214  return i;
215  }
216  }
217  return -1;
218  }
219  int indexOf(const QString& name) const noexcept {
220  for (int i = 0; i < count(); ++i) {
221  if (mObjects[i]->getName() == name) {
222  return i;
223  }
224  }
225  return -1;
226  }
227  bool contains(int index) const noexcept {
228  return index >= 0 && index < mObjects.count();
229  }
230  bool contains(const T* obj) const noexcept { return indexOf(obj) >= 0; }
231  bool contains(const Uuid& key) const noexcept { return indexOf(key) >= 0; }
232  bool contains(const QString& name) const noexcept {
233  return indexOf(name) >= 0;
234  }
235 
236  // "Soft" Element Access (null if not found)
237  std::shared_ptr<T> value(int index) noexcept { return mObjects.value(index); }
238  std::shared_ptr<const T> value(int index) const noexcept {
239  return std::const_pointer_cast<const T>(mObjects.value(index));
240  }
241  std::shared_ptr<T> find(const T* obj) noexcept { return value(indexOf(obj)); }
242  std::shared_ptr<T> find(const Uuid& key) noexcept {
243  return value(indexOf(key));
244  }
245  std::shared_ptr<const T> find(const Uuid& key) const noexcept {
246  return value(indexOf(key));
247  }
248  std::shared_ptr<T> find(const QString& name) noexcept {
249  return value(indexOf(name));
250  }
251  std::shared_ptr<const T> find(const QString& name) const noexcept {
252  return value(indexOf(name));
253  }
254 
255  // "Hard" Element Access (assertion or exception if not found!)
256  std::shared_ptr<const T> at(int index) const noexcept {
257  return std::const_pointer_cast<const T>(mObjects.at(index));
258  } // always read-only!
259  std::shared_ptr<T>& first() noexcept { return mObjects.first(); }
260  std::shared_ptr<const T> first() const noexcept { return mObjects.first(); }
261  std::shared_ptr<T>& last() noexcept { return mObjects.last(); }
262  std::shared_ptr<const T> last() const noexcept { return mObjects.last(); }
263  std::shared_ptr<T> get(const T* obj) {
264  std::shared_ptr<T> ptr = find(obj);
265  if (!ptr) throw LogicError(__FILE__, __LINE__);
266  return ptr;
267  }
268  std::shared_ptr<T> get(const Uuid& key) {
269  std::shared_ptr<T> ptr = find(key);
270  if (!ptr) throwKeyNotFoundException(key);
271  return ptr;
272  }
273  std::shared_ptr<const T> get(const Uuid& key) const {
274  std::shared_ptr<const T> ptr = find(key);
275  if (!ptr) throwKeyNotFoundException(key);
276  return ptr;
277  }
278  std::shared_ptr<T> get(const QString& name) {
279  std::shared_ptr<T> ptr = find(name);
280  if (!ptr) throwNameNotFoundException(name);
281  return ptr;
282  }
283  std::shared_ptr<const T> get(const QString& name) const {
284  std::shared_ptr<const T> ptr = find(name);
285  if (!ptr) throwNameNotFoundException(name);
286  return ptr;
287  }
288 
289  // Iterator Access
290  const_iterator begin() const noexcept { return mObjects.begin(); }
291  const_iterator end() const noexcept { return mObjects.end(); }
292  const_iterator cbegin() noexcept { return mObjects.cbegin(); }
293  const_iterator cend() noexcept { return mObjects.cend(); }
294  iterator begin() noexcept { return mObjects.begin(); }
295  iterator end() noexcept { return mObjects.end(); }
296 
297  // General Methods
298  int loadFromSExpression(const SExpression& node) {
299  clear();
300  foreach (const SExpression& node, node.getChildren(P::tagname)) {
301  append(std::make_shared<T>(node)); // can throw
302  }
303  return count();
304  }
305  void swap(int i, int j) noexcept {
306  // do not call mObjects.swap() because it would not notify the observers
307  qBound(0, i, count() - 1);
308  qBound(0, j, count() - 1);
309  if (i == j) return;
310  if (i > j) qSwap(i, j);
311  std::shared_ptr<T> oj = take(j);
312  std::shared_ptr<T> oi = take(i);
313  insert(i, oj);
314  insert(j, oi);
315  }
316  int insert(int index, const std::shared_ptr<T>& obj) noexcept {
317  Q_ASSERT(obj);
318  qBound(0, index, count());
319  insertElement(index, obj);
320  return index;
321  }
322  int append(const std::shared_ptr<T>& obj) noexcept {
323  return insert(count(), obj);
324  }
325  std::shared_ptr<T> take(int index) noexcept {
326  Q_ASSERT(contains(index));
327  return takeElement(index);
328  }
329  std::shared_ptr<T> take(const T* obj) noexcept { return take(indexOf(obj)); }
330  std::shared_ptr<T> take(const Uuid& uuid) noexcept {
331  return take(indexOf(uuid));
332  }
333  std::shared_ptr<T> take(const QString& name) noexcept {
334  return take(indexOf(name));
335  }
336  void remove(int index) noexcept { take(index); }
337  void remove(const T* obj) noexcept { take(obj); }
338  void remove(const Uuid& uuid) noexcept { take(uuid); }
339  void remove(const QString& name) noexcept { take(name); }
340  void clear() noexcept {
341  // do not call mObjects.clear() because it would not notify the observers
342  for (int i = count() - 1; i >= 0; --i) {
343  remove(i);
344  }
345  Q_ASSERT(isEmpty() && mObjects.isEmpty());
346  }
348  void serialize(SExpression& root) const override {
349  serializePointerContainer(root, mObjects, P::tagname); // can throw
350  }
351 
352  // Convenience Methods
353  SerializableObjectList<T, P, OnEditedArgs...> sortedByUuid() const noexcept {
354  SerializableObjectList<T, P, OnEditedArgs...> copiedList;
355  copiedList.mObjects = mObjects; // copy only the pointers, not the objects!
356  std::sort(
357  copiedList.mObjects.begin(), copiedList.mObjects.end(),
358  [](const std::shared_ptr<T>& ptr1, const std::shared_ptr<T>& ptr2) {
359  return ptr1->getUuid() < ptr2->getUuid();
360  });
361  return copiedList;
362  }
363  SerializableObjectList<T, P, OnEditedArgs...> sortedByName() const noexcept {
364  SerializableObjectList<T, P, OnEditedArgs...> copiedList;
365  copiedList.mObjects = mObjects; // copy only the pointers, not the objects!
366  std::sort(
367  copiedList.mObjects.begin(), copiedList.mObjects.end(),
368  [](const std::shared_ptr<T>& ptr1, const std::shared_ptr<T>& ptr2) {
369  return ptr1->getName() < ptr2->getName();
370  });
371  return copiedList;
372  }
373 
374  // Operator Overloadings
375  std::shared_ptr<T> operator[](int i) noexcept {
376  Q_ASSERT(contains(i));
377  return mObjects[i];
378  }
379  std::shared_ptr<const T> operator[](int i) const noexcept {
380  Q_ASSERT(contains(i));
381  return mObjects[i];
382  }
384  const SerializableObjectList<T, P, OnEditedArgs...>& rhs) const noexcept {
385  if (rhs.mObjects.count() != mObjects.count()) return false;
386  for (int i = 0; i < mObjects.count(); ++i) {
387  if (*rhs.mObjects[i] != *mObjects[i]) return false;
388  }
389  return true;
390  }
392  const SerializableObjectList<T, P, OnEditedArgs...>& rhs) const noexcept {
393  return !(*this == rhs);
394  }
395  SerializableObjectList<T, P, OnEditedArgs...>& operator=(
396  const SerializableObjectList<T, P, OnEditedArgs...>& rhs) noexcept {
397  clear();
398  mObjects.reserve(rhs.count());
399  foreach (const std::shared_ptr<T>& ptr, rhs.mObjects) {
400  append(std::make_shared<T>(*ptr)); // call copy constructor of object
401  }
402  return *this;
403  }
404  SerializableObjectList<T, P, OnEditedArgs...>& operator=(
406  clear();
407  mObjects.reserve(rhs.count());
408  foreach (const std::shared_ptr<T>& ptr, rhs.mObjects) {
409  append(ptr); // copy only the pointer, NOT the object
410  }
411  rhs.clear();
412  return *this;
413  }
414 
415 protected: // Methods
416  void insertElement(int index, const std::shared_ptr<T>& obj) noexcept {
417  mObjects.insert(index, obj);
418  obj->onEdited.attach(mOnEditedSlot);
419  onEdited.notify(index, obj, Event::ElementAdded);
420  }
421  std::shared_ptr<T> takeElement(int index) noexcept {
422  std::shared_ptr<T> obj = mObjects.takeAt(index);
423  obj->onEdited.detach(mOnEditedSlot);
424  onEdited.notify(index, obj, Event::ElementRemoved);
425  return obj;
426  }
427  void elementEditedHandler(const T& obj, OnEditedArgs... args) noexcept {
428  int index = indexOf(&obj);
429  if (contains(index)) {
430  onElementEdited.notify(index, at(index), args...);
431  onEdited.notify(index, at(index), Event::ElementEdited);
432  } else {
433  qCritical() << "SerializableObjectList: Received notification from "
434  "unknown element!";
435  }
436  }
437  void throwKeyNotFoundException(const Uuid& key) const {
438  throw RuntimeError(
439  __FILE__, __LINE__,
440  QString(
441  tr("There is "
442  "no element of type \"%1\" with the UUID \"%2\" in the list."))
443  .arg(P::tagname)
444  .arg(key.toStr()));
445  }
446  void throwNameNotFoundException(const QString& name) const {
447  throw RuntimeError(
448  __FILE__, __LINE__,
449  QString(
450  tr("There is "
451  "no element of type \"%1\" with the name \"%2\" in the list."))
452  .arg(P::tagname)
453  .arg(name));
454  }
455 
456 protected: // Data
457  QVector<std::shared_ptr<T>> mObjects;
458  Slot<T, OnEditedArgs...> mOnEditedSlot;
459 };
460 
461 } // namespace librepcb
462 
463 /*******************************************************************************
464  * Prevent from using SerializableObjectList in a foreach loop because it always
465  *would create a deep copy of the list! You should use C++11 range based for
466  *loops instead.
467  ******************************************************************************/
468 
469 #if (QT_VERSION > QT_VERSION_CHECK(5, 9, 0))
470 namespace QtPrivate {
471 #endif
472 
473 template <typename T, typename P, typename... OnEditedArgs>
474 class QForeachContainer<
475  librepcb::SerializableObjectList<T, P, OnEditedArgs...>> {
476 public:
477  ~QForeachContainer() = delete;
478 };
479 template <typename T, typename P, typename... OnEditedArgs>
480 class QForeachContainer<
481  const librepcb::SerializableObjectList<T, P, OnEditedArgs...>> {
482 public:
483  ~QForeachContainer() = delete;
484 };
485 
486 #if (QT_VERSION > QT_VERSION_CHECK(5, 9, 0))
487 } // namespace QtPrivate
488 #endif
489 
490 /*******************************************************************************
491  * End of File
492  ******************************************************************************/
493 
494 #endif // LIBREPCB_SERIALIZABLEOBJECTLIST_H
I it
Definition: serializableobjectlist.h:101
const_iterator cend() noexcept
Definition: serializableobjectlist.h:293
The LogicError class.
Definition: exceptions.h:182
bool operator!=(const Iterator &rhs) const noexcept
Definition: serializableobjectlist.h:107
const QList< SExpression > & getChildren() const
Definition: sexpression.h:84
Slot< SerializableObjectList< T, P, OnEditedArgs...>, int, const std::shared_ptr< const T > &, Event > OnEditedSlot
Definition: serializableobjectlist.h:133
std::shared_ptr< T > & last() noexcept
Definition: serializableobjectlist.h:261
static void serializePointerContainer(SExpression &root, const T &container, const QString &itemName)
Definition: serializableobject.h:96
SerializableObjectList< T, P, OnEditedArgs...> sortedByUuid() const noexcept
Definition: serializableobjectlist.h:353
std::shared_ptr< T > value(int index) noexcept
Definition: serializableobjectlist.h:237
void clear() noexcept
Definition: serializableobjectlist.h:340
int loadFromSExpression(const SExpression &node)
Definition: serializableobjectlist.h:298
std::vector< Uuid > getUuids() const noexcept
Definition: serializableobjectlist.h:185
std::shared_ptr< T > operator[](int i) noexcept
Definition: serializableobjectlist.h:375
SerializableObjectList< T, P, OnEditedArgs...> sortedByName() const noexcept
Definition: serializableobjectlist.h:363
iterator end() noexcept
Definition: serializableobjectlist.h:295
SerializableObjectList(const SerializableObjectList< T, P, OnEditedArgs...> &other) noexcept
Definition: serializableobjectlist.h:147
Iterator(const I &it) noexcept
Definition: serializableobjectlist.h:106
The SerializableObjectList class implements a list of librepcb::SerializableObject.
Definition: serializableobjectlist.h:94
int indexOf(const QString &name) const noexcept
Definition: serializableobjectlist.h:219
Iterator< typename QVector< std::shared_ptr< Polygon >>::const_iterator, const Polygon > const_iterator
Definition: serializableobjectlist.h:120
Slot< SerializableObjectList< T, P, OnEditedArgs...>, int, const std::shared_ptr< const T > &, OnEditedArgs...> OnElementEditedSlot
Definition: serializableobjectlist.h:139
O & operator*()
Definition: serializableobjectlist.h:112
std::shared_ptr< O > ptr() noexcept
Definition: serializableobjectlist.h:113
int count() const noexcept
Definition: serializableobjectlist.h:184
bool operator!=(const SerializableObjectList< T, P, OnEditedArgs...> &rhs) const noexcept
Definition: serializableobjectlist.h:391
bool contains(int index) const noexcept
Definition: serializableobjectlist.h:227
QSet< Uuid > getUuidSet() const noexcept
Definition: serializableobjectlist.h:193
bool contains(const T *obj) const noexcept
Definition: serializableobjectlist.h:230
Signal< SerializableObjectList< T, P, OnEditedArgs...>, int, const std::shared_ptr< const T > &, Event > onEdited
Definition: serializableobjectlist.h:130
~Iterator()
Definition: serializableobjectlist.h:116
std::shared_ptr< T > & first() noexcept
Definition: serializableobjectlist.h:259
void insertElement(int index, const std::shared_ptr< T > &obj) noexcept
Definition: serializableobjectlist.h:416
SerializableObjectList< T, P, OnEditedArgs...> & operator=(SerializableObjectList< T, P, OnEditedArgs...> &&rhs) noexcept
Definition: serializableobjectlist.h:404
SerializableObjectList(const SExpression &node)
Definition: serializableobjectlist.h:173
bool isEmpty() const noexcept
Definition: serializableobjectlist.h:183
The SerializableObject class is the base class for all classes which need to be serializable/deserial...
Definition: serializableobject.h:43
void serialize(SExpression &root) const override
Serialize the object into an existing S-Expression node.
Definition: serializableobjectlist.h:348
iterator begin() noexcept
Definition: serializableobjectlist.h:294
Signal< SerializableObjectList< T, P, OnEditedArgs...>, int, const std::shared_ptr< const T > &, OnEditedArgs...> onElementEdited
Definition: serializableobjectlist.h:136
std::shared_ptr< const T > at(int index) const noexcept
Definition: serializableobjectlist.h:256
std::shared_ptr< const T > find(const Uuid &key) const noexcept
Definition: serializableobjectlist.h:245
int append(const std::shared_ptr< T > &obj) noexcept
Definition: serializableobjectlist.h:322
bool operator==(const SerializableObjectList< T, P, OnEditedArgs...> &rhs) const noexcept
Definition: serializableobjectlist.h:383
std::shared_ptr< const T > operator[](int i) const noexcept
Definition: serializableobjectlist.h:379
bool contains(const QString &name) const noexcept
Definition: serializableobjectlist.h:232
void elementEditedHandler(const T &obj, OnEditedArgs...args) noexcept
Definition: serializableobjectlist.h:427
std::shared_ptr< T > take(int index) noexcept
Definition: serializableobjectlist.h:325
std::shared_ptr< const T > value(int index) const noexcept
Definition: serializableobjectlist.h:238
The RuntimeError class.
Definition: exceptions.h:219
void throwKeyNotFoundException(const Uuid &key) const
Definition: serializableobjectlist.h:437
std::shared_ptr< const T > find(const QString &name) const noexcept
Definition: serializableobjectlist.h:251
void swap(int i, int j) noexcept
Definition: serializableobjectlist.h:305
int indexOf(const T *obj) const noexcept
Definition: serializableobjectlist.h:203
int insert(int index, const std::shared_ptr< T > &obj) noexcept
Definition: serializableobjectlist.h:316
std::shared_ptr< T > find(const Uuid &key) noexcept
Definition: serializableobjectlist.h:242
Definition: serializableobjectlist.h:100
std::shared_ptr< T > find(const QString &name) noexcept
Definition: serializableobjectlist.h:248
std::shared_ptr< T > take(const QString &name) noexcept
Definition: serializableobjectlist.h:333
std::shared_ptr< T > takeElement(int index) noexcept
Definition: serializableobjectlist.h:421
The Signal class is used to emit signals on non-QObject derived classes.
Definition: signalslot.h:65
Iterator(const Iterator &other) noexcept
Definition: serializableobjectlist.h:105
const_iterator cbegin() noexcept
Definition: serializableobjectlist.h:292
SerializableObjectList(SerializableObjectList< T, P, OnEditedArgs...> &&other) noexcept
Definition: serializableobjectlist.h:155
virtual ~SerializableObjectList() noexcept
Definition: serializableobjectlist.h:180
std::shared_ptr< T > take(const Uuid &uuid) noexcept
Definition: serializableobjectlist.h:330
std::shared_ptr< T > take(const T *obj) noexcept
Definition: serializableobjectlist.h:329
int indexOf(const Uuid &key) const noexcept
Definition: serializableobjectlist.h:211
SerializableObjectList< T, P, OnEditedArgs...> & operator=(const SerializableObjectList< T, P, OnEditedArgs...> &rhs) noexcept
Definition: serializableobjectlist.h:395
std::shared_ptr< T > find(const T *obj) noexcept
Definition: serializableobjectlist.h:241
The Uuid class is a replacement for QUuid to get UUID strings without {} braces.
Definition: uuid.h:58
const_iterator end() const noexcept
Definition: serializableobjectlist.h:291
QVector< std::shared_ptr< T > > mObjects
Definition: serializableobjectlist.h:457
bool contains(const Uuid &key) const noexcept
Definition: serializableobjectlist.h:231
Iterator & operator++()
Definition: serializableobjectlist.h:108
SerializableObjectList(std::initializer_list< std::shared_ptr< T >> elements) noexcept
Definition: serializableobjectlist.h:165
void throwNameNotFoundException(const QString &name) const
Definition: serializableobjectlist.h:446
The Slot class is used to receive signals from non-QObject derived classes.
Definition: signalslot.h:36
The SExpression class.
Definition: sexpression.h:57
QString toStr() const noexcept
Get the UUID as a string (without braces)
Definition: uuid.h:88
SerializableObjectList() noexcept
Definition: serializableobjectlist.h:142
Slot< T, OnEditedArgs...> mOnEditedSlot
Definition: serializableobjectlist.h:458
std::shared_ptr< const T > last() const noexcept
Definition: serializableobjectlist.h:262
std::shared_ptr< const T > first() const noexcept
Definition: serializableobjectlist.h:260
const_iterator begin() const noexcept
Definition: serializableobjectlist.h:290
Iterator< typename QVector< std::shared_ptr< Polygon >>::iterator, Polygon > iterator
Definition: serializableobjectlist.h:118