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