sources/list.h

changeset 181
e254398fcc7c
parent 180
2e7225dbd9b2
child 182
20ca0a6be175
equal deleted inserted replaced
180:2e7225dbd9b2 181:e254398fcc7c
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #pragma once 31 #pragma once
32 #include <vector>
32 #include "basics.h" 33 #include "basics.h"
33 #include <algorithm>
34 #include <deque>
35 #include <functional>
36 #include <cassert>
37 #include <vector>
38 #include "range.h" 34 #include "range.h"
39 BEGIN_ZFC_NAMESPACE 35 BEGIN_ZFC_NAMESPACE
40 36
41 // ------------------------------------------------------------------------------------------------- 37 template<typename T>
42 // 38 using Vector = std::vector<T>;
43 template<typename T, typename C>
44 class Container
45 {
46 public:
47 typedef typename C::iterator Iterator;
48 typedef typename C::const_iterator ConstIterator;
49 typedef typename C::reverse_iterator ReverseIterator;
50 typedef typename C::const_reverse_iterator ConstReverseIterator;
51 typedef Container<T, C> Self;
52
53 Container(){}
54
55 Container (int numvalues) :
56 m_container (numvalues) {}
57
58 Container (const C& other) :
59 m_container (other) {}
60
61 Container(std::initializer_list<T> initializerList) :
62 m_container(initializerList) {}
63
64 T& append (const T& value)
65 {
66 m_container.push_back (value);
67 return m_container[m_container.size() - 1];
68 }
69
70 void append(const T* values, size_t numValues)
71 {
72 size_t i0 = size();
73 resize(size() + numValues);
74
75 for (size_t i : range(numValues))
76 (*this)[i0 + i] = values[i];
77 }
78
79 Iterator begin()
80 {
81 return m_container.begin();
82 }
83
84 ConstIterator begin() const
85 {
86 return m_container.begin();
87 }
88
89 void clear()
90 {
91 m_container.clear();
92 }
93
94 bool contains (const T& a) const
95 {
96 return std::find (m_container.begin(), m_container.end(), a) != m_container.end();
97 }
98
99 ConstReverseIterator crbegin() const
100 {
101 return m_container.rbegin();
102 }
103
104 ConstReverseIterator crend() const
105 {
106 return m_container.rend();
107 }
108
109 const C& container() const
110 {
111 return m_container;
112 }
113
114 Iterator end()
115 {
116 return m_container.end();
117 }
118
119 ConstIterator end() const
120 {
121 return m_container.end();
122 }
123
124 Iterator find (const T& needle)
125 {
126 auto it = std::find (m_container.begin(), m_container.end(), needle);
127
128 if (it == m_container.end())
129 return end();
130
131 return it;
132 }
133
134 ConstIterator find (const T& needle) const
135 {
136 auto it = std::find (m_container.begin(), m_container.end(), needle);
137
138 if (it == m_container.end())
139 return end();
140
141 return it;
142 }
143
144 Iterator find (bool (*func)(T const&))
145 {
146 for (Iterator it = begin(); it != end(); ++it)
147 {
148 if (func (*it))
149 return it;
150 }
151
152 return end();
153 }
154
155 ConstIterator find (bool (*func)(T const&)) const
156 {
157 for (ConstIterator it = begin(); it != end(); ++it)
158 {
159 if (func (*it))
160 return it;
161 }
162
163 return end();
164 }
165
166 T& first()
167 {
168 return *begin();
169 }
170
171 const T& first() const
172 {
173 return *begin();
174 }
175
176 void insert (int pos, const T& value)
177 {
178 m_container.insert (m_container.begin() + pos, value);
179 }
180
181 bool is_empty() const
182 {
183 return size() == 0;
184 }
185
186 T& last()
187 {
188 return *(end() - 1);
189 }
190
191 const T& last() const
192 {
193 return *(end() - 1);
194 }
195
196 void merge (const Self& other)
197 {
198 int oldsize = size();
199 resize (size() + other.size());
200 std::copy (other.begin(), other.end(), begin() + oldsize);
201 }
202
203 bool pop (T& val)
204 {
205 if (is_empty())
206 return false;
207
208 val = m_container[size() - 1];
209 m_container.erase (m_container.end() - 1);
210 return true;
211 }
212
213 T& prepend (const T& value)
214 {
215 m_container.push_front (value);
216 return m_container[0];
217 }
218
219 ReverseIterator rbegin()
220 {
221 return m_container.rbegin();
222 }
223
224 void remove_at (int pos)
225 {
226 assert (pos < size());
227 m_container.erase (m_container.begin() + pos);
228 }
229
230 void remove_duplicates()
231 {
232 sort();
233 resize (std::distance (begin(), std::unique (begin(), end())));
234 }
235
236 void remove_one (const T& valueToRemove)
237 {
238 auto it = std::find (m_container.begin(), m_container.end(), valueToRemove);
239
240 if (it != m_container.end())
241 m_container.erase (it);
242 }
243
244 ReverseIterator rend()
245 {
246 return m_container.rend();
247 }
248
249 void resize (int size)
250 {
251 m_container.resize (size);
252 }
253
254 Self reverse() const
255 {
256 Self rev;
257 std::copy (rbegin(), rend(), rev.begin());
258 return rev;
259 }
260
261 int size() const
262 {
263 return m_container.size();
264 }
265
266 void sort()
267 {
268 std::sort (begin(), end());
269 }
270
271 Self splice(int start, int end, int step = 1) const
272 {
273 start = clamp(start, 0, size());
274 end = clamp(end, 0, size());
275
276 if (end <= start)
277 {
278 return Self();
279 }
280 else
281 {
282 Self result;
283
284 for (int i : range(start, end, step))
285 result << operator[] (i);
286
287 return result;
288 }
289 }
290
291 Self splice(Range<int>& range) const
292 {
293 return splice(range.min(), range.max(), range.step());
294 }
295
296 Self& operator<< (const T& value)
297 {
298 append (value);
299 return *this;
300 }
301
302 Self& operator<< (const Self& vals)
303 {
304 merge (vals);
305 return *this;
306 }
307
308 T& operator[] (int n)
309 {
310 assert (n < size());
311 return m_container[n];
312 }
313
314 const T& operator[] (int n) const
315 {
316 assert (n < size());
317 return m_container[n];
318 }
319
320 Self operator[] (Range<int> const& n) const
321 {
322 return splice (n);
323 }
324
325 Self operator+ (const Self& other) const
326 {
327 Self out (*this);
328 out.merge (other);
329 return out;
330 }
331
332 protected:
333 C m_container;
334 };
335
336 // -------------------------------------------------------------------------------------------------
337 //
338 template<typename T, typename C>
339 Container<T, C>& operator>> (const T& value, Container<T, C>& haystack)
340 {
341 haystack.prepend (value);
342 return haystack;
343 }
344
345 // -------------------------------------------------------------------------------------------------
346 //
347 39
348 template<typename T> 40 template<typename T>
349 class Vector : public Container<T, std::vector<T> > 41 auto& last(T& container)
350 { 42 {
351 public: 43 return *(container.begin() + container.size() - 1);
352 typedef Container<T, std::vector<T> > Super; 44 }
353
354 Vector(){}
355
356 Vector(int numvalues) :
357 Super(numvalues){}
358
359 Vector (T* data, size_t length) :
360 Super (std::vector<T> (data, data + length)) {}
361
362 Vector(std::initializer_list<T> initializerList) :
363 Super(initializerList) {}
364
365 Vector(const Super& other) :
366 Super(other) {}
367
368 T* data()
369 {
370 return Super::m_container.data();
371 }
372
373 const T* data() const
374 {
375 return Super::m_container.data();
376 }
377
378 operator const T*() const
379 {
380 return data();
381 }
382 };
383 45
384 using ByteArray = std::vector<unsigned char>; 46 using ByteArray = std::vector<unsigned char>;
385 class String quote(const ByteArray& bytes); 47 class String quote(const ByteArray& bytes);
386 48
387 template<typename T> 49 template<typename T>

mercurial