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