Polaris: Array.h Source File

Array.h

Go to the documentation of this file.
00001 #ifndef _ARRAY_H
00002 #define _ARRAY_H
00003 ///
00004 ///
00005 ///
00006 /// \class Array 
00007 /// \brief A template for an array of objects
00008 /// \defgroup Polaris
00009 /// \ingroup Polaris
00010 ///  Base
00011 /// \see Array.h
00012 /// \see Array.h
00013 ///
00014 /// \endcode
00015 /// \section Overview Overview
00016 /// This class is a template for forming an array of objects.
00017 ///
00018 /// \endcode
00019 /// \section Description Description
00020 /// The Array class offers three improvements from a simple array of
00021 /// objects; It knows its size, it can be resized, and it knows how to
00022 /// print itself.  This class differs from the List class in that
00023 /// random access is cheap to perform while resizing is expensive.
00024 ///
00025 /// The objects stored in Array must have two methods: a constructor
00026 /// that takes no arguments, and operator=().
00027 ///
00028 /// Arrays are indexed from 0.
00029 ///
00030 #include "ClassNames.h"
00031 #include <stream.h>
00032 #include "p-assert.h"
00033 ///
00034 template<class T>
00035 
00036 class Array {
00037 public:
00038     inline Array();
00039     inline Array(int size);
00040     inline Array(const Array<T> &other);
00041     inline ~Array();
00042 
00043     inline int entries() const;
00044     ///< Return the size of the array.
00045 
00046     inline const T & operator[] (int sub) const; 
00047     inline T & operator[] (int sub);
00048     ///< Access an element in the array.
00049 
00050     inline void clear();
00051     ///< Delete all the elements of the array and set the size
00052     ///< to zero.
00053 
00054     inline void resize(int size);
00055     ///< Resize the array to the given value.
00056 
00057     inline void print(ostream &out) const;
00058 
00059     ///< gcc-2.96 need the stupid "<>" pair
00060     ///< inline friend ostream & operator << (ostream &o, const Array<T> & a);
00061     friend ostream & operator << <> (ostream &o, const Array<T> & a);
00062 
00063     ///< Print Array as a comma separated list where each element is
00064     ///< printed out in the form subscript:object.
00065 
00066     inline void print(ostream &out, char *sep) const;
00067     ///< Print Array with 'sep' separating each element.  The
00068     ///< subscripts are not printed.
00069 
00070     inline Array<T> & operator = (const Array<T> & l);
00071     ///< Copy the contents of the other array into myself.
00072 
00073     inline int structures_OK() const;
00074     ///< Check the structure of the data for errors or inconsistency
00075     ///< Return 0 and print error message if problems found, otherwise
00076     ///< return 1 without message.
00077 
00078 private:
00079     T *_array;
00080     int _entries;
00081 };
00082 
00083 
00084 ///< implementation
00085 
00086 template <class T>
00087 inline
00088 Array<T>::Array()
00089 {
00090     #ifdef CLASS_INSTANCE_REGISTRY
00091     register_instance(ARRAY_CLASS, sizeof(Array), this);
00092     #endif
00093 
00094     _entries = 0;
00095     _array = 0;
00096 }
00097 
00098 template <class T>
00099 inline
00100 Array<T>::Array(int size)
00101 {
00102     #ifdef CLASS_INSTANCE_REGISTRY
00103     register_instance(ARRAY_CLASS, sizeof(Array), this);
00104     #endif
00105 
00106     _entries = 0;
00107     _array = 0;
00108     resize(size);
00109 }
00110 
00111 template <class T>
00112 inline
00113 Array<T>::Array(const Array<T> &other)
00114 {
00115     #ifdef CLASS_INSTANCE_REGISTRY
00116     register_instance(ARRAY_CLASS, sizeof(Array), this);
00117     #endif
00118 
00119     _entries = 0;
00120     _array = 0;
00121     *this = other;
00122 }
00123 
00124 template <class T>
00125 inline
00126 Array<T>::~Array()
00127 {
00128     #ifdef CLASS_INSTANCE_REGISTRY
00129     unregister_instance(ARRAY_CLASS, this);
00130     #endif
00131 
00132     if (_array)
00133         delete  [] _array;
00134 }
00135 
00136 template <class T>
00137 inline int
00138 Array<T>::entries() const
00139 {
00140     return _entries;
00141 }
00142 
00143 template <class T>
00144 inline const T &
00145 Array<T>::operator[] (int sub) const
00146 {
00147     p_assert(0 <= sub && sub < _entries,
00148          "Subscript out of range for Array::operator[]().");
00149 
00150     return _array[sub];
00151 }
00152 
00153 template <class T>
00154 inline T &
00155 Array<T>::operator[] (int sub)
00156 {
00157     p_assert(0 <= sub && sub < _entries,
00158          "Subscript out of range for Array::operator[]().");
00159 
00160     return _array[sub];
00161 }
00162 
00163 template <class T>
00164 inline void
00165 Array<T>::clear()
00166 {
00167     _entries = 0;
00168 
00169     if (_array) {
00170         delete  [] _array;
00171         _array = 0;
00172     }
00173 }
00174 
00175 template <class T>
00176 inline void
00177 Array<T>::resize(int size)
00178 {
00179     if (size < 0)
00180         size = 0;
00181 
00182     if (size != _entries) {
00183         int min_size = (size < _entries) ? size : _entries;
00184         T * old_array = _array;
00185         _entries = size;
00186         _array = new T [_entries];
00187 
00188         for (int i = 0; i < min_size; ++i) 
00189             _array[i] = old_array[i];
00190 
00191         if (old_array)
00192             delete [] old_array;
00193     }
00194 }
00195 
00196 template <class T>
00197 inline Array<T> &
00198 Array<T>::operator = (const Array<T> & other)
00199 {
00200     if (_entries != other._entries)
00201         resize(other._entries);
00202 
00203     for (int i = 0; i < _entries; ++i)
00204         _array[i] = other._array[i];
00205 
00206     return *this;
00207 }
00208 
00209 template <class T>
00210 inline void
00211 Array<T>::print(ostream & out,  char *sep) const
00212 {
00213     if (_entries > 0) {
00214         out << _array[0];
00215 
00216         for (int i = 1; i < _entries; ++i) 
00217             out << sep << _array[i];
00218     }
00219 }
00220 
00221 template <class T>
00222 inline void
00223 Array<T>::print(ostream & out) const
00224 {
00225     if (_entries > 0) {
00226         out << 0 << ":" << _array[0];
00227 
00228         for (int i = 1; i < _entries; ++i) 
00229             out << ", " << i << ":" << _array[i];
00230     }
00231 }
00232 
00233 template <class T> ostream &
00234 operator << (ostream &o, const Array<T> & a)
00235 {
00236     a.print(o);
00237     return o;
00238 }
00239 
00240 template <class T>
00241 inline int
00242 Array<T>::structures_OK() const
00243 {
00244     if (_entries < 0) {
00245         cerr << "\n\nError: Array::structures_OK(): Has a negative size.\n";
00246         return 0;
00247     }
00248     else if (_array == 0 && _entries != 0) {
00249         cerr << "\n\nError: Array::structures_OK(): _array field is NULL.\n";
00250         return 0;
00251     }
00252     
00253     return 1;
00254 }
00255 
00256 #endif
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:37 2005