/* exarray.h. A template of dynamic arrays with automatic check of an index. (minimal edition). (C) R.N.Shakirov, IMach of RAS (UB), 1998 - 2000 All Rights Reserved. */ template <class T> class exarray { T* e; // Base array unsigned len; // Num of elements // Memory allocation methods (see below). void realloc (unsigned size); void grow (unsigned i); // Private copy constructor & copy assignment: // assignment of dynamic arrays is locked. exarray (const exarray<T>&); exarray<T>& operator = (const exarray<T>&); public: // Constructor of dynamic array. exarray () { e = 0; len = 0; } // Destructor of dynamic array. ~exarray() { realloc (0); } // Access to array with check of bounds. // If index is out of range, the array grows, // extra memory is filled with zeros and // constructors of extra elements is called. T& operator [] (unsigned i) { if (len<=i) grow(i); return e[i]; } T& operator [] (int i) { return (operator [] ((unsigned)i));} T& operator * () { if (len<=0) grow(0); return e[0]; } // Access to array without check of bounds. T& item (unsigned i) { return e[i];} T* base () { return e; } // Auto conversion to const T*. operator const T* () { return e; } }; // Declarations of memory allocation // functions from exarray.cpp. void exmrealloc (void **p, unsigned size, unsigned oldsize); unsigned excalcsize (unsigned size); // Function exmuladd computes n*s+k // within int range 0..~0u>>1. // In the case of overflow returns ~0u. inline unsigned exmuladd (unsigned s, unsigned n, unsigned k) { return ((n<=((~0u>>1)-k)/s)? n*s+k: ~0u);} // Stub class for call of constructors and // destructors without memory allocation. template <class T> struct __EXRELOC { T value; void* operator new (size_t, void* p) { return p; } void operator delete (void*) { ; } }; // Private method realloc sets // the dynamic array size (in bytes) // and call default constructors of // destructors of elements. template <class T> void exarray<T>::realloc (unsigned size) { unsigned n = size/sizeof (T); while (len > n) // Destructors { len--; delete (__EXRELOC<T> *)(e + len);} exmrealloc // Memory allocation ((void **)&e, size, sizeof(T)*len); while (len < n) // Default constructors { new (e + len)__EXRELOC<T>; len++; } } // Private method grow allocates memory for // elements with indexes up to i (at least). // For efficiency extra allocation is provided. template <class T> void exarray<T>::grow (unsigned i) { realloc (excalcsize ( exmuladd (sizeof(T), i, sizeof(T)))); }