/* ** tarray.h ** Templated, automatically resizing array ** **--------------------------------------------------------------------------- ** Copyright 1998-2001 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** 3. The name of the author may not be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** */ #ifndef __TARRAY_H__ #define __TARRAY_H__ #include template class TArray { public: TArray () { Most = 0; Count = 0; Array = NULL; } TArray (int max) { Most = max; Count = 0; Array = new T[max]; } TArray (const TArray &other) { DoCopy (other); } TArray &operator= (const TArray &other) { if (&other != this) { if (Array != NULL) { delete[] Array; } DoCopy (other); } return *this; } ~TArray () { if (Array) free (Array); } T &operator[] (size_t index) const { return Array[index]; } size_t Push (const T &item) { if (Count >= Most) { Most = (Most >= 16) ? Most + Most / 2 : 16; Realloc (Count, Most); } Array[Count] = item; return Count++; } bool Pop (T &item) { if (Count > 0) { item = Array[--Count]; return true; } return false; } void Delete (int index) { if (index < Count-1) memmove (Array + index, Array + index + 1, (Count - index) * sizeof(T)); else if (index < Count) Count--; } void Realloc (size_t count, size_t most) { T *copy = new T[most]; for (size_t i = 0; i < count; ++i) { copy[i] = Array[i]; } delete[] Array; Array = copy; } void ShrinkToFit () { if (Most > Count) { Most = Count; if (Most == 0) { if (Array != NULL) { free (Array); Array = NULL; } } else { Realloc (Count, Most); } } } // Grow Array to be large enough to hold amount more entries without // further growing. void Grow (size_t amount) { if (Count + amount > Most) { const size_t choicea = Count + amount; const size_t choiceb = Most + Most/2; Most = (choicea > choiceb ? choicea : choiceb); Realloc (Count, Most); } } // Resize Array so that it has exactly amount entries in use. void Resize (size_t amount) { if (Count < amount) { Grow (amount - Count); } else if (Count > amount) { Count = amount; } } // Reserves amount entries at the end of the array, but does nothing // with them. size_t Reserve (size_t amount) { if (Count + amount > Most) { Grow (amount); } size_t place = Count; Count += amount; return place; } size_t Size () const { return Count; } size_t Max () const { return Most; } void Clear () { Count = 0; } private: T *Array; size_t Most; size_t Count; void DoCopy (const TArray &other) { Most = Count = other.Count; if (Count != 0) { Array = new T[Most]; for (size_t i = 0; i < Count; ++i) { Array[i] = other.Array[i]; } } else { Array = NULL; } } }; #endif //__TARRAY_H__