// Program name: darray.h // Programmed by: Anthony Barbachan // Programmed in: C++ (Turbo C++ 3.0 Compatable) // Purpose: Header file a templatized dynamic array object. // Version: 1.00 // Last modified on: 5/10/1999 #ifndef __DARRAY_H__ #define __DARRAY_H__ #include #include ////////////////////////////////////////////////////////////////////////////// template class dynamic_array { public: enum { OK = 0, OUT_OF_MEMORY = -1, COUNTER_OVERFLOW = -2 }; protected: ObjectType** obj_array; size_t nobjects; size_t objects_allocated; size_t fragment_size; private: void clear_variables(size_t fsize = 1u); void free_buffers(void); public: dynamic_array(size_t fsize = 1u) { clear_variables(fsize); } ~dynamic_array() { free_buffers(); } void reset(size_t fsize = 1u); int add_object(ObjectType* obj = NULL); int add_objects(size_t nobjs); ObjectType& operator [] (size_t pos) { return *(obj_array[pos]); } }; ////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////*************************************** template void dynamic_array::clear_variables(size_t fsize) { obj_array = NULL; nobjects = 0u; objects_allocated = 0u; fragment_size = (fsize) ? fsize : 1u; } ///////////////////////////////////////*************************************** // This function frees all the objects' dynamically allocated memory. template void dynamic_array::free_buffers() { if(obj_array != NULL) // If memory currently allocated { while(nobjects > 0u) // Delete allocated objects { nobjects--; delete obj_array[nobjects]; } free(obj_array); } } ///////////////////////////////////////*************************************** // Note: This function assumes that nobjects is never greater than // objects_allocated. Any code that does that is a bug. template int dynamic_array::add_object(ObjectType* obj) { if(nobjects == objects_allocated) // Check for free positions { // Resize array if needbe size_t new_allocation = objects_allocated + fragment_size; if(new_allocation < objects_allocated) return COUNTER_OVERFLOW; ObjectType** temp = (ObjectType * *) realloc(obj_array, new_allocation * sizeof(ObjectType *)); if(temp == NULL) return OUT_OF_MEMORY; memset(temp + objects_allocated, 0, fragment_size * sizeof(ObjectType *)); objects_allocated = new_allocation; obj_array = temp; } obj_array[nobjects] = (obj == NULL) ? new ObjectType : obj; nobjects++; return OK; } ///////////////////////////////////////*************************************** // Note: This function assumes that nobjects is never greater than // objects_allocated. Any code that does that is a bug. // Note: Memory allocation is still done on the fragment border, thus using // a large fragment size combined with a large allocation can cause // a counter overflow error despite there being enougth memory // available for the desired number of objects. template int dynamic_array::add_objects(size_t nobjs) { size_t new_nobjects = nobjects + nobjs; if(new_nobjects < nobjects) return COUNTER_OVERFLOW; if(new_nobjects > objects_allocated) // Check for free positions { size_t needed = new_nobjects - objects_allocated; size_t new_allocation = needed; needed = (needed / fragment_size + (needed % fragment_size != 0)) * fragment_size; if(needed < new_allocation) return COUNTER_OVERFLOW; new_allocation = objects_allocated + needed; if(new_allocation < objects_allocated) return COUNTER_OVERFLOW; ObjectType** temp = (ObjectType * *) realloc(obj_array, new_allocation * sizeof(ObjectType *)); if(temp == NULL) return OUT_OF_MEMORY; memset(temp + objects_allocated, 0, needed * sizeof(ObjectType *)); objects_allocated = new_allocation; obj_array = temp; } while(nobjects < new_nobjects) { obj_array[nobjects] = new ObjectType; nobjects++; } return OK; } ///////////////////////////////////////*************************************** template void dynamic_array::reset(size_t fsize) { free_buffers(); clear_variables(fsize); } ///////////////////////////////////////*************************************** #endif