src/Containers.h

changeset 88
5def6ff8b466
child 94
8915ee6a277d
equal deleted inserted replaced
87:8f65914e7046 88:5def6ff8b466
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<class T>
38 class List
39 {
40 public:
41 using ListType = typename std::deque<T>;
42 using Iterator = typename ListType::iterator;
43 using ConstIterator = typename ListType::const_iterator;
44 using ReverseIterator = typename ListType::reverse_iterator;
45 using ConstReverseIterator = typename ListType::const_reverse_iterator;
46 using ValueType = T;
47 using SelfType = 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 ListType& 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 SelfType& vals)
148 {
149 for (const T & val : vals)
150 Append (val);
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 T& operator<< (const T& value)
168 {
169 return Append (value);
170 }
171
172 // =====================================================================
173 //
174 void operator<< (const SelfType& vals)
175 {
176 Merge (vals);
177 }
178
179 // =====================================================================
180 //
181 bool operator>> (T& value)
182 {
183 return Pop (value);
184 }
185
186 // =====================================================================
187 //
188 SelfType Reverse() const
189 {
190 SelfType rev;
191
192 for (const T & val : *this)
193 val >> rev;
194
195 return rev;
196 }
197
198 // =====================================================================
199 //
200 void Clear()
201 {
202 m_data.clear();
203 }
204
205 // =====================================================================
206 //
207 void Insert (int pos, const ValueType& value)
208 {
209 m_data.insert (m_data.begin() + pos, value);
210 }
211
212 // =====================================================================
213 //
214 void RemoveDuplicates()
215 {
216 // Remove duplicate entries. For this to be effective, the vector must be
217 // sorted first.
218 Sort();
219 Iterator pos = std::unique (begin(), end());
220 Resize (std::distance (begin(), pos));
221 }
222
223 // =====================================================================
224 //
225 int Size() const
226 {
227 return m_data.size();
228 }
229
230 // =====================================================================
231 //
232 ValueType& operator[] (int n)
233 {
234 assert (n < Size());
235 return m_data[n];
236 }
237
238 // =====================================================================
239 //
240 const ValueType& operator[] (int n) const
241 {
242 assert (n < Size());
243 return m_data[n];
244 }
245
246 // =====================================================================
247 //
248 void Resize (int size)
249 {
250 m_data.resize (size);
251 }
252
253 // =====================================================================
254 //
255 void Sort()
256 {
257 std::sort (begin(), end());
258 }
259
260 // =====================================================================
261 //
262 int Find (const ValueType& needle) const
263 {
264 int i = 0;
265
266 for (const ValueType & hay : *this)
267 {
268 if (&hay == &needle)
269 return i;
270
271 i++;
272 }
273
274 return -1;
275 }
276
277 // =====================================================================
278 //
279 void Remove (const ValueType& it)
280 {
281 int idx;
282
283 if ((idx = Find (it)) != -1)
284 RemoveAt (idx);
285 }
286
287 // =====================================================================
288 //
289 inline bool IsEmpty() const
290 {
291 return Size() == 0;
292 }
293
294 // =====================================================================
295 //
296 SelfType Mid (int a, int b) const
297 {
298 assert (a >= 0 && b >= 0 && a < Size() && b < Size() && a <= b);
299 SelfType result;
300
301 for (int i = a; i <= b; ++i)
302 result << operator[] (i);
303
304 return result;
305 }
306
307 // =====================================================================
308 //
309 inline const ListType& GetDeque() const
310 {
311 return m_data;
312 }
313
314 // =====================================================================
315 //
316 inline const ValueType& First() const
317 {
318 return *m_data.begin();
319 }
320
321 // =====================================================================
322 //
323 inline const ValueType& Last() const
324 {
325 return *(m_data.end() - 1);
326 }
327
328 // =====================================================================
329 //
330 inline bool Contains (const ValueType& a) const
331 {
332 return Find (a) != -1;
333 }
334
335 private:
336 ListType m_data;
337 };
338
339 // =============================================================================
340 //
341 template<class T>
342 List<T>& operator>> (const T& value, List<T>& haystack)
343 {
344 haystack.push_front (value);
345 return haystack;
346 }
347
348 #endif // BOTC_CONTAINERS_H

mercurial