src/containers.h

changeset 88
5def6ff8b466
parent 87
8f65914e7046
child 89
029a330a9bef
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> class list
38 {
39 public:
40 using list_type = typename ::std::deque<T>;
41 using iterator = typename list_type::iterator;
42 using const_iterator = typename list_type::const_iterator;
43 using reverse_iterator = typename list_type::reverse_iterator;
44 using const_reverse_iterator = typename list_type::const_reverse_iterator;
45 using element_type = T;
46 using self_type = list<T>;
47
48 // =====================================================================
49 //
50 list() {}
51
52 // =====================================================================
53 //
54 list (std::initializer_list<element_type> vals)
55 {
56 m_data = vals;
57 }
58
59 // =====================================================================
60 //
61 list (const list_type& a) :
62 m_data (a) {}
63
64 // =====================================================================
65 //
66 iterator begin()
67 {
68 return m_data.begin();
69 }
70
71 // =====================================================================
72 //
73 const_iterator begin() const
74 {
75 return m_data.cbegin();
76 }
77
78 // =====================================================================
79 //
80 iterator end()
81 {
82 return m_data.end();
83 }
84
85 // =====================================================================
86 //
87 const_iterator end() const
88 {
89 return m_data.cend();
90 }
91
92 // =====================================================================
93 //
94 reverse_iterator rbegin()
95 {
96 return m_data.rbegin();
97 }
98
99 // =====================================================================
100 //
101 const_reverse_iterator crbegin() const
102 {
103 return m_data.crbegin();
104 }
105
106 // =====================================================================
107 //
108 reverse_iterator rend()
109 {
110 return m_data.rend();
111 }
112
113 // =====================================================================
114 //
115 const_reverse_iterator crend() const
116 {
117 return m_data.crend();
118 }
119
120 // =====================================================================
121 //
122 inline void erase (int pos)
123 {
124 assert (pos < size());
125 m_data.erase (m_data.begin() + pos);
126 }
127
128 // =====================================================================
129 //
130 element_type& push_front (const element_type& value)
131 {
132 m_data.push_front (value);
133 return m_data[0];
134 }
135
136 // =====================================================================
137 //
138 element_type& push_back (const element_type& value)
139 {
140 m_data.push_back (value);
141 return m_data[m_data.size() - 1];
142 }
143
144 // =====================================================================
145 //
146 void push_back (const self_type& vals)
147 {
148 for (const T & val : vals)
149 push_back (val);
150 }
151
152 // =====================================================================
153 //
154 bool pop (T& val)
155 {
156 if (is_empty())
157 return false;
158
159 val = m_data[size() - 1];
160 m_data.erase (m_data.end() - 1);
161 return true;
162 }
163
164 // =====================================================================
165 //
166 T& operator<< (const T& value)
167 {
168 return push_back (value);
169 }
170
171 // =====================================================================
172 //
173 void operator<< (const self_type& vals)
174 {
175 push_back (vals);
176 }
177
178 // =====================================================================
179 //
180 bool operator>> (T& value)
181 {
182 return pop (value);
183 }
184
185 // =====================================================================
186 //
187 self_type reverse() const
188 {
189 self_type rev;
190
191 for (const T & val : *this)
192 val >> rev;
193
194 return rev;
195 }
196
197 // =====================================================================
198 //
199 void clear()
200 {
201 m_data.clear();
202 }
203
204 // =====================================================================
205 //
206 void insert (int pos, const element_type& value)
207 {
208 m_data.insert (m_data.begin() + pos, value);
209 }
210
211 // =====================================================================
212 //
213 void makeUnique()
214 {
215 // Remove duplicate entries. For this to be effective, the vector must be
216 // sorted first.
217 sort();
218 iterator pos = std::unique (begin(), end());
219 resize (std::distance (begin(), pos));
220 }
221
222 // =====================================================================
223 //
224 int size() const
225 {
226 return m_data.size();
227 }
228
229 // =====================================================================
230 //
231 element_type& operator[] (int n)
232 {
233 assert (n < size());
234 return m_data[n];
235 }
236
237 // =====================================================================
238 //
239 const element_type& operator[] (int n) const
240 {
241 assert (n < size());
242 return m_data[n];
243 }
244
245 // =====================================================================
246 //
247 void resize (int size)
248 {
249 m_data.resize (size);
250 }
251
252 // =====================================================================
253 //
254 void sort()
255 {
256 std::sort (begin(), end());
257 }
258
259 // =====================================================================
260 //
261 int find (const element_type& needle) const
262 {
263 int i = 0;
264
265 for (const element_type& hay : *this)
266 {
267 if (&hay == &needle)
268 return i;
269
270 i++;
271 }
272
273 return -1;
274 }
275
276 // =====================================================================
277 //
278 void remove (const element_type& it)
279 {
280 int idx;
281
282 if ((idx = find (it)) != -1)
283 erase (idx);
284 }
285
286 // =====================================================================
287 //
288 inline bool is_empty() const
289 {
290 return size() == 0;
291 }
292
293 // =====================================================================
294 //
295 self_type mid (int a, int b) const
296 {
297 assert (a >= 0 && b >= 0 && a < size() && b < size() && a <= b);
298 self_type result;
299
300 for (int i = a; i <= b; ++i)
301 result << operator[] (i);
302
303 return result;
304 }
305
306 // =====================================================================
307 //
308 inline const list_type& std_deque() const
309 {
310 return m_data;
311 }
312
313 // =====================================================================
314 //
315 const element_type& first() const
316 {
317 return *(m_data.begin());
318 }
319
320 // =====================================================================
321 //
322 const element_type& last() const
323 {
324 return *(m_data.end() - 1);
325 }
326
327 // =====================================================================
328 //
329 bool contains (const element_type& a) const
330 {
331 return find (a) != -1;
332 }
333
334 private:
335 list_type m_data;
336 };
337
338 // =============================================================================
339 //
340 template<class T> list<T>& operator>> (const T& value, list<T>& haystack)
341 {
342 haystack.push_front (value);
343 return haystack;
344 }
345
346 #endif // BOTC_CONTAINERS_H

mercurial