Vector.h
Go to the documentation of this file.
1#ifndef MiscLib__VECTOR_HEADER__
2#define MiscLib__VECTOR_HEADER__
3#include <algorithm>
4#include <iterator>
5
7#ifdef min
8#undef min
9#endif
10#ifdef max
11#undef max
12#endif
13
14namespace MiscLib
15{
16 // This is a special implementation of std::vector. You should be able to use it whereever you could you use std::vector.
17 // For some reason it is faster than the actual std::vector (at least under windows and with the Intel Compiler)
18 template <class T, class AllocatorT = MiscLib::AlignedAllocator<T>>
19 class Vector : protected AllocatorT
20 {
21 public:
22 typedef size_t size_type;
23 typedef T value_type;
24 typedef T* iterator;
25 typedef const T* const_iterator;
26 typedef T& reference;
27 typedef const T& const_reference;
28 typedef T* pointer;
29 typedef const T* const_pointer;
30 typedef size_t ptrdiff_t;
31 typedef std::reverse_iterator<T*> reverse_iterator;
32 typedef std::reverse_iterator<const T*> const_reverse_iterator;
33
35 {
36 m_begin = NULL;
37 m_end = NULL;
38 m_capacity = NULL;
39 }
40
42 {
43 m_begin = AllocatorT::allocate(s);
44 m_end = m_begin + s;
45 m_capacity = m_end;
47 for (size_type i = 0; i < s; ++i)
48 {
49 AllocatorT::construct(m_begin + i, v);
50 }
51 }
52
53 Vector(size_type s, const T& v)
54 {
55 m_begin = AllocatorT::allocate(s);
56 m_end = m_begin + s;
57 m_capacity = m_end;
58 for (size_type i = 0; i < s; ++i)
59 {
60 AllocatorT::construct(m_begin + i, v);
61 }
62 }
63
64 Vector(const Vector<T, AllocatorT>& v) : AllocatorT(v)
65 {
66 size_type s = v.size();
67 if (!s)
68 {
69 m_begin = NULL;
70 m_end = NULL;
71 m_capacity = NULL;
72 return;
73 }
74 m_begin = AllocatorT::allocate(s);
75 m_end = m_begin + s;
76 m_capacity = m_end;
77 for (size_type i = 0; i < s; ++i)
78 {
79 AllocatorT::construct(m_begin + i, v.m_begin[i]);
80 }
81 }
82
83 template <class OtherAllocatorT>
85 {
86 size_type s = v.size();
87 if (!s)
88 {
89 m_begin = NULL;
90 m_end = NULL;
91 m_capacity = NULL;
92 return;
93 }
94 m_begin = AllocatorT::allocate(s);
95 m_end = m_begin + s;
96 m_capacity = m_end;
97 for (size_type i = 0; i < s; ++i)
98 {
99 AllocatorT::construct(m_begin + i, v.m_begin[i]);
100 }
101 }
102
104 {
105 if (m_begin)
106 {
107 for (size_type i = 0; i < size(); ++i)
108 {
109 AllocatorT::destroy(m_begin + i);
110 }
111 AllocatorT::deallocate(m_begin, capacity());
112 }
113 }
114
117 {
118 if (&v == this)
119 {
120 return *this;
121 }
122 size_type s = v.size();
123 if (!s)
124 {
125 clear();
126 return *this;
127 }
128 if (m_begin)
129 {
130 for (size_type i = 0; i < size(); ++i)
131 {
132 AllocatorT::destroy(m_begin + i);
133 }
134 AllocatorT::deallocate(m_begin, capacity());
135 }
136 m_begin = AllocatorT::allocate(s);
137 m_end = m_begin + s;
138 m_capacity = m_end;
139 for (size_type i = 0; i < s; ++i)
140 {
141 AllocatorT::construct(m_begin + i, v.m_begin[i]);
142 }
143 return *this;
144 }
145
146 template <class OtherAllocatorT>
149 {
150 size_type s = v.size();
151 if (!s)
152 {
153 clear();
154 return *this;
155 }
156 if (m_begin)
157 {
158 for (size_type i = 0; i < size(); ++i)
159 {
160 AllocatorT::destroy(m_begin + i);
161 }
162 AllocatorT::deallocate(m_begin, capacity());
163 }
164 m_begin = AllocatorT::allocate(s);
165 m_end = m_begin + s;
166 m_capacity = m_end;
167 for (size_type i = 0; i < s; ++i)
168 {
169 AllocatorT::construct(m_begin + i, v.m_begin[i]);
170 }
171 return *this;
172 }
173
174 void
176 {
177 if (m_begin)
178 {
179 for (size_type i = 0; i < size(); ++i)
180 {
181 AllocatorT::destroy(m_begin + i);
182 }
183 AllocatorT::deallocate(m_begin, capacity());
184 }
185 m_end = m_begin = m_capacity = NULL;
186 }
187
188 void
190 {
191 if (!s)
192 {
193 return;
194 }
195 if ((size_type)(m_capacity - m_begin) < s)
196 {
197 size_type olds = size();
198 T* newBegin = AllocatorT::allocate(s);
199 if (m_begin)
200 {
201 for (size_type i = 0; i < olds; ++i)
202 {
203 AllocatorT::construct(newBegin + i, m_begin[i]);
204 AllocatorT::destroy(m_begin + i);
205 }
206 AllocatorT::deallocate(m_begin, capacity());
207 }
208 m_end = newBegin + olds;
209 m_begin = newBegin;
210 m_capacity = m_begin + s;
211 }
212 }
213
215 size() const
216 {
217 return m_end - m_begin;
218 }
219
221 capacity() const
222 {
223 return m_capacity - m_begin;
224 }
225
226 void
228 {
229 if (!s)
230 {
231 clear();
232 return;
233 }
234 if ((size_type)(m_capacity - m_begin) >= s)
235 {
236 if (2 * s <= capacity())
237 {
238 T* newBegin = AllocatorT::allocate(s);
239 size_type copyRange = std::min(s, size());
240 for (size_type i = 0; i < copyRange; ++i)
241 {
242 AllocatorT::construct(newBegin + i, m_begin[i]);
243 AllocatorT::destroy(m_begin + i);
244 }
245 for (size_type i = s; i < size(); ++i)
246 {
247 AllocatorT::destroy(m_begin + i);
248 }
249 for (size_type i = size(); i < s; ++i)
250 {
251 AllocatorT::construct(newBegin + i, v);
252 }
253 AllocatorT::deallocate(m_begin, capacity());
254 m_end = newBegin + s;
255 m_begin = newBegin;
256 m_capacity = m_begin + s;
257 return;
258 }
259 for (size_type i = size(); i < s; ++i)
260 {
261 AllocatorT::construct(m_begin + i, v);
262 }
263 for (size_type i = s; i < size(); ++i)
264 {
265 AllocatorT::destroy(m_begin + i);
266 }
267 m_end = m_begin + s;
268 return;
269 }
270 size_type newCapacity = std::max(s, capacity() + capacity() / 2);
271 T* newBegin = AllocatorT::allocate(newCapacity);
272 if (m_begin)
273 {
274 for (size_type i = 0; i < size(); ++i)
275 {
276 AllocatorT::construct(newBegin + i, m_begin[i]);
277 AllocatorT::destroy(m_begin + i);
278 }
279 AllocatorT::deallocate(m_begin, capacity());
280 for (size_type i = size(); i < s; ++i)
281 {
282 AllocatorT::construct(newBegin + i, v);
283 }
284 }
285 else
286 {
287 for (size_type i = 0; i < s; ++i)
288 {
289 AllocatorT::construct(newBegin + i, v);
290 }
291 }
292 m_end = newBegin + s;
293 m_begin = newBegin;
294 m_capacity = m_begin + newCapacity;
295 }
296
297 void
299 {
300 resize(s, value_type());
301 }
302
303 operator T*()
304 {
305 return m_begin;
306 }
307
308 operator const T*() const
309 {
310 return m_begin;
311 }
312
313 T&
315 {
316 return m_begin[i];
317 }
318
319 const T&
320 at(size_type i) const
321 {
322 return m_begin[i];
323 }
324
325 //T &operator[](size_type i)
326 //{
327 // if(i >= size())
328 // throw int(1);
329 // return m_begin[i];
330 //}
331
332 //const T &operator[](size_type i) const
333 //{
334 // if(i >= size())
335 // throw int(1);
336 // return m_begin[i];
337 //}
338
339 //T &at(size_type i)
340 //{
341 // if(i >= size())
342 // throw int(1);
343 // return m_begin[i];
344 //}
345
346 //const T &at(size_type i) const
347 //{
348 // if(i >= size())
349 // throw int(1);
350 // return m_begin[i];
351 //}
352
353 void
354 push_back(const T& v)
355 {
356 if (m_end >= m_capacity)
357 {
358 size_type olds = size();
359 size_type s = olds * 2;
360 if (!s)
361 {
362 s = 1;
363 }
364 T* newBegin = AllocatorT::allocate(s);
365 if (m_begin)
366 {
367 for (size_type i = 0; i < olds; ++i)
368 {
369 AllocatorT::construct(newBegin + i, m_begin[i]);
370 AllocatorT::destroy(m_begin + i);
371 }
372 AllocatorT::deallocate(m_begin, capacity());
373 }
374 m_end = newBegin + olds;
375 m_begin = newBegin;
376 m_capacity = m_begin + s;
377 }
378 AllocatorT::construct(m_end, v);
379 ++m_end;
380 }
381
382 void
383 insert(T* where, const T& v)
384 {
385 size_type whereIdx = where - m_begin;
386 if (m_end >= m_capacity)
387 {
388 size_type olds = size();
389 size_type s = olds * 2;
390 if (!s)
391 {
392 s = 1;
393 }
394 T* newBegin = AllocatorT::allocate(s);
395 if (m_begin)
396 {
397 for (size_type i = 0; i < olds; ++i)
398 {
399 AllocatorT::construct(newBegin + i, m_begin[i]);
400 AllocatorT::destroy(m_begin + i);
401 }
402 AllocatorT::deallocate(m_begin, capacity());
403 }
404 m_end = newBegin + olds;
405 m_begin = newBegin;
406 m_capacity = m_begin + s;
407 where = m_begin + whereIdx;
408 }
409 if (size() > whereIdx)
410 {
411 AllocatorT::construct(m_end, m_begin[size() - 1]);
412 for (size_type i = size() - 1; i > whereIdx; --i)
413 {
414 m_begin[i] = m_begin[i - 1];
415 }
416 *where = v;
417 }
418 else
419 {
420 AllocatorT::construct(where, v);
421 }
422 ++m_end;
423 }
424
425 void
426 erase(T* where)
427 {
428 for (size_type i = where - m_begin; i < size() - 1; ++i)
429 {
430 m_begin[i] = m_begin[i + 1];
431 }
432 --m_end;
433 AllocatorT::destroy(m_end);
434 size_type s = size();
435 if (s && 2 * s <= capacity())
436 {
437 T* newBegin = AllocatorT::allocate(size());
438 for (size_type i = 0; i < s; ++i)
439 {
440 AllocatorT::construct(newBegin + i, m_begin[i]);
441 AllocatorT::destroy(m_begin + i);
442 }
443 AllocatorT::deallocate(m_begin, capacity());
444 m_end = newBegin + s;
445 m_begin = newBegin;
446 m_capacity = m_begin + s;
447 }
448 }
449
450 void
452 {
453 --m_end;
454 AllocatorT::destroy(m_end);
455 size_type s = size();
456 if (s && 2 * s <= capacity())
457 {
458 T* newBegin = AllocatorT::allocate(size());
459 for (size_type i = 0; i < s; ++i)
460 {
461 AllocatorT::construct(newBegin + i, m_begin[i]);
462 AllocatorT::destroy(m_begin + i);
463 }
464 AllocatorT::deallocate(m_begin, capacity());
465 m_end = newBegin + s;
466 m_begin = newBegin;
467 m_capacity = m_begin + s;
468 }
469 }
470
471 T*
473 {
474 return m_begin;
475 }
476
477 const T*
478 begin() const
479 {
480 return m_begin;
481 }
482
483 T*
485 {
486 return m_end;
487 }
488
489 const T*
490 end() const
491 {
492 return m_end;
493 }
494
497 {
498 return std::reverse_iterator<T*>(m_end);
499 }
500
502 rbegin() const
503 {
504 return std::reverse_iterator<const T*>(m_end);
505 }
506
509 {
510 return std::reverse_iterator<T*>(m_begin);
511 }
512
514 rend() const
515 {
516 return std::reverse_iterator<const T*>(m_begin);
517 }
518
519 T&
521 {
522 return *(m_end - 1);
523 }
524
525 const T&
526 back() const
527 {
528 return *(m_end - 1);
529 }
530
531 T&
533 {
534 return *m_begin;
535 }
536
537 const T&
538 front() const
539 {
540 return *m_begin;
541 }
542
543 private:
544 T* m_begin;
545 T* m_end;
546 T* m_capacity;
547 };
548}; // namespace MiscLib
549
550#endif
void pop_back()
Definition Vector.h:451
const_reverse_iterator rend() const
Definition Vector.h:514
void resize(size_type s, const value_type &v)
Definition Vector.h:227
const T * end() const
Definition Vector.h:490
void resize(size_type s)
Definition Vector.h:298
std::reverse_iterator< const T * > const_reverse_iterator
Definition Vector.h:32
const T & front() const
Definition Vector.h:538
const T * const_iterator
Definition Vector.h:25
Vector< T, AllocatorT > & operator=(const Vector< T, AllocatorT > &v)
Definition Vector.h:116
Vector(const Vector< T, AllocatorT > &v)
Definition Vector.h:64
size_t size_type
Definition Vector.h:22
const T * const_pointer
Definition Vector.h:29
T & at(size_type i)
Definition Vector.h:314
std::reverse_iterator< T * > reverse_iterator
Definition Vector.h:31
size_type size() const
Definition Vector.h:215
void erase(T *where)
Definition Vector.h:426
reverse_iterator rend()
Definition Vector.h:508
const T & back() const
Definition Vector.h:526
void push_back(const T &v)
Definition Vector.h:354
void reserve(size_type s)
Definition Vector.h:189
Vector< T, AllocatorT > & operator=(const Vector< T, OtherAllocatorT > &v)
Definition Vector.h:148
size_t ptrdiff_t
Definition Vector.h:30
void clear()
Definition Vector.h:175
Vector(size_type s)
Definition Vector.h:41
reverse_iterator rbegin()
Definition Vector.h:496
size_type capacity() const
Definition Vector.h:221
const T & at(size_type i) const
Definition Vector.h:320
const_reverse_iterator rbegin() const
Definition Vector.h:502
const T * begin() const
Definition Vector.h:478
Vector(const Vector< T, OtherAllocatorT > &v)
Definition Vector.h:84
const T & const_reference
Definition Vector.h:27
Vector(size_type s, const T &v)
Definition Vector.h:53
void insert(T *where, const T &v)
Definition Vector.h:383