src/Containers.h

changeset 119
bdf8d46c145f
parent 118
e3361cf7cbf4
child 120
5ea0faefa82a
equal deleted inserted replaced
118:e3361cf7cbf4 119:bdf8d46c145f
1 /*
2 Copyright 2012-2014 Santeri Piippo
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. The name of the author may not be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef BOTC_CONTAINERS_H
30 #define BOTC_CONTAINERS_H
31
32 #include <cassert>
33 #include <algorithm>
34 #include <deque>
35 #include <initializer_list>
36
37 template<typename T>
38 class List
39 {
40 public:
41 using WrappedList = typename std::deque<T>;
42 using Iterator = typename WrappedList::iterator;
43 using ConstIterator = typename WrappedList::const_iterator;
44 using ReverseIterator = typename WrappedList::reverse_iterator;
45 using ConstReverseIterator = typename WrappedList::const_reverse_iterator;
46 using ValueType = T;
47 using Self = List<T>;
48
49 // =====================================================================
50 //
51 List() {}
52
53 // =====================================================================
54 //
55 List (std::initializer_list<ValueType> vals)
56 {
57 m_data = vals;
58 }
59
60 // =====================================================================
61 //
62 List (const WrappedList& a) :
63 m_data (a) {}
64
65 // =====================================================================
66 //
67 Iterator begin()
68 {
69 return m_data.begin();
70 }
71
72 // =====================================================================
73 //
74 ConstIterator begin() const
75 {
76 return m_data.cbegin();
77 }
78
79 // =====================================================================
80 //
81 Iterator end()
82 {
83 return m_data.end();
84 }
85
86 // =====================================================================
87 //
88 ConstIterator end() const
89 {
90 return m_data.cend();
91 }
92
93 // =====================================================================
94 //
95 ReverseIterator rbegin()
96 {
97 return m_data.rbegin();
98 }
99
100 // =====================================================================
101 //
102 ConstReverseIterator crbegin() const
103 {
104 return m_data.crbegin();
105 }
106
107 // =====================================================================
108 //
109 ReverseIterator rend()
110 {
111 return m_data.rend();
112 }
113
114 // =====================================================================
115 //
116 ConstReverseIterator crend() const
117 {
118 return m_data.crend();
119 }
120
121 // =====================================================================
122 //
123 inline void removeAt (int pos)
124 {
125 assert (pos < size());
126 m_data.erase (m_data.begin() + pos);
127 }
128
129 // =====================================================================
130 //
131 ValueType& prepend (const ValueType& value)
132 {
133 m_data.push_front (value);
134 return m_data[0];
135 }
136
137 // =====================================================================
138 //
139 ValueType& append (const ValueType& value)
140 {
141 m_data.push_back (value);
142 return m_data[m_data.size() - 1];
143 }
144
145 // =====================================================================
146 //
147 void merge (const Self& other)
148 {
149 resize (size() + other.size());
150 std::copy (other.begin(), other.end(), begin() + other.size());
151 }
152
153 // =====================================================================
154 //
155 bool pop (T& val)
156 {
157 if (isEmpty())
158 return false;
159
160 val = m_data[size() - 1];
161 m_data.erase (m_data.end() - 1);
162 return true;
163 }
164
165 // =====================================================================
166 //
167 Self& operator<< (const T& value)
168 {
169 append (value);
170 return *this;
171 }
172
173 // =====================================================================
174 //
175 void operator<< (const Self& vals)
176 {
177 merge (vals);
178 }
179
180 // =====================================================================
181 //
182 bool operator>> (T& value)
183 {
184 return pop (value);
185 }
186
187 // =====================================================================
188 //
189 Self reverse() const
190 {
191 Self rev;
192
193 for (const T & val : *this)
194 val >> rev;
195
196 return rev;
197 }
198
199 // =====================================================================
200 //
201 void clear()
202 {
203 m_data.clear();
204 }
205
206 // =====================================================================
207 //
208 void insert (int pos, const ValueType& value)
209 {
210 m_data.insert (m_data.begin() + pos, value);
211 }
212
213 // =====================================================================
214 //
215 void removeDuplicates()
216 {
217 // Remove duplicate entries. For this to be effective, the vector must be
218 // sorted first.
219 sort();
220 Iterator pos = std::unique (begin(), end());
221 resize (std::distance (begin(), pos));
222 }
223
224 // =====================================================================
225 //
226 int size() const
227 {
228 return m_data.size();
229 }
230
231 // =====================================================================
232 //
233 ValueType& operator[] (int n)
234 {
235 assert (n < size());
236 return m_data[n];
237 }
238
239 // =====================================================================
240 //
241 const ValueType& operator[] (int n) const
242 {
243 assert (n < size());
244 return m_data[n];
245 }
246
247 // =====================================================================
248 //
249 void resize (int size)
250 {
251 m_data.resize (size);
252 }
253
254 // =====================================================================
255 //
256 void sort()
257 {
258 std::sort (begin(), end());
259 }
260
261 // =====================================================================
262 //
263 int find (const ValueType& needle) const
264 {
265 int i = 0;
266
267 for (const ValueType& hay : *this)
268 {
269 if (hay == needle)
270 return i;
271
272 i++;
273 }
274
275 return -1;
276 }
277
278 // =====================================================================
279 //
280 void removeOne (const ValueType& it)
281 {
282 int idx;
283
284 if ((idx = find (it)) != -1)
285 removeAt (idx);
286 }
287
288 // =====================================================================
289 //
290 inline bool isEmpty() const
291 {
292 return size() == 0;
293 }
294
295 // =====================================================================
296 //
297 Self splice (int a, int b) const
298 {
299 assert (a >= 0 && b >= 0 && a < size() && b < size() && a <= b);
300 Self result;
301
302 for (int i = a; i <= b; ++i)
303 result << operator[] (i);
304
305 return result;
306 }
307
308 // =====================================================================
309 //
310 inline const WrappedList& deque() const
311 {
312 return m_data;
313 }
314
315 // =====================================================================
316 //
317 inline const ValueType& first() const
318 {
319 return *m_data.begin();
320 }
321
322 // =====================================================================
323 //
324 inline const ValueType& last() const
325 {
326 return *(m_data.end() - 1);
327 }
328
329 // =====================================================================
330 //
331 inline bool contains (const ValueType& a) const
332 {
333 return find (a) != -1;
334 }
335
336 // =====================================================================
337 //
338 Self operator+ (const Self& other) const
339 {
340 Self out (*this);
341 out.merge (other);
342 return out;
343 }
344
345 private:
346 WrappedList m_data;
347 };
348
349 // =============================================================================
350 //
351 template<typename T>
352 List<T>& operator>> (const T& value, List<T>& haystack)
353 {
354 haystack.prepend (value);
355 return haystack;
356 }
357
358 #endif // BOTC_CONTAINERS_H

mercurial