vector.hpp
Go to the documentation of this file.
1 /*
2  * SocialLedge.com - Copyright (C) 2013
3  *
4  * This file is part of free software framework for embedded processors.
5  * You can use it and/or distribute it as long as this copyright header
6  * remains unmodified. The code is free for personal use and requires
7  * permission to use in a commercial product.
8  *
9  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
10  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
12  * I SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
13  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
14  *
15  * You can reach the author of this software at :
16  * p r e e t . w i k i @ g m a i l . c o m
17  */
18 
27 #ifndef _VECTOR_H__
28 #define _VECTOR_H__
29 
30 #include <stdlib.h>
31 
32 
33 
56 template <typename TYPE>
57 class VECTOR
58 {
59 public:
60  VECTOR();
61  VECTOR(int initialCapacity);
62  VECTOR(const VECTOR& copy);
63  VECTOR& operator=(const VECTOR& copy);
64  ~VECTOR();
65 
66  const TYPE& front();
67  const TYPE& back();
68  const TYPE& pop_front();
69  const TYPE& pop_back();
70  void push_back(const TYPE& element);
71  void push_front(const TYPE& element);
72 
73  void reverse();
74  const TYPE& rotateRight();
75  const TYPE& rotateLeft();
76 
77  const TYPE& eraseAt(unsigned int pos);
78  int getFirstIndexOf(const TYPE& find);
79  bool remove(const TYPE& element);
80  int removeAll(const TYPE& element);
81 
82  bool replace(const TYPE& find, const TYPE& replace);
83  int replaceAll(const TYPE& find, const TYPE& replace);
84 
85  void fill(const TYPE& fillElement);
86  void fillUnused(const TYPE& fillElement);
87 
88  unsigned int size() const;
89  unsigned int capacity() const;
90  void reserve(unsigned int size);
91  void setGrowthFactor(int factor);
92  void clear();
93  bool isEmpty();
94 
95  TYPE& at(const unsigned int i);
96  TYPE& operator[](const unsigned int i );
97  const TYPE& operator[](const unsigned int i ) const;
98  void operator+=(const TYPE& item) { push_back(item); }
99 
100 private:
101  void changeCapacity(unsigned int newSize);
102  TYPE* shiftLeftFromPosition(unsigned int pos);
103  TYPE* shiftRightFromPosition(unsigned int pos);
104 
105  unsigned int mGrowthRate;
106  unsigned int mVectorCapacity;
107  unsigned int mVectorSize;
108  TYPE **mpObjPtrs;
109  TYPE mNullItem;
110 
112  void init()
113  {
114  mGrowthRate = 4;
115  mVectorCapacity = 0;
116  mVectorSize = 0;
117  mpObjPtrs = 0;
118  }
119 };
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 template <typename TYPE>
138 {
139  init();
140 }
141 template <typename TYPE>
142 VECTOR<TYPE>::VECTOR(int initialCapacity)
143 {
144  init();
145  changeCapacity(initialCapacity);
146 }
147 
148 template <typename TYPE>
150 {
151  init();
152  *this = copy; // Call = Operator below to copy vector contents
153 }
154 
155 template <typename TYPE>
157 {
158  if(this != &copy)
159  {
160  // Clear this vector and reserve enough for the vector to copy
161  this->clear();
162  this->reserve(copy.capacity());
163 
164  // Now copy other vectors contents into this vector
165  for(unsigned int i = 0; i < copy.size(); i++)
166  {
167  *(this->mpObjPtrs[i]) = copy[i];
168  }
169  }
170  return *this;
171 }
172 
173 template <typename TYPE>
175 {
176  for(unsigned int i=0; i < mVectorCapacity; i++) {
177  delete mpObjPtrs[i];
178  }
179  delete [] mpObjPtrs;
180 }
181 
182 
183 template <typename TYPE>
185 {
186  return (mVectorSize > 0) ? *mpObjPtrs[--mVectorSize] : mNullItem;
187 }
188 
189 
190 template <typename TYPE>
192 {
193  return eraseAt(0);
194 }
195 
196 template <typename TYPE>
197 void VECTOR<TYPE>::push_back(const TYPE& element)
198 {
199  if(mVectorSize >= mVectorCapacity)
200  {
201  changeCapacity( (mVectorCapacity + mGrowthRate) );
202  }
203  *mpObjPtrs[mVectorSize++] = element;
204 }
205 
206 template <typename TYPE>
207 void VECTOR<TYPE>::push_front(const TYPE& element)
208 {
209  if(mVectorSize >= mVectorCapacity)
210  {
211  changeCapacity( (mVectorCapacity + mGrowthRate) );
212  }
213 
214  // Make room to put new item at mpData[0] by moving free right-most pointer back to 0
215  if( mVectorSize++ >= 1)
216  {
217  mpObjPtrs[0] = shiftRightFromPosition(0);
218  }
219 
220  // 1st element was moved to 2nd by shifting right, place new item at 1st location.
221  *mpObjPtrs[0] = element;
222 }
223 
224 template <typename TYPE>
225 const TYPE& VECTOR<TYPE>::front()
226 {
227  return (*this)[0];
228 }
229 
230 template <typename TYPE>
231 const TYPE& VECTOR<TYPE>::back()
232 {
233  return (*this)[mVectorSize-1];
234 }
235 
236 template <typename TYPE>
237 unsigned int VECTOR<TYPE>::size() const
238 {
239  return mVectorSize;
240 }
241 
242 template <typename TYPE>
243 unsigned int VECTOR<TYPE>::capacity() const
244 {
245  return mVectorCapacity;
246 }
247 
248 template <typename TYPE>
249 void VECTOR<TYPE>::reserve(unsigned int theSize)
250 {
251  changeCapacity(theSize);
252 }
253 
254 template <typename TYPE>
256 {
257  if(factor > 1)
258  mGrowthRate = factor;
259 }
260 
261 template <typename TYPE>
262 int VECTOR<TYPE>::getFirstIndexOf(const TYPE& find)
263 {
264  for(unsigned int i = 0; i < mVectorSize; i++) {
265  if(*mpObjPtrs[i] == find) {
266  return i;
267  }
268  }
269  return -1;
270 }
271 
272 template <typename TYPE>
273 const TYPE& VECTOR<TYPE>::eraseAt(unsigned int elementNumber)
274 {
275  TYPE* item = 0;
276  if(elementNumber < mVectorSize && elementNumber >= 0)
277  {
278  // Must save the pointer even though we are erasing
279  item = (mpObjPtrs[mVectorSize-1] = shiftLeftFromPosition(elementNumber));
280  mVectorSize--;
281  }
282  return 0 == item ? mNullItem : *item;
283 }
284 
285 template <typename TYPE>
286 bool VECTOR<TYPE>::remove(const TYPE& element)
287 {
288  const int index = getFirstIndexOf(element);
289  const bool found = (index >= 0);
290  if(found) {
291  eraseAt(index);
292  }
293  return found;
294 }
295 
296 template <typename TYPE>
297 int VECTOR<TYPE>::removeAll(const TYPE& element)
298 {
299  // Optimize vector::removeAll() ???
300  int itemsRemoved = 0;
301  while(remove(element)) { itemsRemoved++; }
302  return itemsRemoved;
303 }
304 
305 template <typename TYPE>
306 bool VECTOR<TYPE>::replace(const TYPE& find, const TYPE& replaceWith)
307 {
308  const int index = getFirstIndexOf(find);
309  const bool found = (index >= 0);
310 
311  if(found) {
312  *mpObjPtrs[index] = replaceWith;
313  }
314 
315  return found;
316 }
317 
318 template <typename TYPE>
319 int VECTOR<TYPE>::replaceAll(const TYPE& find, const TYPE& replaceWith)
320 {
321  int itemsReplaced = 0;
322  for(unsigned int i = 0; i < mVectorSize; i++) {
323  if(*mpObjPtrs[i] == find) {
324  *mpObjPtrs[i] = replaceWith;
325  itemsReplaced++;
326  }
327  }
328  return itemsReplaced;
329 }
330 
331 template <typename TYPE>
332 void VECTOR<TYPE>::fill(const TYPE& fillElement)
333 {
334  for(unsigned int i = 0; i < mVectorCapacity; i++) {
335  *mpObjPtrs[i] = fillElement;
336  }
337  mVectorSize = mVectorCapacity;
338 }
339 
340 template <typename TYPE>
341 void VECTOR<TYPE>::fillUnused(const TYPE& fillElement)
342 {
343  for(unsigned int i = mVectorSize; i < mVectorCapacity; i++) {
344  *mpObjPtrs[i] = fillElement;
345  }
346  mVectorSize = mVectorCapacity;
347 }
348 
349 template <typename TYPE>
351 {
352  mVectorSize = 0;
353 }
354 
355 template <typename TYPE>
357 {
358  return (0 == mVectorSize);
359 }
360 
361 template <typename TYPE>
363 {
364  for(unsigned int i = 0; i < (mVectorSize/2); i++)
365  {
366  TYPE* temp = mpObjPtrs[i];
367  mpObjPtrs[i] = mpObjPtrs[ (mVectorSize-1-i) ];
368  mpObjPtrs[ (mVectorSize-1-i) ] = temp;
369  }
370 }
371 
372 template <typename TYPE>
374 {
375  if(mVectorSize >= 2)
376  {
377  // Shift right and set shifted element to index 0
378  mpObjPtrs[0] = shiftRightFromPosition(0);
379  }
380  return (*this)[0];
381 }
382 
383 template <typename TYPE>
385 {
386  if(mVectorSize >= 2)
387  {
388  // Shift left, and set the last element to shifted element.
389  mpObjPtrs[ (mVectorSize-1) ] = shiftLeftFromPosition(0);
390  }
391  return (*this)[0];
392 }
393 
394 template <typename TYPE>
395 TYPE& VECTOR<TYPE>::at(const unsigned int i )
396 {
397  return (*this)[i];
398 }
399 
400 template <typename TYPE>
401 TYPE& VECTOR<TYPE>::operator[](const unsigned int i )
402 {
403  return ( i >= 0 && i < mVectorSize) ? *mpObjPtrs[i] : mNullItem;
404 }
405 
406 template <typename TYPE>
407 const TYPE& VECTOR<TYPE>::operator[](const unsigned int i ) const
408 {
409  return ( i >= 0 && i < mVectorSize) ? *mpObjPtrs[i] : mNullItem;
410 }
411 
412 
413 
414 // ******* PRIVATE FUNCTIONS:
415 template <typename TYPE>
416 void VECTOR<TYPE>::changeCapacity(unsigned int newSize)
417 {
418  if(newSize < mVectorCapacity)
419  return;
420 
421  // This is slow code so it is #ifdef'd out
422 #if 0
423  // Allocate new memory and call TYPE's default constructor
424  TYPE **newData = new TYPE*[ (newSize) ];
425  for(unsigned int i = 0; i < newSize; i++) {
426  newData[i] = new TYPE();
427  }
428 
429  // Copy old memory to new one & delete old memory
430  if(mpObjPtrs)
431  {
432  for(unsigned int i = 0; i < mVectorSize; i++)
433  {
434  newData[i] = mpObjPtrs[i];
435  }
436  delete [] mpObjPtrs;
437  }
438 
439  // Point data to new memory
440  mpObjPtrs = newData;
441 #else
442  // Allocate pointers of the datatype
443  mpObjPtrs = (TYPE**)realloc(mpObjPtrs, sizeof(TYPE*)*newSize);
444 
445  // Allocate new objects ONLY at each of the new pointers
446  for(unsigned int i = mVectorSize; i < newSize; i++) {
447  mpObjPtrs[i] = new TYPE();
448  }
449 #endif
450 
451  mVectorCapacity = newSize;
452 }
453 
454 template <typename TYPE>
455 TYPE* VECTOR<TYPE>::shiftLeftFromPosition(unsigned int pos)
456 {
457  TYPE* leftMostItem = mpObjPtrs[pos];
458  if(mVectorSize > 1 && (mVectorSize-pos) > 1)
459  {
460  // Shift elements left by one.
461  for( unsigned int i = pos; i < (mVectorSize-1); i++)
462  {
463  mpObjPtrs[i] = mpObjPtrs[i+1];
464  }
465  }
466  return leftMostItem;
467 }
468 
469 template <typename TYPE>
470 TYPE* VECTOR<TYPE>::shiftRightFromPosition(unsigned int pos)
471 {
472  // Vector size must be at least 1 before calling this function
473  TYPE* rightMostItem = mpObjPtrs[mVectorSize-1];
474 
475  // Shift elements right by one.
476  for( unsigned int i = mVectorSize-1; i > pos; i--)
477  {
478  mpObjPtrs[i] = mpObjPtrs[i-1];
479  }
480  return rightMostItem;
481 }
482 
483 #endif /* #ifndef _VECTOR_H__ */
void setGrowthFactor(int factor)
Changes the size the vector grows by.
Definition: vector.hpp:255
void fillUnused(const TYPE &fillElement)
Fills the unused capacity of the vector with the given fillElement.
Definition: vector.hpp:341
Definition: vector.hpp:57
int getFirstIndexOf(const TYPE &find)
Definition: vector.hpp:262
void reserve(unsigned int size)
Reserves the memory for the vector up front.
Definition: vector.hpp:249
VECTOR()
Default Constructor.
Definition: vector.hpp:137
const TYPE & rotateLeft()
Rotates the vector left by 1 and.
Definition: vector.hpp:373
bool remove(const TYPE &element)
Removes the first Vector Element match from this vector,.
Definition: vector.hpp:286
void operator+=(const TYPE &item)
+= Operator which is same as push_back() of an item
Definition: vector.hpp:98
const TYPE & rotateRight()
Rotates the vector right by 1 and.
Definition: vector.hpp:384
const TYPE & pop_back()
Pops & returns the last element from the vector. (FAST)
Definition: vector.hpp:184
bool isEmpty()
Definition: vector.hpp:356
int replaceAll(const TYPE &find, const TYPE &replace)
Replaces all instances of "find" and replaces it with "replace".
Definition: vector.hpp:319
const TYPE & eraseAt(unsigned int pos)
Erases the element at pos and returns it. All elements are shifted left from this pos...
Definition: vector.hpp:273
VECTOR & operator=(const VECTOR &copy)
=Operator to copy the vector.
Definition: vector.hpp:156
TYPE & operator[](const unsigned int i)
[] Operator for Left-hand-side.
Definition: vector.hpp:401
const TYPE & back()
Definition: vector.hpp:231
const TYPE & pop_front()
Pops & returns the first(oldest) element of the vector (index 0). (SLOW)
Definition: vector.hpp:191
bool replace(const TYPE &find, const TYPE &replace)
Replaces the first element "find" and replaces it with "replace".
Definition: vector.hpp:306
int removeAll(const TYPE &element)
Removes all Vector Elements that match the given element,.
Definition: vector.hpp:297
TYPE & at(const unsigned int i)
Access element at given index.
Definition: vector.hpp:395
const TYPE & front()
Definition: vector.hpp:225
unsigned int capacity() const
Definition: vector.hpp:243
void clear()
Clears the entire vector.
Definition: vector.hpp:350
void fill(const TYPE &fillElement)
Fills the entire vector capacity with the given fillElement.
Definition: vector.hpp:332
~VECTOR()
Destructor of the vector.
Definition: vector.hpp:174
void reverse()
Reverses the order of the vector contents.
Definition: vector.hpp:362
void push_front(const TYPE &element)
Pushes the element at the 1st location (index 0). (SLOW)
Definition: vector.hpp:207
void push_back(const TYPE &element)
Pushes the element to the end of the vector. (FAST)
Definition: vector.hpp:197
unsigned int size() const
Definition: vector.hpp:237