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 <QStack>
23 
24 namespace quentier {
25 
32 template <class T>
33 class LimitedStack : public QStack<T>
34 {
35 public:
36  LimitedStack(void (*deleter)(T &) = nullptr) :
37  m_limit(-1), m_deleter(deleter)
38  {}
39 
40  LimitedStack(const LimitedStack<T> & other) :
41  QStack<T>(other), m_limit(other.m_limit), m_deleter(other.m_deleter)
42  {}
43 
44  LimitedStack(LimitedStack<T> && other) :
45  QStack<T>(std::move(other)), m_limit(std::move(other.m_limit)),
46  m_deleter(std::move(other.m_deleter))
47  {}
48 
49  LimitedStack<T> & operator=(const LimitedStack<T> & other)
50  {
51  if (this != &other) {
52  QStack<T>::operator=(other);
53  m_limit = other.m_limit;
54  m_deleter = other.m_deleter;
55  }
56 
57  return *this;
58  }
59 
60  LimitedStack<T> & operator=(LimitedStack<T> && other)
61  {
62  if (this != &other) {
63  QStack<T>::operator=(std::move(other));
64  m_limit = std::move(other.m_limit);
65  m_deleter = std::move(other.m_deleter);
66  }
67 
68  return *this;
69  }
70 
71  ~LimitedStack()
72  {
73  if (m_deleter) {
74  while (!QStack<T>::isEmpty()) {
75  T t = QStack<T>::pop();
76  (*m_deleter)(t);
77  }
78  }
79  }
80 
81  void swap(const LimitedStack<T> & other)
82  {
83  int limit = other.m_limit;
84  other.m_limit = m_limit;
85  m_limit = limit;
86 
87  void (*deleter)(T &) = other.m_deleter;
88  other.m_deleter = m_deleter;
89  m_deleter = deleter;
90 
91  QStack<T>::swap(other);
92  }
93 
94  int limit() const
95  {
96  return m_limit;
97  }
98  void setLimit(const int limit)
99  {
100  m_limit = limit;
101  }
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
The LimitedStack template class implements a stack which may have a limitation for its size; when the...
Definition: LimitedStack.h:34