libquentier  0.5.0
The library for rich desktop clients of Evernote service
LimitedStack.h
1 /*
2  * Copyright 2016-2020 Dmitry Ivanov
3  *
4  * This file is part of libquentier
5  *
6  * libquentier is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, version 3 of the License.
9  *
10  * libquentier is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libquentier. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef LIB_QUENTIER_UTILITY_LIMITED_STACK_H
20 #define LIB_QUENTIER_UTILITY_LIMITED_STACK_H
21 
22 #include <quentier/utility/Macros.h>
23 
24 #include <QStack>
25 
26 namespace quentier {
27 
34 template <class T>
35 class LimitedStack: public QStack<T>
36 {
37 public:
38  LimitedStack(void (*deleter)(T&) = nullptr) :
39  m_limit(-1), m_deleter(deleter)
40  {}
41 
42  LimitedStack(const LimitedStack<T> & other) :
43  QStack<T>(other),
44  m_limit(other.m_limit),
45  m_deleter(other.m_deleter)
46  {}
47 
48  LimitedStack(LimitedStack<T> && other) :
49  QStack<T>(std::move(other)),
50  m_limit(std::move(other.m_limit)),
51  m_deleter(std::move(other.m_deleter))
52  {}
53 
54  LimitedStack<T> & operator=(const LimitedStack<T> & other)
55  {
56  if (this != &other) {
57  QStack<T>::operator=(other);
58  m_limit = other.m_limit;
59  m_deleter = other.m_deleter;
60  }
61 
62  return *this;
63  }
64 
65  LimitedStack<T> & operator=(LimitedStack<T> && other)
66  {
67  if (this != &other) {
68  QStack<T>::operator=(std::move(other));
69  m_limit = std::move(other.m_limit);
70  m_deleter = std::move(other.m_deleter);
71  }
72 
73  return *this;
74  }
75 
76  ~LimitedStack()
77  {
78  if (m_deleter)
79  {
80  while (!QStack<T>::isEmpty()) {
81  T t = QStack<T>::pop();
82  (*m_deleter)(t);
83  }
84  }
85  }
86 
87  void swap(const LimitedStack<T> & other)
88  {
89  int limit = other.m_limit;
90  other.m_limit = m_limit;
91  m_limit = limit;
92 
93  void (*deleter)(T &) = other.m_deleter;
94  other.m_deleter = m_deleter;
95  m_deleter = deleter;
96 
97  QStack<T>::swap(other);
98  }
99 
100  int limit() const { return m_limit; }
101  void setLimit(const int limit) { m_limit = limit; }
102 
103  void push(const T & t)
104  {
105  if ((m_limit > 0) && (QVector<T>::size() == m_limit - 1)) {
106  if (m_deleter) {
107  (*m_deleter)(*QVector<T>::begin());
108  }
109  Q_UNUSED(QVector<T>::erase(QVector<T>::begin()));
110  }
111 
112  QStack<T>::push(t);
113  }
114 
115 private:
116  int m_limit;
117  void (*m_deleter)(T &);
118 };
119 
120 } // namespace quentier
121 
122 #endif // LIB_QUENTIER_UTILITY_LIMITED_STACK_H
quentier::LimitedStack
The LimitedStack template class implements a stack which may have a limitation for its size; when the...
Definition: LimitedStack.h:35