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