WVector.h
Go to the documentation of this file.
1 /* $Id: WVector.h 1156 2011-06-07 04:01:16Z bhagman $
2 ||
3 || @author Hernando Barragan <b@wiring.org.co>
4 || @url http://wiring.org.co/
5 || @contribution Brett Hagman <bhagman@wiring.org.co>
6 || @contribution Alexander Brevig <abrevig@wiring.org.co>
7 ||
8 || @description
9 || | Vector data structure.
10 || |
11 || | Wiring Common API
12 || #
13 ||
14 || @license Please see cores/Common/License.txt.
15 ||
16 */
17 
18 #pragma once
19 
20 #include "Countable.h"
21 #include <cstdlib>
22 #include <cstring>
23 #include <algorithm>
24 #include <iterator>
25 #include "WiringList.h"
26 
31 template <typename Element> class Vector : public Countable<Element>
32 {
33 public:
34  using Comparer = int (*)(const Element& lhs, const Element& rhs);
35 
36  template <bool is_const> class Iterator
37  {
38  public:
39  using iterator_category = std::random_access_iterator_tag;
40  using value_type = Element;
41  using difference_type = std::ptrdiff_t;
42  using pointer = Element*;
43  using reference = Element&;
44 
45  using V = typename std::conditional<is_const, const Vector, Vector>::type;
46  using E = typename std::conditional<is_const, const Element, Element>::type;
47 
48  Iterator(const Iterator&) = default;
49  Iterator(Iterator&&) = default;
50  Iterator& operator=(const Iterator&) = default;
51  Iterator& operator=(Iterator&&) = default;
52 
53  Iterator(V& vector, unsigned index) : vector(vector), index(index)
54  {
55  }
56 
57  ~Iterator() = default;
58 
60  {
61  ++index;
62  return *this;
63  }
64 
66  {
67  Iterator tmp(*this);
68  ++index;
69  return tmp;
70  }
71 
72  Iterator operator+=(size_t distance)
73  {
74  Iterator tmp(*this);
75  index += distance;
76  return tmp;
77  }
78 
79  bool operator==(const Iterator& rhs) const
80  {
81  return &vector == &rhs.vector && index == rhs.index;
82  }
83 
84  bool operator!=(const Iterator& rhs) const
85  {
86  return !operator==(rhs);
87  }
88 
89  template <typename U = Element> typename std::enable_if<!is_const, U&>::type operator*()
90  {
91  return vector[index];
92  }
93 
94  E& operator*() const
95  {
96  return vector[index];
97  }
98 
99  private:
100  V& vector;
101  unsigned index{0};
102  };
103 
104  Vector(unsigned int initialCapacity = 10, unsigned int capacityIncrement = 10) : _increment(capacityIncrement)
105  {
106  _data.allocate(initialCapacity);
107  }
108 
109  Vector(const Vector& rhv)
110  {
111  copyFrom(rhv);
112  }
113 
114  Vector(Vector&&) = delete;
115 
116  ~Vector() = default;
117 
118  // methods
119  unsigned int capacity() const
120  {
121  return _data.size;
122  }
123 
124  template <typename T> bool contains(const T& elem) const
125  {
126  return indexOf(elem) >= 0;
127  }
128 
129  const Element& firstElement() const
130  {
131  if(_size == 0) {
132  abort();
133  }
134 
135  return _data[0];
136  }
137 
138  template <typename T> int indexOf(const T& elem) const;
139 
140  bool isEmpty() const
141  {
142  return _size == 0;
143  }
144 
145  const Element& lastElement() const
146  {
147  if(_size == 0) {
148  abort();
149  }
150 
151  return _data[_size - 1];
152  }
153 
154  template <typename T> int lastIndexOf(const T& elem) const;
155 
156  unsigned int count() const override
157  {
158  return size();
159  }
160 
161  unsigned int size() const
162  {
163  return _size;
164  }
165 
166  void copyInto(Element* array) const;
167 
168  bool add(const Element& obj)
169  {
170  return addElement(obj);
171  }
172 
173  bool addElement(const Element& obj);
174  bool addElement(Element* objp);
175 
176  void clear()
177  {
179  }
180 
181  bool ensureCapacity(size_t minCapacity);
182 
184  {
185  _data.clear();
186  _size = 0;
187  }
188 
189  template <typename T> bool removeElement(const T& elem)
190  {
191  return removeElementAt(indexOf(elem));
192  }
193 
201  bool setSize(unsigned int newSize);
202 
206  void trimToSize()
207  {
208  if(_size < _data.size) {
209  _data.trim(_size, true);
210  }
211  }
212 
213  const Element& elementAt(unsigned int index) const
214  {
215  if(index >= _size) {
216  abort();
217  }
218  return _data[index];
219  }
220 
221  bool insertElementAt(const Element& obj, unsigned int index);
222 
223  bool remove(unsigned int index)
224  {
225  return removeElementAt(index);
226  }
227 
228  bool removeElementAt(unsigned int index);
229  bool setElementAt(const Element& obj, unsigned int index);
230 
231  const Element& get(unsigned int index) const
232  {
233  return elementAt(index);
234  }
235 
236  const Element& operator[](unsigned int index) const override
237  {
238  return elementAt(index);
239  }
240 
241  Element& operator[](unsigned int index) override
242  {
243  if(index >= _size) {
244  abort();
245  }
246  return _data[index];
247  }
248 
250  {
251  if(this != &rhv) {
252  copyFrom(rhv);
253  }
254  return *this;
255  }
256 
257  Vector<Element>& operator=(Vector<Element>&& other) noexcept // move assignment
258  {
259  clear();
260  _increment = 0;
261  std::swap(_data, other._data);
262  std::swap(_size, other._size);
263  std::swap(_increment, other._increment);
264  return *this;
265  }
266 
267  void sort(Comparer compareFunction);
268 
270  {
271  return Iterator<false>(*this, 0);
272  }
273 
275  {
276  return Iterator<false>(*this, count());
277  }
278 
279  const Iterator<true> begin() const
280  {
281  return Iterator<true>(*this, 0);
282  }
283 
284  const Iterator<true> end() const
285  {
286  return Iterator<true>(*this, count());
287  }
288 
289 protected:
290  void copyFrom(const Vector& rhv);
291 
292 protected:
294 
295  unsigned int _size{0};
296  unsigned int _increment{0};
298 };
299 
300 template <class Element> void Vector<Element>::copyFrom(const Vector<Element>& rhv)
301 {
302  _data.clear();
303  if(!_data.allocate(rhv._data.size)) {
304  _size = _increment = 0;
305  return;
306  }
307 
308  _size = rhv._size;
309  _increment = rhv._increment;
310 
311  for(unsigned int i = 0; i < _size; i++) {
312  _data[i] = rhv._data[i];
313  }
314 }
315 
316 template <class Element> void Vector<Element>::copyInto(Element* array) const
317 {
318  if(array == nullptr) {
319  return;
320  }
321 
322  for(unsigned int i = 0; i < _size; i++) {
323  array[i] = _data[i];
324  }
325 }
326 
327 template <class Element> template <typename T> int Vector<Element>::indexOf(const T& elem) const
328 {
329  for(unsigned int i = 0; i < _size; i++) {
330  if(_data[i] == elem) {
331  return int(i);
332  }
333  }
334 
335  return -1;
336 }
337 
338 template <class Element> template <typename T> int Vector<Element>::lastIndexOf(const T& elem) const
339 {
340  // check for empty vector
341  if(_size == 0) {
342  return -1;
343  }
344 
345  unsigned int i = _size;
346 
347  do {
348  i--;
349  if(_data[i] == elem) {
350  return int(i);
351  }
352  } while(i != 0);
353 
354  return -1;
355 }
356 
357 template <class Element> bool Vector<Element>::addElement(const Element& obj)
358 {
359  if(!ensureCapacity(_size + 1)) {
360  return false;
361  }
362  _data[_size++] = obj;
363  return true;
364 }
365 
366 template <class Element> bool Vector<Element>::addElement(Element* objp)
367 {
368  if(!ensureCapacity(_size + 1)) {
369  return false;
370  }
371  _data[_size++] = objp;
372  return true;
373 }
374 
375 template <class Element> bool Vector<Element>::ensureCapacity(size_t minCapacity)
376 {
377  if(_data.size >= minCapacity) {
378  return true;
379  }
380 
381  auto newCapacity = std::max(minCapacity, _data.size + _increment);
382  return _data.allocate(newCapacity);
383 }
384 
385 template <class Element> bool Vector<Element>::insertElementAt(const Element& obj, unsigned int index)
386 {
387  if(index == _size) {
388  return addElement(obj);
389  }
390 
391  if(index > _size) {
392  return false;
393  }
394  if(!ensureCapacity(_size + 1)) {
395  return false;
396  }
397 
398  if(!_data.insert(index, obj)) {
399  return false;
400  }
401 
402  _size++;
403  return true;
404 }
405 
406 template <class Element> bool Vector<Element>::removeElementAt(unsigned int index)
407 {
408  // check for valid index
409  if(index >= _size) {
410  return false;
411  }
412 
413  _data.remove(index);
414  _size--;
415  return true;
416 }
417 
418 template <class Element> bool Vector<Element>::setElementAt(const Element& obj, unsigned int index)
419 {
420  // check for valid index
421  if(index >= _size) {
422  return false;
423  }
424  _data[index] = obj;
425  return true;
426 }
427 
428 template <class Element> bool Vector<Element>::setSize(unsigned int newSize)
429 {
430  if(!ensureCapacity(newSize)) {
431  return false;
432  }
433 
434  _data.trim(newSize, false);
435  _size = std::min(_size, newSize);
436  return true;
437 }
438 
439 template <class Element> void Vector<Element>::sort(Comparer compareFunction)
440 {
441  // Start with 1 (not 0)
442  for(unsigned j = 1; j < _size; j++) {
443  auto key = _data.values[j];
444  Element& keyRef = _data[j];
445  // Smaller values move up
446  int i;
447  for(i = int(j) - 1; (i >= 0) && compareFunction(_data[i], keyRef) > 0; i--) {
448  _data.values[i + 1] = _data.values[i];
449  }
450  // Put key into its proper location
451  _data.values[i + 1] = key;
452  }
453 }
void size_t const void * key
Definition: blake2s.h:33
Definition: Countable.h:20
Definition: WVector.h:37
Iterator(V &vector, unsigned index)
Definition: WVector.h:53
typename std::conditional< is_const, const Element, Element >::type E
Definition: WVector.h:46
Element value_type
Definition: WVector.h:40
Element * pointer
Definition: WVector.h:42
typename std::conditional< is_const, const Vector, Vector >::type V
Definition: WVector.h:45
Iterator operator++(int)
Definition: WVector.h:65
std::random_access_iterator_tag iterator_category
Definition: WVector.h:39
Iterator & operator=(const Iterator &)=default
Iterator & operator=(Iterator &&)=default
Iterator & operator++()
Definition: WVector.h:59
E & operator*() const
Definition: WVector.h:94
bool operator!=(const Iterator &rhs) const
Definition: WVector.h:84
Iterator operator+=(size_t distance)
Definition: WVector.h:72
std::enable_if<!is_const, U & >::type operator*()
Definition: WVector.h:89
std::ptrdiff_t difference_type
Definition: WVector.h:41
Iterator(const Iterator &)=default
Element & reference
Definition: WVector.h:43
~Iterator()=default
bool operator==(const Iterator &rhs) const
Definition: WVector.h:79
Iterator(Iterator &&)=default
Vector class template.
Definition: WVector.h:32
bool ensureCapacity(size_t minCapacity)
Definition: WVector.h:375
bool setElementAt(const Element &obj, unsigned int index)
Definition: WVector.h:418
bool addElement(const Element &obj)
Definition: WVector.h:357
bool setSize(unsigned int newSize)
Reduce or increase number of items.
Definition: WVector.h:428
const Iterator< true > begin() const
Definition: WVector.h:279
bool contains(const T &elem) const
Definition: WVector.h:124
bool removeElementAt(unsigned int index)
Definition: WVector.h:406
Vector(Vector &&)=delete
unsigned int count() const override
Definition: WVector.h:156
bool add(const Element &obj)
Definition: WVector.h:168
Vector< Element > & operator=(Vector< Element > &&other) noexcept
Definition: WVector.h:257
void clear()
Definition: WVector.h:176
Iterator< false > end()
Definition: WVector.h:274
int(*)(const Element &lhs, const Element &rhs) Comparer
Definition: WVector.h:34
void copyFrom(const Vector &rhv)
Definition: WVector.h:300
bool remove(unsigned int index)
Definition: WVector.h:223
unsigned int capacity() const
Definition: WVector.h:119
bool isEmpty() const
Definition: WVector.h:140
void removeAllElements()
Definition: WVector.h:183
const Element & get(unsigned int index) const
Definition: WVector.h:231
Iterator< false > begin()
Definition: WVector.h:269
void trimToSize()
Reduce capacity to match current size.
Definition: WVector.h:206
~Vector()=default
void sort(Comparer compareFunction)
Definition: WVector.h:439
Element & operator[](unsigned int index) override
Definition: WVector.h:241
unsigned int size() const
Definition: WVector.h:161
Vector(const Vector &rhv)
Definition: WVector.h:109
int lastIndexOf(const T &elem) const
Definition: WVector.h:338
ElementList _data
Definition: WVector.h:297
unsigned int _size
Definition: WVector.h:295
Vector< Element > & operator=(const Vector< Element > &rhv)
Definition: WVector.h:249
wiring_private::List< Element > ElementList
Definition: WVector.h:293
bool removeElement(const T &elem)
Definition: WVector.h:189
int indexOf(const T &elem) const
Definition: WVector.h:327
bool insertElementAt(const Element &obj, unsigned int index)
Definition: WVector.h:385
const Element & lastElement() const
Definition: WVector.h:145
const Element & elementAt(unsigned int index) const
Definition: WVector.h:213
const Element & firstElement() const
Definition: WVector.h:129
void copyInto(Element *array) const
Definition: WVector.h:316
const Element & operator[](unsigned int index) const override
Definition: WVector.h:236
Vector(unsigned int initialCapacity=10, unsigned int capacityIncrement=10)
Definition: WVector.h:104
unsigned int _increment
Definition: WVector.h:296
const Iterator< true > end() const
Definition: WVector.h:284
bool addElement(Element *objp)
Definition: WVector.h:366
typename std::conditional< std::is_scalar< T >::value, ScalarList< T >, ObjectList< T > >::type List
Definition: WiringList.h:197