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>>
17  class NoShrinkVector : protected AllocatorT
18  {
19  public:
20  typedef size_t size_type;
21  typedef T value_type;
22  typedef T* iterator;
23  typedef const T* const_iterator;
24  typedef T& reference;
25  typedef const T& const_reference;
26  typedef T* pointer;
27  typedef const T* const_pointer;
28  typedef size_t ptrdiff_t;
29  typedef std::reverse_iterator<T*> reverse_iterator;
30  typedef std::reverse_iterator<const T*> const_reverse_iterator;
31 
33  {
34  m_begin = NULL;
35  m_end = NULL;
36  m_capacity = NULL;
37  }
38 
40  {
41  m_begin = AllocatorT::allocate(s);
42  m_end = m_begin + s;
43  m_capacity = m_end;
44  value_type v;
45  for (size_type i = 0; i < s; ++i)
46  {
47  AllocatorT::construct(m_begin + i, v);
48  }
49  }
50 
52  {
53  m_begin = AllocatorT::allocate(s);
54  m_end = m_begin + s;
55  m_capacity = m_end;
56  for (size_type i = 0; i < s; ++i)
57  {
58  AllocatorT::construct(m_begin + i, v);
59  }
60  }
61 
63  {
64  size_type s = v.size();
65  if (!s)
66  {
67  m_begin = NULL;
68  m_end = NULL;
69  m_capacity = NULL;
70  return;
71  }
72  m_begin = AllocatorT::allocate(s);
73  m_end = m_begin + s;
74  m_capacity = m_end;
75  for (size_type i = 0; i < s; ++i)
76  {
77  AllocatorT::construct(m_begin + i, v.m_begin[i]);
78  }
79  }
80 
81  template <class OtherAllocatorT>
83  {
84  size_type s = v.size();
85  if (!s)
86  {
87  m_begin = NULL;
88  m_end = NULL;
89  m_capacity = NULL;
90  return;
91  }
92  m_begin = AllocatorT::allocate(s);
93  m_end = m_begin + s;
94  m_capacity = m_end;
95  for (size_type i = 0; i < s; ++i)
96  {
97  AllocatorT::construct(m_begin + i, v.m_begin[i]);
98  }
99  }
100 
102  {
103  if (m_begin)
104  {
105  for (size_type i = 0; i < size(); ++i)
106  {
107  AllocatorT::destroy(m_begin + i);
108  }
109  AllocatorT::deallocate(m_begin, capacity());
110  }
111  }
112 
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>
147  {
148  size_type s = v.size();
149  if (!s)
150  {
151  clear();
152  return *this;
153  }
154  if (m_begin)
155  {
156  for (size_type i = 0; i < size(); ++i)
157  {
158  AllocatorT::destroy(m_begin + i);
159  }
160  AllocatorT::deallocate(m_begin, capacity());
161  }
162  m_begin = AllocatorT::allocate(s);
163  m_end = m_begin + s;
164  m_capacity = m_end;
165  for (size_type i = 0; i < s; ++i)
166  {
167  AllocatorT::construct(m_begin + i, v.m_begin[i]);
168  }
169  return *this;
170  }
171 
172  void
174  {
175  for (size_type i = 0; i < size(); ++i)
176  {
177  AllocatorT::destroy(m_begin + i);
178  }
179  m_end = m_begin;
180  }
181 
182  void
184  {
185  if (m_begin)
186  {
187  for (size_type i = 0; i < size(); ++i)
188  {
189  AllocatorT::destroy(m_begin + i);
190  }
191  AllocatorT::deallocate(m_begin, capacity());
192  }
193  m_end = m_begin = m_capacity = NULL;
194  }
195 
196  void
198  {
199  if (!s)
200  {
201  return;
202  }
203  if (capacity() < s)
204  {
205  size_type olds = size();
206  T* newBegin = AllocatorT::allocate(s);
207  if (m_begin)
208  {
209  for (size_type i = 0; i < olds; ++i)
210  {
211  AllocatorT::construct(newBegin + i, m_begin[i]);
212  AllocatorT::destroy(m_begin + i);
213  }
214  AllocatorT::deallocate(m_begin, capacity());
215  }
216  m_end = newBegin + olds;
217  m_begin = newBegin;
218  m_capacity = m_begin + s;
219  }
220  }
221 
222  size_type
223  size() const
224  {
225  return m_end - m_begin;
226  }
227 
228  size_type
229  capacity() const
230  {
231  return m_capacity - m_begin;
232  }
233 
234  void
236  {
237  if (!s)
238  {
239  clear();
240  return;
241  }
242  if (capacity() >= s)
243  {
244  for (size_type i = s; i < size(); ++i)
245  {
246  AllocatorT::destroy(m_begin + i);
247  }
248  for (size_type i = size(); i < s; ++i)
249  {
250  AllocatorT::construct(m_begin + i, v);
251  }
252  m_end = m_begin + s;
253  return;
254  }
255  T* newBegin = AllocatorT::allocate(2 * s);
256  if (m_begin)
257  {
258  for (size_type i = 0; i < size(); ++i)
259  {
260  AllocatorT::construct(newBegin + i, m_begin[i]);
261  AllocatorT::destroy(m_begin + i);
262  }
263  AllocatorT::deallocate(m_begin, capacity());
264  for (size_type i = size(); i < s; ++i)
265  {
266  AllocatorT::construct(newBegin + i, v);
267  }
268  }
269  else
270  {
271  for (size_type i = 0; i < s; ++i)
272  {
273  AllocatorT::construct(newBegin + i, v);
274  }
275  }
276  m_end = newBegin + s;
277  m_begin = newBegin;
278  m_capacity = m_begin + 2 * s;
279  }
280 
281  void
283  {
284  resize(s, value_type());
285  }
286 
287  operator T*()
288  {
289  return m_begin;
290  }
291 
292  operator const T*() const
293  {
294  return m_begin;
295  }
296 
297  T&
299  {
300  return m_begin[i];
301  }
302 
303  const T&
304  at(size_type i) const
305  {
306  return m_begin[i];
307  }
308 
309  void
310  push_back(const T& v)
311  {
312  if (m_end >= m_capacity)
313  {
314  size_type olds = size();
315  size_type s = olds * 2;
316  if (!s)
317  {
318  s = 1;
319  }
320  T* newBegin = AllocatorT::allocate(s);
321  if (m_begin)
322  {
323  for (size_type i = 0; i < olds; ++i)
324  {
325  AllocatorT::construct(newBegin + i, m_begin[i]);
326  AllocatorT::destroy(m_begin + i);
327  }
328  AllocatorT::deallocate(m_begin, capacity());
329  }
330  m_end = newBegin + olds;
331  m_begin = newBegin;
332  m_capacity = m_begin + s;
333  }
334  AllocatorT::construct(m_end, v);
335  ++m_end;
336  }
337 
338  void
339  insert(T* where, const T& v)
340  {
341  size_type whereIdx = where - m_begin;
342  if (m_end >= m_capacity)
343  {
344  size_type olds = size();
345  size_type s = olds * 2;
346  if (!s)
347  {
348  s = 1;
349  }
350  T* newBegin = AllocatorT::allocate(s);
351  if (m_begin)
352  {
353  for (size_type i = 0; i < olds; ++i)
354  {
355  AllocatorT::construct(newBegin + i, m_begin[i]);
356  AllocatorT::destroy(m_begin + i);
357  }
358  AllocatorT::deallocate(m_begin, capacity());
359  }
360  m_end = newBegin + olds;
361  m_begin = newBegin;
362  m_capacity = m_begin + s;
363  where = m_begin + whereIdx;
364  }
365  if (size() > whereIdx)
366  {
367  AllocatorT::construct(m_end, m_begin[size() - 1]);
368  for (size_type i = size() - 1; i > whereIdx; --i)
369  {
370  m_begin[i] = m_begin[i - 1];
371  }
372  *where = v;
373  }
374  else
375  {
376  AllocatorT::construct(where, v);
377  }
378  ++m_end;
379  }
380 
381  void
382  erase(T* where)
383  {
384  for (size_type i = where - m_begin; i < size() - 1; ++i)
385  {
386  m_begin[i] = m_begin[i + 1];
387  }
388  --m_end;
389  AllocatorT::destroy(m_end);
390  }
391 
392  void
394  {
395  --m_end;
396  AllocatorT::destroy(m_end);
397  }
398 
399  T*
401  {
402  return m_begin;
403  }
404 
405  const T*
406  begin() const
407  {
408  return m_begin;
409  }
410 
411  T*
412  end()
413  {
414  return m_end;
415  }
416 
417  const T*
418  end() const
419  {
420  return m_end;
421  }
422 
425  {
426  return std::reverse_iterator<T*>(m_end);
427  }
428 
430  rbegin() const
431  {
432  return std::reverse_iterator<const T*>(m_end);
433  }
434 
437  {
438  return std::reverse_iterator<T*>(m_begin);
439  }
440 
442  rend() const
443  {
444  return std::reverse_iterator<const T*>(m_begin);
445  }
446 
447  T&
449  {
450  return *(m_end - 1);
451  }
452 
453  const T&
454  back() const
455  {
456  return *(m_end - 1);
457  }
458 
459  T&
461  {
462  return *m_begin;
463  }
464 
465  const T&
466  front() const
467  {
468  return *m_begin;
469  }
470 
471  private:
472  T* m_begin;
473  T* m_end;
474  T* m_capacity;
475  };
476 }; // namespace MiscLib
477 
478 #endif
MiscLib::NoShrinkVector::rend
const_reverse_iterator rend() const
Definition: NoShrinkVector.h:442
MiscLib::NoShrinkVector::operator=
NoShrinkVector< T > & operator=(const NoShrinkVector< T, AllocatorT > &v)
Definition: NoShrinkVector.h:114
MiscLib::NoShrinkVector::const_pointer
const typedef T * const_pointer
Definition: NoShrinkVector.h:27
MiscLib::NoShrinkVector::capacity
size_type capacity() const
Definition: NoShrinkVector.h:229
MiscLib::NoShrinkVector::pop_back
void pop_back()
Definition: NoShrinkVector.h:393
MiscLib::NoShrinkVector::erase
void erase(T *where)
Definition: NoShrinkVector.h:382
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector(size_type s)
Definition: NoShrinkVector.h:39
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector(const NoShrinkVector< T, OtherAllocatorT > &v)
Definition: NoShrinkVector.h:82
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector(size_type s, const T &v)
Definition: NoShrinkVector.h:51
MiscLib::NoShrinkVector::value_type
T value_type
Definition: NoShrinkVector.h:21
MiscLib::NoShrinkVector::begin
const T * begin() const
Definition: NoShrinkVector.h:406
MiscLib::NoShrinkVector::pointer
T * pointer
Definition: NoShrinkVector.h:26
MiscLib::NoShrinkVector::size_type
size_t size_type
Definition: NoShrinkVector.h:20
MiscLib::NoShrinkVector::end
T * end()
Definition: NoShrinkVector.h:412
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector()
Definition: NoShrinkVector.h:32
MiscLib::NoShrinkVector::rbegin
reverse_iterator rbegin()
Definition: NoShrinkVector.h:424
MiscLib::NoShrinkVector::rbegin
const_reverse_iterator rbegin() const
Definition: NoShrinkVector.h:430
MiscLib::NoShrinkVector::rend
reverse_iterator rend()
Definition: NoShrinkVector.h:436
MiscLib::NoShrinkVector::front
const T & front() const
Definition: NoShrinkVector.h:466
MiscLib::NoShrinkVector::front
T & front()
Definition: NoShrinkVector.h:460
MiscLib::NoShrinkVector
Definition: NoShrinkVector.h:17
MiscLib::NoShrinkVector::reverse_iterator
std::reverse_iterator< T * > reverse_iterator
Definition: NoShrinkVector.h:29
MiscLib::NoShrinkVector::push_back
void push_back(const T &v)
Definition: NoShrinkVector.h:310
MiscLib::NoShrinkVector::end
const T * end() const
Definition: NoShrinkVector.h:418
MiscLib::NoShrinkVector::resize
void resize(size_type s)
Definition: NoShrinkVector.h:282
MiscLib::NoShrinkVector::const_iterator
const typedef T * const_iterator
Definition: NoShrinkVector.h:23
MiscLib::NoShrinkVector::iterator
T * iterator
Definition: NoShrinkVector.h:22
MiscLib::NoShrinkVector::resize
void resize(size_type s, const value_type &v)
Definition: NoShrinkVector.h:235
MiscLib
Definition: AlignedAllocator.h:12
MiscLib::NoShrinkVector::ptrdiff_t
size_t ptrdiff_t
Definition: NoShrinkVector.h:28
MiscLib::NoShrinkVector::insert
void insert(T *where, const T &v)
Definition: NoShrinkVector.h:339
MiscLib::NoShrinkVector::back
const T & back() const
Definition: NoShrinkVector.h:454
MiscLib::NoShrinkVector::ClearTotal
void ClearTotal()
Definition: NoShrinkVector.h:183
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
MiscLib::NoShrinkVector::operator=
NoShrinkVector< T > & operator=(const NoShrinkVector< T, OtherAllocatorT > &v)
Definition: NoShrinkVector.h:146
MiscLib::NoShrinkVector::~NoShrinkVector
~NoShrinkVector()
Definition: NoShrinkVector.h:101
MiscLib::NoShrinkVector::begin
T * begin()
Definition: NoShrinkVector.h:400
MiscLib::NoShrinkVector::clear
void clear()
Definition: NoShrinkVector.h:173
MiscLib::NoShrinkVector::at
const T & at(size_type i) const
Definition: NoShrinkVector.h:304
MiscLib::NoShrinkVector::back
T & back()
Definition: NoShrinkVector.h:448
MiscLib::NoShrinkVector::NoShrinkVector
NoShrinkVector(const NoShrinkVector< T, AllocatorT > &v)
Definition: NoShrinkVector.h:62
MiscLib::NoShrinkVector::size
size_type size() const
Definition: NoShrinkVector.h:223
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38
MiscLib::NoShrinkVector::const_reverse_iterator
std::reverse_iterator< const T * > const_reverse_iterator
Definition: NoShrinkVector.h:30
MiscLib::NoShrinkVector::reserve
void reserve(size_type s)
Definition: NoShrinkVector.h:197
MiscLib::NoShrinkVector::reference
T & reference
Definition: NoShrinkVector.h:24
MiscLib::NoShrinkVector::at
T & at(size_type i)
Definition: NoShrinkVector.h:298
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:25
AlignedAllocator.h