The Pedigree Project  0.1
Vector.h
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef KERNEL_UTILITIES_VECTOR_H
21 #define KERNEL_UTILITIES_VECTOR_H
22 
23 #include "pedigree/kernel/compiler.h"
24 #include "pedigree/kernel/processor/types.h"
25 #include "pedigree/kernel/utilities/utility.h"
26 
32 template <class T>
34 {
35  public:
37  typedef T *Iterator;
39  typedef T const *ConstIterator;
41  template <class T_>
43  {
44  T_ value;
45 
47  {
48  --value;
49  return *this;
50  }
52  {
53  ++value;
54  return *this;
55  }
56 
58  {
59  T_ origValue = value;
60  --value;
61  return ReverseIteratorContainer<T_>{.value = origValue};
62  }
64  {
65  T_ origValue = value;
66  ++value;
67  return ReverseIteratorContainer<T_>{.value = origValue};
68  }
69 
70  operator T_() const
71  {
72  return value;
73  }
74 
75  typename pedigree_std::remove_pointer<T_>::type operator*() const
76  {
77  return *value;
78  }
79 
80  bool operator==(const ReverseIteratorContainer<T_> &other)
81  {
82  return value == other.value;
83  }
84  };
87 
89  Vector();
92  explicit Vector(size_t size);
95  Vector(const Vector &x);
97  ~Vector();
98 
101  Vector &operator=(const Vector &x);
105  T &operator[](size_t index) const;
106 
109  size_t size() const;
112  size_t count() const;
115  void pushBack(const T &value);
118  T popBack();
121  void pushFront(const T &value);
124  T popFront();
126  void setAt(size_t idx, const T &value);
128  void swap(Iterator a, Iterator b);
131  void insert(size_t index, const T &value);
132 
138  void clear(bool freeMem=false);
140  void erase(size_t index);
142  Iterator erase(Iterator iter);
144  ReverseIterator erase(ReverseIterator iter);
145 
148  Iterator begin()
149  {
150  return m_Data + m_Start;
151  }
154  ConstIterator begin() const
155  {
156  return m_Data + m_Start;
157  }
160  Iterator end()
161  {
162  return m_Data + m_Start + m_Count;
163  }
166  ConstIterator end() const
167  {
168  return m_Data + m_Start + m_Count;
169  }
170 
171  ReverseIterator rbegin()
172  {
173  return ReverseIterator{.value = m_Data + m_Start + m_Count - 1};
174  }
175  ConstReverseIterator rbegin() const
176  {
177  return ConstReverseIterator{.value = m_Data + m_Start + m_Count - 1};
178  }
179  ReverseIterator rend()
180  {
181  return ReverseIterator{.value = m_Data + m_Start - 1};
182  }
183  ConstReverseIterator rend() const
184  {
185  return ConstReverseIterator{.value = m_Data + m_Start - 1};
186  }
189  void assign(const Vector &x);
193  void reserve(size_t size, bool copy);
194 
195  private:
200  void reserve(size_t size, bool copy, bool free);
202  size_t m_Size;
204  size_t m_Count;
209  size_t m_Start;
211  T *m_Data;
213  static const int m_ReserveFactor = 2;
214 };
215 
216 template <class T>
217 Vector<T>::Vector() : m_Size(0), m_Count(0), m_Start(0), m_Data(0)
218 {
219 }
220 
221 template <class T>
223 {
224  reserve(size, false);
225 }
226 
227 template <class T>
229  : m_Size(0), m_Count(0), m_Start(0), m_Data(0)
230 {
231  assign(x);
232 }
233 
234 template <class T>
236 {
237  if (m_Data != 0)
238  delete[] m_Data;
239 }
240 
241 template <class T>
243 {
244  assign(x);
245  return *this;
246 }
247 
248 template <class T>
249 T &Vector<T>::operator[](size_t index) const
250 {
251  static T outofbounds = T();
252  if (index > m_Count)
253  return outofbounds;
254  return m_Data[m_Start + index];
255 }
256 
257 template <class T>
258 size_t Vector<T>::size() const
259 {
260  return m_Size;
261 }
262 
263 template <class T>
264 size_t Vector<T>::count() const
265 {
266  return m_Count;
267 }
268 
269 template <class T>
270 void Vector<T>::pushBack(const T &value)
271 {
272  reserve(m_Count + 1, true);
273 
274  // If we've hit the end of the reserved space we can use, we need to move
275  // the existing entries (rather than this happening in each reserve).
276  if ((m_Start + m_Count + 1) > m_Size)
277  {
278  pedigree_std::copy(m_Data, m_Data + m_Start, m_Count);
279  m_Start = 0;
280  }
281 
282  m_Data[m_Start + m_Count++] = value;
283 }
284 
285 template <class T>
287 {
288  m_Count--;
289  return m_Data[m_Start + m_Count];
290 }
291 
292 template <class T>
293 void Vector<T>::pushFront(const T &value)
294 {
295  const T *oldData = m_Data;
296 
297  reserve(m_Count + 1, true, false);
298 
299  if (m_Start && (m_Data == oldData))
300  {
301  m_Start--;
302  m_Data[m_Start] = value;
303  }
304  else
305  {
306  // We have a bigger buffer, copy items from the old buffer now.
307  pedigree_std::copy(&m_Data[1], oldData, m_Count);
308  m_Data[0] = value;
309  }
310 
311  m_Count++;
312 
313  // All finished with the previous buffer now.
314  if (m_Data != oldData)
315  {
316  delete[] oldData;
317  }
318 }
319 
320 template <class T>
322 {
323  T ret = m_Data[m_Start];
324  m_Count--;
325  m_Start++;
326  return ret;
327 }
328 
329 template <class T>
330 void Vector<T>::setAt(size_t idx, const T &value)
331 {
332  if (idx < m_Count)
333  m_Data[m_Start + idx] = value;
334 }
335 
336 template <class T>
337 void Vector<T>::clear(bool freeMem)
338 {
339  m_Count = 0;
340  m_Start = 0;
341  if (freeMem)
342  {
343  m_Size = 0;
344  delete[] m_Data;
345  m_Data = 0;
346  }
347 }
348 
349 template <class T>
350 void Vector<T>::erase(size_t index)
351 {
352  if (!m_Count)
353  {
354  return;
355  }
356  else if (index >= m_Count)
357  {
358  return;
359  }
360 
361  T *base = m_Data + m_Start;
362  pedigree_std::copy(base + index, base + index + 1, m_Count - index - 1);
363  m_Count--;
364 }
365 
366 template <class T>
368 {
369  erase(static_cast<size_t>(iter - begin()));
370  return iter;
371 }
372 
373 template <class T>
375 {
376  erase(static_cast<size_t>(iter.value - (m_Data + m_Start)));
377  return iter;
378 }
379 
380 template <class T>
381 void Vector<T>::assign(const Vector &x)
382 {
383  reserve(x.size(), false);
384  pedigree_std::copy(m_Data, x.m_Data, x.m_Count);
385  m_Count = x.count();
386  m_Start = x.m_Start;
387 }
388 
389 template <class T>
390 void Vector<T>::reserve(size_t size, bool copy)
391 {
392  reserve(size, copy, true);
393 }
394 
395 template <class T>
396 void Vector<T>::reserve(size_t size, bool copy, bool free)
397 {
398  if (size <= m_Size)
399  {
400  return;
401  }
402  else if (size < (m_Size * m_ReserveFactor))
403  {
404  // Grow exponentially.
405  size = m_Size * m_ReserveFactor;
406  }
407 
408  T *tmp = m_Data;
409  m_Data = new T[size];
410  if (tmp != 0)
411  {
412  if ((copy == true) && m_Size)
413  {
414  pedigree_std::copy(m_Data, tmp + m_Start, m_Size - m_Start);
415  m_Start = 0;
416  }
417  if (free)
418  {
419  delete[] tmp;
420  }
421  }
422  m_Size = size;
423 }
424 
425 template <class T>
427 {
428  if (a == b)
429  return;
430  else if (a < begin() || a >= end())
431  return;
432  else if (b < begin() || b >= end())
433  return;
434 
435  // Perform the swap.
436  T tmp = *a;
437  *a = *b;
438  *b = tmp;
439 }
440 
441 template <class T>
442 void Vector<T>::insert(size_t index, const T &value)
443 {
444  if (index >= m_Count)
445  {
446  pushBack(value);
447  return;
448  }
449  else if (index == 0)
450  {
451  pushFront(value);
452  return;
453  }
454 
455  reserve(m_Count + 1, true);
456 
457  pedigree_std::copy(
458  m_Data + m_Start + index + 1, m_Data + m_Start + index,
459  m_Count - index);
460 
461  m_Data[m_Start + index] = value;
462  ++m_Count;
463 }
464 
465 extern template class Vector<void *>; // IWYU pragma: keep
466 extern template class Vector<uint64_t>; // IWYU pragma: keep
467 extern template class Vector<uint32_t>; // IWYU pragma: keep
468 extern template class Vector<uint16_t>; // IWYU pragma: keep
469 extern template class Vector<uint8_t>; // IWYU pragma: keep
470 extern template class Vector<int64_t>; // IWYU pragma: keep
471 extern template class Vector<int32_t>; // IWYU pragma: keep
472 extern template class Vector<int16_t>; // IWYU pragma: keep
473 extern template class Vector<int8_t>; // IWYU pragma: keep
474 
477 #endif
void pushBack(const T &value)
Definition: Vector.h:270
T popBack()
Definition: Vector.h:286
Iterator begin()
Definition: Vector.h:148
Iterator end()
Definition: Vector.h:160
size_t count() const
Definition: Vector.h:264
A vector / dynamic array.
Vector & operator=(const Vector &x)
Definition: Vector.h:242
void assign(const Vector &x)
Definition: Vector.h:381
T operator++(T &x, int)
Global postincrement operator for types with overloaded preincrement operator.
Definition: template.h:41
void setAt(size_t idx, const T &value)
Definition: Vector.h:330
static const int m_ReserveFactor
Definition: Vector.h:213
void insert(size_t index, const T &value)
Definition: Vector.h:442
size_t m_Size
Definition: Vector.h:202
T * m_Data
Definition: Vector.h:211
size_t m_Count
Definition: Vector.h:204
ConstIterator begin() const
Definition: Vector.h:154
T * Iterator
Definition: Vector.h:37
ConstIterator end() const
Definition: Vector.h:166
T const * ConstIterator
Definition: Vector.h:39
An iterator applicable for many data structures.
Definition: Iterator.h:43
size_t size() const
Definition: Vector.h:258
size_t m_Start
Definition: Vector.h:209
void pushFront(const T &value)
Definition: Vector.h:293
void reserve(size_t size, bool copy)
Definition: Vector.h:390
T operator--(T &x, int)
Global postdecrement operator for types with overloaded predecrement operator.
Definition: template.h:52
Vector()
Definition: Vector.h:217
bool operator==(const Iterator< originalT, Struct, FunctionPrev, FunctionNext, T1 > &x1, const Iterator< originalT, Struct, FunctionPrev, FunctionNext, T2 > &x2)
Definition: Iterator.h:326
T & operator[](size_t index) const
Definition: Vector.h:249
void swap(Iterator a, Iterator b)
Definition: Vector.h:426
void clear(bool freeMem=false)
Definition: Vector.h:337
void erase(size_t index)
Definition: Vector.h:350
T popFront()
Definition: Vector.h:321
~Vector()
Definition: Vector.h:235