libquentier  0.4.0
The library for rich desktop clients of Evernote service
LimitedStack.h
1 /*
2  * Copyright 2016 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 #include <QStack>
24 
25 namespace quentier {
26 
32 template <class T>
33 class LimitedStack: public QStack<T>
34 {
35 public:
36  LimitedStack(void (*deleter)(T&) = Q_NULLPTR) : m_limit(-1), m_deleter(deleter) {}
37  LimitedStack(const LimitedStack<T> & other) : QStack<T>(other), m_limit(other.m_limit), m_deleter(other.m_deleter) {}
38  LimitedStack(LimitedStack<T> && other) : QStack<T>(std::move(other)), m_limit(std::move(other.m_limit)), m_deleter(std::move(other.m_deleter)) {}
39 
40  LimitedStack<T> & operator=(const LimitedStack<T> & other)
41  {
42  if (this != &other) {
43  QStack<T>::operator=(other);
44  m_limit = other.m_limit;
45  m_deleter = other.m_deleter;
46  }
47 
48  return *this;
49  }
50 
51  LimitedStack<T> & operator=(LimitedStack<T> && other)
52  {
53  if (this != &other) {
54  QStack<T>::operator=(std::move(other));
55  m_limit = std::move(other.m_limit);
56  m_deleter = std::move(other.m_deleter);
57  }
58 
59  return *this;
60  }
61 
62  ~LimitedStack()
63  {
64  if (m_deleter)
65  {
66  while (!QStack<T>::isEmpty()) {
67  T t = QStack<T>::pop();
68  (*m_deleter)(t);
69  }
70  }
71  }
72 
73  void swap(const LimitedStack<T> & other)
74  {
75  int limit = other.m_limit;
76  other.m_limit = m_limit;
77  m_limit = limit;
78 
79  void (*deleter)(T &) = other.m_deleter;
80  other.m_deleter = m_deleter;
81  m_deleter = deleter;
82 
83  QStack<T>::swap(other);
84  }
85 
86  int limit() const { return m_limit; }
87  void setLimit(const int limit) { m_limit = limit; }
88 
89  void push(const T & t)
90  {
91  if ((m_limit > 0) && (QVector<T>::size() == m_limit - 1)) {
92  if (m_deleter) {
93  (*m_deleter)(*QVector<T>::begin());
94  }
95  Q_UNUSED(QVector<T>::erase(QVector<T>::begin()));
96  }
97 
98  QStack<T>::push(t);
99  }
100 
101 private:
102  int m_limit;
103  void (*m_deleter)(T &);
104 };
105 
106 } // namespace quentier
107 
108 #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:33