DataDirector API
dynamic_array.h
Go to the documentation of this file.
1 #ifndef _DYNAMIC_ARRAY_H
2 #define _DYNAMIC_ARRAY_H
3 
4 /*! \file dynamic_array.h
5  \brief The disti::DynamicArray class. A templated array of objects capable of dynamically growing.
6 
7  \par Copyright Information
8 
9  Copyright (c) 2012 The DiSTI Corporation.<br>
10  11301 Corporate Blvd; Suite 100<br>
11  Orlando, Florida 32817<br>
12  USA<br>
13  <br>
14  All rights reserved.<br>
15 
16  This Software contains proprietary trade secrets of DiSTI and may not be
17 reproduced, in whole or part, in any form, or by any means of electronic,
18 mechanical, or otherwise, without the written permission of DiSTI. Said
19 permission may be derived through the purchase of applicable DiSTI product
20 licenses which detail the distribution rights of this content and any
21 Derivative Works based on this or other copyrighted DiSTI Software.
22 
23  NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
24 AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
25 PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
26 AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
27 IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
28 PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
29 
30  LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
31 IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
32 INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
33 DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
34 INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
35 INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBLITY
36 OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
37 EXCEED FIVE DOLLARS (US$5.00).
38 
39  The aforementioned terms and restrictions are governed by the laws of the
40 State of Florida and the United States of America.
41 
42 */
43 
44 #include "string.h"
45 #include "assert.h"
46 
47 namespace disti
48 {
49 
50 #if defined (_MSC_VER)
51 #pragma warning( push, 3 )
52 #endif
53 
54 /** \brief A templated array of objects. The array dynamically resizes as needed.
55  \param TypeIsSimple set to true for types which can be initialized to
56  all zero using memset.
57  If T is a class with a default constructor, a working '=' operator,
58  set TypeIsSimple to false.
59 */
60 template <class T,bool TypeIsSimple = true>
62 {
63  protected:
64 
65  unsigned int _size; /** Number of elements in the array */
66  unsigned int _count; /** Number of elements used */
67  T *_objects; /** Dynamic array is an array of objects */
68 
69 
70  /** Grow the array. If nothing has been allocated yet, set the size to 2 elements. Otherwise double the array size. */
71  void GrowArray(void)
72  {
73  if (!_objects || _size == 0)
74  Size(2);
75  else
76  Size(_size * 2);
77  }
78 
79  public:
80 
81  typedef T ElementType;
82 
83  /** DynamicArray constructor
84  * \param The initial number of elements to be allocated for the array
85  */
86  DynamicArray(int initialSize=0)
87  {
88  _size = initialSize;
89  _count = 0;
90  _objects = NULL;
91 
92  if (initialSize)
93  Size(initialSize);
94  }
95 
96  DynamicArray(const DynamicArray& other)
97  {
98  _size = 0;
99  _count = 0;
100  _objects = NULL;
101 
102  *this = other;
103  }
104 
105  /** DynamicArray destructor. Clears the array but does not delete the objects being pointed to by the array
106  */
108  {
109  if (_objects)
110  {
111  delete []_objects;
112  }
113  };
114 
115 
116  /** Set the "Count" value for this array
117  */
118  void Count(const unsigned int count)
119  {
120  _count = count;
121 
122  if(_count > _size)
123  {
124  Size(_count);
125  }
126  }
127 
128  /** Returns the number of elements used of this dynamic array
129  * \return The number of elements used of the array (number of elements)
130  */
131  inline unsigned int Count() const { return _count; }
132 
133  /** Returns the current size of this dynamic array
134  * \return The current size of the array (number of elements)
135  */
136  inline unsigned int Size() const { return _size; }
137 
138  /** Sets the array size to the new size given. Reallocates the array as needed
139  * \param newSize The new number of elements in the array
140  */
141  void Size(unsigned int newSize)
142  {
143  T *newobjs;
144 
145  if (newSize > 0)
146  {
147  // Test for case when array has not yet been allocated
148  if (!_objects)
149  {
150  _objects = new T[newSize];
151  assert(_objects);
152 
153  if (TypeIsSimple)
154  memset(_objects,0,newSize*sizeof(T));
155 
156  _size = newSize;
157  }
158 
159  // Don't reallocate if the size doesn't change
160  if (newSize == _size)
161  return;
162 
163  newobjs = new T[newSize];
164  assert(newobjs);
165 
166  if (newSize > _size)
167  {
168  if (TypeIsSimple)
169  {
170  // Because it is just a pointer or other simple type,
171  // we can just memcpy the data
172  memcpy(newobjs,_objects,_size*sizeof(T));
173  }
174  else
175  {
176  for(unsigned int i=0; i < _size; i++)
177  {
178  newobjs[i] = _objects[i];
179  }
180  }
181 
182  if (TypeIsSimple)
183  memset(newobjs+_size,0,(newSize-_size)*sizeof(T));
184  }
185  else
186  {
187 
188  if (TypeIsSimple)
189  {
190  // Because it is just a pointer or other simple type,
191  // we can just memcpy the data
192  memcpy(newobjs,_objects,newSize*sizeof(T));
193  }
194  else
195  {
196  for(unsigned int i=0; i < newSize; i++)
197  {
198  newobjs[i] = _objects[i];
199  }
200  }
201  }
202 
203  if (_objects)
204  delete [] _objects;
205 
206  _objects = newobjs;
207  }
208  else // newSize is zero
209  {
210  if (_objects)
211  delete [] _objects;
212 
213  _objects = NULL;
214  }
215 
216  _size = newSize;
217 
218  // Just in case the user shrank the array, reduce count to match size if needed
219  if (_count > _size)
220  _count = _size;
221  }
222 
223  /** Attempts to insert the object into the list at the specified location. If the
224  * specified location is beyond the array bounds, the object is inserted at the next
225  * position in the array.
226  * \param obj The object to insert
227  * \param loc The index location to insert into
228  */
229  void InsertObject(const T& obj,unsigned int loc)
230  {
231  _count++; // we are adding an object, increase the count
232 
233  // Check to see if the count exceeds the size, if so Grow
234  if (_count > _size)
235  {
236  GrowArray();
237  }
238 
239  // If the Location Index exceeds the array bounds,
240  // put the new object at the end of the array
241  if (loc >= _count)
242  {
243  loc = _count-1;
244  }
245 
246  // Move the array elements up to make room to insert the new element
247  for (unsigned int i=_count-1; i > loc; i--)
248  {
249  _objects[i] = _objects[i-1];
250  }
251 
252  _objects[loc] = obj; // Insert the new object.
253  }
254 
255  /** Adds the specified object into the list, at the end of the list
256  * \param A pointer to the object to add
257  * \return Where the object was inserted
258  */
259  unsigned int InsertObject(const T& obj)
260  {
261  unsigned int rval;
262 
263  rval = _count;
264 
265  InsertObject(obj,_count);
266 
267  return rval;
268  }
269 
270  /** Adds the specified object into the list, at the head of the list
271  * Treats the list like a stack, hence the name Push
272  * \param A pointer to the object to add
273  */
274  void PushObject(const T& obj)
275  {
276  InsertObject(obj,0);
277  }
278 
279  /** Insert the object into the list at the specified location
280  * \param obj The object to insert
281  * \param loc The index location to insert into
282  */
283  void InsertObjectAfter(const T& obj,unsigned int loc)
284  {
285  InsertObject(obj,loc+1);
286  }
287 
288  /** Deletes the specified object from the list. Does not free it
289  * \param A pointer to the object to delete
290  * \return true if object was found and deleted else false
291  */
292  bool DeleteObject(const T& obj)
293  {
294  int loc = Position(obj);
295 
296  if (loc >= 0)
297  return DeleteObjectAtIndex(loc);
298 
299  return false;
300  }
301 
302  /** Deletes the object at the specified index. Does not free it
303  * \param Index of the object to delete
304  * \return true if object was found and deleted else false
305  */
306  bool DeleteObjectAtIndex(unsigned int index)
307  {
308  if (index >= _count)
309  {
310  return false;
311  }
312  else
313  {
314  for (unsigned int j=index; j < (_count - 1u); j++)
315  {
316  _objects[j] = _objects[j+1u];
317  }
318 
319  _count--;
320  }
321  return true;
322  }
323 
324  /** Get the index position of the specified object in the list
325  * \param obj The object to find
326  * \return The index of the object in the list, -1 if it isn't in the list
327  */
328  int Position(const T& obj)
329  {
330  for (unsigned int i=0;i < _count; i++)
331  if (obj==_objects[i])
332  return i;
333  return -1;
334  }
335 
336  /** Empties the list, calling delete on all of its elements
337  * This method is intended for pointer data types only.
338  */
339  void EmptyList(void)
340  {
341  for (unsigned int i=0; i < Count(); i++)
342  delete _objects[i];
343 
344  ClearList();
345  }
346 
347  /** Clears the list so Count() is zero. Does not attempt to delete the objects data */
348  void ClearList(void)
349  {
350  // Clear object array
351  if (_objects)
352  {
353  if(TypeIsSimple)
354  {
355  memset(_objects,0,sizeof(T) * _size);
356  }
357  else
358  {
359  // For non simple objects, just delete them all, and
360  // as they are accessed, new ones will be created.
361  delete [] _objects;
362  _objects = NULL;
363  _size = 0;
364  }
365  }
366 
367  _count = 0;
368  }
369 
370  /** Overload of array operator to get element at desired index */
371  T &operator[] (unsigned int index)
372  {
373  assert(int(index) >= 0); //test for passing in -1, which would resize the array to size 0
374 
375  // This gets an element, resizing the array if needed
376 
377  if (index >= _size)
378  {
379  Size(index+1);
380  _count = index+1;
381  }
382  else if (index >= _count)
383  {
384  _count = index+1;
385  }
386 
387  return _objects[index];
388  }
389 
390  /** Overload of array operator to get element at desired index - const safe version */
391  const T &operator[] (unsigned int index) const
392  {
393  assert(int(index) >= 0); //test for passing in -1, which would resize the array to size 0
394 
395  // This gets an element, resizing the array if needed
396 
397  if (index >= _size)
398  {
399  Size(index+1);
400  _count = index+1;
401  }
402  else if (index >= _count)
403  {
404  _count = index+1;
405  }
406 
407  return _objects[index];
408  }
409 
410 
411  /** Return the internal array pointer
412  * If you call any other methods on this object it invalidates the pointer.*/
413  inline T* InternalArray(void)
414  {
415  return _objects;
416  }
417 
418  /** Overload the assignment operator to create a duplicate of the righthand operand */
420  {
421  Size(right.Size());
422  for(unsigned int i = 0; i <Size(); i++)
423  {
424  _objects[i] = right._objects[i];
425  }
426  _count = right.Count();
427  return *this;
428  }
429 
430  /** \return true if the list is empty */
431  bool IsEmpty(void) const
432  {
433  return (_count==0);
434  }
435 };
436 
437 #if defined (_MSC_VER)
438 #pragma warning( pop )
439 #endif
440 
441 } // namespace disti
442 
443 #endif
444 
void ClearList(void)
Definition: dynamic_array.h:348
unsigned int Count() const
Definition: dynamic_array.h:131
A templated array of objects. The array dynamically resizes as needed.
Definition: dynamic_array.h:61
T & operator[](unsigned int index)
Definition: dynamic_array.h:371
int Position(const T &obj)
Definition: dynamic_array.h:328
void EmptyList(void)
Definition: dynamic_array.h:339
void InsertObjectAfter(const T &obj, unsigned int loc)
Definition: dynamic_array.h:283
unsigned int InsertObject(const T &obj)
Definition: dynamic_array.h:259
bool IsEmpty(void) const
Definition: dynamic_array.h:431
bool DeleteObjectAtIndex(unsigned int index)
Definition: dynamic_array.h:306
void InsertObject(const T &obj, unsigned int loc)
Definition: dynamic_array.h:229
void GrowArray(void)
Definition: dynamic_array.h:71
bool DeleteObject(const T &obj)
Definition: dynamic_array.h:292
void Count(const unsigned int count)
Definition: dynamic_array.h:118
~DynamicArray(void)
Definition: dynamic_array.h:107
unsigned int _count
Definition: dynamic_array.h:66
T * InternalArray(void)
Definition: dynamic_array.h:413
void PushObject(const T &obj)
Definition: dynamic_array.h:274
DynamicArray(int initialSize=0)
Definition: dynamic_array.h:86
void Size(unsigned int newSize)
Definition: dynamic_array.h:141
DynamicArray< T, TypeIsSimple > & operator=(const DynamicArray< T, TypeIsSimple > &right)
Definition: dynamic_array.h:419
unsigned int Size() const
Definition: dynamic_array.h:136
Definition: AttributeChangedEmitter.h:46
T * _objects
Definition: dynamic_array.h:67