/*-------------------------------------------------------------------------- @COPYRIGHT : Copyright 1996, Alex P. Zijdenbos, McConnell Brain Imaging Centre, Montreal Neurological Institute, McGill University. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies. The author and McGill University make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ---------------------------------------------------------------------------- $RCSfile: Array.h,v $ $Revision: 1.4 $ $Author: stever $ $Date: 2003/11/17 04:07:52 $ $State: Exp $ --------------------------------------------------------------------------*/ /* * Essentially the template Array class described in Lippman's C++ Primer * * 11/12/1993 * * Alex Zijdenbos */ #ifndef ARRAY_H #define ARRAY_H #include #include "trivials.h" #include "MTypes.h" const int DEFAULT_SIZE = 0; const int SIZE_INCREMENT = 32; const int BEFORE = -1; const int AFTER = 1; /****************** * Array base class ******************/ template class Array { // data members Array *_self; // Provided to circumvent the const mechanism for the iterator protected: static unsigned _arrayCtr; static Boolean _debug; static unsigned _rangeErrorCount; unsigned _size; unsigned _maxSize; Type *_contents; // Iterator member unsigned _itIndex; public: static unsigned debug(Boolean on = TRUE); // Manager functions Array (unsigned sz = DEFAULT_SIZE); Array (const Type&, unsigned sz); Array (const Type *, unsigned); Array (const Array&); virtual ~Array (); // Access functions inline Type& operator [] (unsigned i); inline Type& operator [] (int i); inline const Type& operator [] (unsigned i) const; inline const Type& operator [] (int i) const; inline virtual Type& getEl(unsigned i); inline virtual const Type& getEl(unsigned i) const; inline virtual const Type& getElConst(unsigned i) const; inline virtual void setEl(unsigned i, Type value); // Iterator functions //virtual void resetIterator(unsigned i = 0); // Resets iterator to element i virtual void resetIterator(unsigned i = 0) const; inline virtual Type& current(); inline virtual const Type& current() const; // Prefix ascending iterators inline virtual Type& operator ++(); inline virtual const Type& operator ++() const; // Postfix ascending iterators inline virtual Type& operator ++(int); inline virtual const Type& operator ++(int) const; // Prefix descending iterators inline virtual Type& operator --(); inline virtual const Type& operator --() const; // Postfix descending iterators inline virtual Type& operator --(int); inline virtual const Type& operator --(int) const; Array operator () (unsigned nElements) const; // Sub-array (first nElements) Array operator () (unsigned start, unsigned end) const; // Sub-array Boolean operator ! () const; virtual Type& first(); virtual Type& last(); virtual unsigned size() const; // Direct access to contents - volatile!! virtual const Type *contents() const; virtual Type *contents(); virtual operator const Type *() const; virtual operator Type *(); // Other functions Array& operator = (const Array&); // Copy Array& absorb(Array&); // Copy (source destroyed) Array& operator () (const Type *, unsigned); // Copy from C array // Returns C array. Uses if specified; otherwise allocates a new array. Type *asCarray(Type *array = 0) const; Array& append(const Type value); // Append a value at the end Array& append(const Array&); // Concatenate two arrays Array& insert(const Type&, unsigned index = 0); // Insert an element at Array& insert(const Array&, unsigned index = 0); // Insert an array at Array& replace(const Array&, unsigned index = 0);// Replace, starting at Type remove(unsigned index = 0); // Remove the element at Type removeLast(); // Remove the last element Array& reorder(const Array& indices); // Reorder the array Array& shuffle(); // Randomly re-order the array virtual void clear(const Type& value); virtual void newSize(unsigned); // Changes size of array; keeps contents if possible Array& destroy(); // Destroys array (sets size to zero, frees memory) // Rotate operators Array& operator << (unsigned); Array& operator >> (unsigned); Array sample(unsigned maxN) const; Array applyElementWise(Type (*function) (Type)) const; // I/O virtual std::ostream& print(std::ostream& os) const; protected: void _grow(unsigned amount); // Allocate more space; do not change _size virtual void _rangeError(unsigned& index) const; virtual void _notImplementedError() const; }; template unsigned size(const Array& array); template std::ostream& operator << (std::ostream& os, const Array& array); template Type& Array::operator [] (unsigned i) { return getEl(i); } template Type& Array::operator [] (int i) { return getEl((unsigned)i); } template const Type& Array::operator [] (unsigned i) const { return getElConst(i); } template const Type& Array::operator [] (int i) const { return getElConst(i); } // // Access functions // template Type& Array::getEl(unsigned i) { if (i >= _size)_rangeError(i); return _contents[i]; } template const Type& Array::getEl(unsigned i) const { return getElConst(i); } template const Type& Array::getElConst(unsigned i) const { if (i >= _size) _rangeError(i); return _contents[i]; } template void Array::setEl(unsigned i, Type value) { if (i >= _size) _rangeError(i); _contents[i] = value; } template Type& Array::current() { return _contents[_itIndex]; } template const Type& Array::current() const { return _contents[_itIndex]; } // Prefix ascending iterators template Type& Array::operator ++() { return _contents[++_itIndex]; } template const Type& Array::operator ++() const { return _contents[++_self->_itIndex]; } // Postfix ascending iterators template Type& Array::operator ++(int) { return _contents[_itIndex++]; } template const Type& Array::operator ++(int) const { return _contents[_self->_itIndex++]; } // Prefix descending iterators template Type& Array::operator --() { return _contents[--_itIndex]; } template const Type& Array::operator --() const { return _contents[--_self->_itIndex]; } // Postfix descending iterators template Type& Array::operator --(int) { return _contents[_itIndex--]; } template const Type& Array::operator --(int) const { return _contents[_self->_itIndex--]; } #endif