NoShrinkVector.h
Go to the documentation of this file.
1 #ifndef MiscLib__NOSHRINKVECTOR_HEADER__
2 #define MiscLib__NOSHRINKVECTOR_HEADER__
4 
5 namespace MiscLib
6 {
7  // This is a special implementation of std::vector. You should be able to use it whereever you could you use std::vector.
8  // For some reason it is faster than the actual std::vector (at least under windows and with the Intel Compiler)
9  // It also has the special property that it never (!!!) frees memory automatically, even if you call clear()
10  // The only way to get rid of the allocated mem is to call ClearTotal() (or during destruction of course)
11  // Note that element constructors and destructors are invoked correctly though, e.g. when calling clear
12  // all elements are destructed.
13  // The advantage is however that no copying takes place for resize operations (unless new memory must be allocated)
14  // So if you have an array whose size constantly varies between 0 and a max size this class is a good choice
15  // SO BE CAREFUL WHEN USING THIS CLASS, IT MAY WASTE A LOT OF MEMORY!
16  template< class T, class AllocatorT = MiscLib::AlignedAllocator< T > >
18  : protected AllocatorT
19  {
20  public:
21  typedef size_t size_type;
22  typedef T value_type;
23  typedef T* iterator;
24  typedef const T* const_iterator;
25  typedef T& reference;
26  typedef const T& const_reference;
27  typedef T* pointer;
28  typedef const T* const_pointer;
29  typedef size_t ptrdiff_t;
30  typedef std::reverse_iterator< T* > reverse_iterator;
31  typedef std::reverse_iterator< const T* > const_reverse_iterator;
32 
34  {
35  m_begin = NULL;
36  m_end = NULL;
37  m_capacity = NULL;
38  }
39 
41  {
42  m_begin = AllocatorT::allocate(s);
43  m_end = m_begin + s;
44  m_capacity = m_end;
45  value_type v;
46  for (size_type i = 0; i < s; ++i)
47  {
48  AllocatorT::construct(m_begin + i, v);
49  }
50  }
51 
53  {
54  m_begin = AllocatorT::allocate(s);
55  m_end = m_begin + s;
56  m_capacity = m_end;
57  for (size_type i = 0; i < s; ++i)
58  {
59  AllocatorT::construct(m_begin + i, v);
60  }
61  }
62 
64  {
65  size_type s = v.size();
66  if (!s)
67  {
68  m_begin = NULL;
69  m_end = NULL;
70  m_capacity = NULL;
71  return;
72  }
73  m_begin = AllocatorT::allocate(s);
74  m_end = m_begin + s;
75  m_capacity = m_end;
76  for (size_type i = 0; i < s; ++i)
77  {
78  AllocatorT::construct(m_begin + i, v.m_begin[i]);
79  }
80  }
81 
82  template< class OtherAllocatorT >
84  {
85  size_type s = v.size();
86  if (!s)
87  {
88  m_begin = NULL;
89  m_end = NULL;
90  m_capacity = NULL;
91  return;
92  }
93  m_begin = AllocatorT::allocate(s);
94  m_end = m_begin + s;
95  m_capacity = m_end;
96  for (size_type i = 0; i < s; ++i)
97  {
98  AllocatorT::construct(m_begin + i, v.m_begin[i]);
99  }
100  }
101 
103  {
104  if (m_begin)
105  {
106  for (size_type i = 0; i < size(); ++i)
107  {
108  AllocatorT::destroy(m_begin + i);
109  }
110  AllocatorT::deallocate(m_begin, capacity());
111  }
112  }
113 
115  {
116  if (&v == this)
117  {
118  return *this;
119  }
120  size_type s = v.size();
121  if (!s)
122  {
123  clear();
124  return *this;
125  }
126  if (m_begin)
127  {
128  for (size_type i = 0; i < size(); ++i)
129  {
130  AllocatorT::destroy(m_begin + i);
131  }
132  AllocatorT::deallocate(m_begin, capacity());
133  }
134  m_begin = AllocatorT::allocate(s);
135  m_end = m_begin + s;
136  m_capacity = m_end;
137  for (size_type i = 0; i < s; ++i)
138  {
139  AllocatorT::construct(m_begin + i, v.m_begin[i]);
140  }
141  return *this;
142  }
143 
144  template< class OtherAllocatorT >
146  {
147  size_type s = v.size();
148  if (!s)
149  {
150  clear();
151  return *this;
152  }
153  if (m_begin)
154  {
155  for (size_type i = 0; i < size(); ++i)
156  {
157  AllocatorT::destroy(m_begin + i);
158  }
159  AllocatorT::deallocate(m_begin, capacity());
160  }
161  m_begin = AllocatorT::allocate(s);
162  m_end = m_begin + s;
163  m_capacity = m_end;
164  for (size_type i = 0; i < s; ++i)
165  {
166  AllocatorT::construct(m_begin + i, v.m_begin[i]);
167  }
168  return *this;
169  }
170 
171  void clear()
172  {
173  for (size_type i = 0; i < size(); ++i)
174  {
175  AllocatorT::destroy(m_begin + i);
176  }
177  m_end = m_begin;
178  }
179 
180  void ClearTotal()
181  {
182  if (m_begin)
183  {
184  for (size_type i = 0; i < size(); ++i)
185  {
186  AllocatorT::destroy(m_begin + i);
187  }
188  AllocatorT::deallocate(m_begin, capacity());
189  }
190  m_end = m_begin = m_capacity = NULL;
191  }
192 
194  {
195  if (!s)
196  {
197  return;
198  }
199  if (capacity() < s)
200  {
201  size_type olds = size();
202  T* newBegin = AllocatorT::allocate(s);
203  if (m_begin)
204  {
205  for (size_type i = 0; i < olds; ++i)
206  {
207  AllocatorT::construct(newBegin + i, m_begin[i]);
208  AllocatorT::destroy(m_begin + i);
209  }
210  AllocatorT::deallocate(m_begin, capacity());
211  }
212  m_end = newBegin + olds;
213  m_begin = newBegin;
214  m_capacity = m_begin + s;
215  }
216  }
217 
218  size_type size() const
219  {
220  return m_end - m_begin;
221  }
222 
224  {
225  return m_capacity - m_begin;
226  }
227 
228  void resize(size_type s, const value_type& v)
229  {
230  if (!s)
231  {
232  clear();
233  return;
234  }
235  if (capacity() >= s)
236  {
237  for (size_type i = s; i < size(); ++i)
238  {
239  AllocatorT::destroy(m_begin + i);
240  }
241  for (size_type i = size(); i < s; ++i)
242  {
243  AllocatorT::construct(m_begin + i, v);
244  }
245  m_end = m_begin + s;
246  return;
247  }
248  T* newBegin = AllocatorT::allocate(2 * s);
249  if (m_begin)
250  {
251  for (size_type i = 0; i < size(); ++i)
252  {
253  AllocatorT::construct(newBegin + i, m_begin[i]);
254  AllocatorT::destroy(m_begin + i);
255  }
256  AllocatorT::deallocate(m_begin, capacity());
257  for (size_type i = size(); i < s; ++i)
258  {
259  AllocatorT::construct(newBegin + i, v);
260  }
261  }
262  else
263  {
264  for (size_type i = 0; i < s; ++i)
265  {
266  AllocatorT::construct(newBegin + i, v);
267  }
268  }
269  m_end = newBegin + s;
270  m_begin = newBegin;
271  m_capacity = m_begin + 2 * s;
272  }
273 
275  {
276  resize(s, value_type());
277  }
278 
279  operator T* ()
280  {
281  return m_begin;
282  }
283 
284  operator const T* () const
285  {
286  return m_begin;
287  }
288 
290  {
291  return m_begin[i];
292  }
293 
294  const T& at(size_type i) const
295  {
296  return m_begin[i];
297  }
298 
299  void push_back(const T& v)
300  {
301  if (m_end >= m_capacity)
302  {
303  size_type olds = size();
304  size_type s = olds * 2;
305  if (!s)
306  {
307  s = 1;
308  }
309  T* newBegin = AllocatorT::allocate(s);
310  if (m_begin)
311  {
312  for (size_type i = 0; i < olds; ++i)
313  {
314  AllocatorT::construct(newBegin + i, m_begin[i]);
315  AllocatorT::destroy(m_begin + i);
316  }
317  AllocatorT::deallocate(m_begin, capacity());
318  }
319  m_end = newBegin + olds;
320  m_begin = newBegin;
321  m_capacity = m_begin + s;
322  }
323  AllocatorT::construct(m_end, v);
324  ++m_end;
325  }
326 
327  void insert(T* where, const T& v)
328  {
329  size_type whereIdx = where - m_begin;
330  if (m_end >= m_capacity)
331  {
332  size_type olds = size();
333  size_type s = olds * 2;
334  if (!s)
335  {
336  s = 1;
337  }
338  T* newBegin = AllocatorT::allocate(s);
339  if (m_begin)
340  {
341  for (size_type i = 0; i < olds; ++i)
342  {
343  AllocatorT::construct(newBegin + i, m_begin[i]);
344  AllocatorT::destroy(m_begin + i);
345  }
346  AllocatorT::deallocate(m_begin, capacity());
347  }
348  m_end = newBegin + olds;
349  m_begin = newBegin;
350  m_capacity = m_begin + s;
351  where = m_begin + whereIdx;
352  }
353  if (size() > whereIdx)
354  {
355  AllocatorT::construct(m_end, m_begin[size() - 1]);
356  for (size_type i = size() - 1; i > whereIdx; --i)
357  {
358  m_begin[i] = m_begin[i - 1];
359  }
360  *where = v;
361  }
362  else
363  {
364  AllocatorT::construct(where, v);
365  }
366  ++m_end;
367  }
368 
369  void erase(T* where)
370  {
371  for (size_type i = where - m_begin; i < size() - 1; ++i)
372  {
373  m_begin[i] = m_begin[i + 1];
374  }
375  --m_end;
376  AllocatorT::destroy(m_end);
377  }
378 
379  void pop_back()
380  {
381  --m_end;
382  AllocatorT::destroy(m_end);
383  }
384 
385  T* begin()
386  {
387  return m_begin;
388  }
389 
390  const T* begin() const
391  {
392  return m_begin;
393  }
394 
395  T* end()
396  {
397  return m_end;
398  }
399 
400  const T* end() const
401  {
402  return m_end;
403  }
404 
406  {
407  return std::reverse_iterator< T* >(m_end);
408  }
409 
411  {
412  return std::reverse_iterator< const T* >(m_end);
413  }
414 
416  {
417  return std::reverse_iterator< T* >(m_begin);
418  }
419 
421  {
422  return std::reverse_iterator< const T* >(m_begin);
423  }
424 
425  T& back()
426  {
427  return *(m_end - 1);
428  }
429 
430  const T& back() const
431  {
432  return *(m_end - 1);
433  }
434 
435  T& front()
436  {
437  return *m_begin;
438  }
439 
440  const T& front() const
441  {
442  return *m_begin;
443  }
444 
445  private:
446  T* m_begin;
447  T* m_end;
448  T* m_capacity;
449  };
450 };
451 
452 #endif
MiscLib::NoShrinkVector::reverse_iterator
std::reverse_iterator< T * > reverse_iterator
Definition: NoShrinkVector.h:30
MiscLib::NoShrinkVector::rend
const_reverse_iterator rend() const
Definition: NoShrinkVector.h:420
MiscLib::NoShrinkVector::const_pointer
const typedef T * const_pointer
Definition: NoShrinkVector.h:28
MiscLib::NoShrinkVector::capacity
size_type capacity() const
Definition: NoShrinkVector.h:223
MiscLib::NoShrinkVector::pop_back
void pop_back()
Definition: NoShrinkVector.h:379
MiscLib::NoShrinkVector::erase
void erase(T *where)
Definition: NoShrinkVector.h:369
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector(size_type s)
Definition: NoShrinkVector.h:40
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector(const NoShrinkVector< T, OtherAllocatorT > &v)
Definition: NoShrinkVector.h:83
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector(size_type s, const T &v)
Definition: NoShrinkVector.h:52
MiscLib::NoShrinkVector::value_type
T value_type
Definition: NoShrinkVector.h:22
MiscLib::NoShrinkVector::operator=
NoShrinkVector< T > & operator=(const NoShrinkVector< T, OtherAllocatorT > &v)
Definition: NoShrinkVector.h:145
MiscLib::NoShrinkVector::begin
const T * begin() const
Definition: NoShrinkVector.h:390
MiscLib::NoShrinkVector::pointer
T * pointer
Definition: NoShrinkVector.h:27
MiscLib::NoShrinkVector::size_type
size_t size_type
Definition: NoShrinkVector.h:21
MiscLib::NoShrinkVector::end
T * end()
Definition: NoShrinkVector.h:395
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector()
Definition: NoShrinkVector.h:33
MiscLib::NoShrinkVector::rbegin
reverse_iterator rbegin()
Definition: NoShrinkVector.h:405
MiscLib::NoShrinkVector::rbegin
const_reverse_iterator rbegin() const
Definition: NoShrinkVector.h:410
MiscLib::NoShrinkVector::rend
reverse_iterator rend()
Definition: NoShrinkVector.h:415
MiscLib::NoShrinkVector::front
const T & front() const
Definition: NoShrinkVector.h:440
MiscLib::NoShrinkVector::front
T & front()
Definition: NoShrinkVector.h:435
MiscLib::NoShrinkVector
Definition: NoShrinkVector.h:17
MiscLib::NoShrinkVector::push_back
void push_back(const T &v)
Definition: NoShrinkVector.h:299
MiscLib::NoShrinkVector::end
const T * end() const
Definition: NoShrinkVector.h:400
MiscLib::NoShrinkVector::resize
void resize(size_type s)
Definition: NoShrinkVector.h:274
MiscLib::NoShrinkVector::const_iterator
const typedef T * const_iterator
Definition: NoShrinkVector.h:24
MiscLib::NoShrinkVector::iterator
T * iterator
Definition: NoShrinkVector.h:23
MiscLib::NoShrinkVector::resize
void resize(size_type s, const value_type &v)
Definition: NoShrinkVector.h:228
MiscLib
Definition: AlignedAllocator.h:11
MiscLib::NoShrinkVector::ptrdiff_t
size_t ptrdiff_t
Definition: NoShrinkVector.h:29
MiscLib::NoShrinkVector::operator=
NoShrinkVector< T > & operator=(const NoShrinkVector< T, AllocatorT > &v)
Definition: NoShrinkVector.h:114
MiscLib::NoShrinkVector::insert
void insert(T *where, const T &v)
Definition: NoShrinkVector.h:327
MiscLib::NoShrinkVector::back
const T & back() const
Definition: NoShrinkVector.h:430
MiscLib::NoShrinkVector::const_reverse_iterator
std::reverse_iterator< const T * > const_reverse_iterator
Definition: NoShrinkVector.h:31
MiscLib::NoShrinkVector::ClearTotal
void ClearTotal()
Definition: NoShrinkVector.h:180
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
MiscLib::NoShrinkVector::~NoShrinkVector
~NoShrinkVector()
Definition: NoShrinkVector.h:102
MiscLib::NoShrinkVector::begin
T * begin()
Definition: NoShrinkVector.h:385
MiscLib::NoShrinkVector::clear
void clear()
Definition: NoShrinkVector.h:171
MiscLib::NoShrinkVector::at
const T & at(size_type i) const
Definition: NoShrinkVector.h:294
MiscLib::NoShrinkVector::back
T & back()
Definition: NoShrinkVector.h:425
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector(const NoShrinkVector< T, AllocatorT > &v)
Definition: NoShrinkVector.h:63
MiscLib::NoShrinkVector::size
size_type size() const
Definition: NoShrinkVector.h:218
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
MiscLib::NoShrinkVector::reserve
void reserve(size_type s)
Definition: NoShrinkVector.h:193
MiscLib::NoShrinkVector::reference
T & reference
Definition: NoShrinkVector.h:25
MiscLib::NoShrinkVector::at
T & at(size_type i)
Definition: NoShrinkVector.h:289
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
MiscLib::NoShrinkVector::const_reference
const typedef T & const_reference
Definition: NoShrinkVector.h:26
AlignedAllocator.h