// Template array classes /* Copyright (C) 1996, 1997 John W. Eaton This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if !defined (octave_Array_h) #define octave_Array_h 1 #if defined (__GNUG__) #pragma interface #endif #include #include class idx_vector; // For now, define this here if it is not already defined. Not doing // this can result in bugs that are very hard to find. #ifndef HEAVYWEIGHT_INDEXING #define HEAVYWEIGHT_INDEXING 1 #endif // One dimensional array class. Handles the reference counting for // all the derived classes. template class Array { private: // The real representation of all arrays. class ArrayRep { public: T *data; int len; int count; ArrayRep& operator = (const ArrayRep& a); ArrayRep (T *d, int l) : data (d), len (l), count (1) { } ArrayRep (void) : data (0), len (0), count (1) { } ArrayRep (int n) : data (new T [n]), len (n), count (1) { } ArrayRep (const ArrayRep& a) : data (new T [a.len]), len (a.len), count (1) { for (int i = 0; i < len; i++) data[i] = a.data[i]; } ~ArrayRep (void) { delete [] data; } int length (void) const { return len; } T& elem (int n) { return data[n]; } T elem (int n) const { return data[n]; } void qsort (int (*compare) (const void *, const void *)) { ::qsort (data, len, sizeof (T), compare); } }; void make_unique (void) { if (rep->count > 1) { --rep->count; rep = new ArrayRep (*rep); } } #ifdef HEAVYWEIGHT_INDEXING idx_vector *idx; int max_indices; int idx_count; #endif protected: ArrayRep *rep; Array (T *d, int l) { rep = new ArrayRep (d, l); #ifdef HEAVYWEIGHT_INDEXING idx = 0; max_indices = 1; idx_count = 0; #endif } public: Array (void) { rep = new ArrayRep (); #ifdef HEAVYWEIGHT_INDEXING idx = 0; max_indices = 1; idx_count = 0; #endif } Array (int n) { rep = new ArrayRep (n); #ifdef HEAVYWEIGHT_INDEXING idx = 0; max_indices = 1; idx_count = 0; #endif } Array (int n, const T& val); Array (const Array& a) { rep = a.rep; rep->count++; #ifdef HEAVYWEIGHT_INDEXING max_indices = a.max_indices; idx_count = 0; idx = 0; #endif } ~Array (void); Array& operator = (const Array& a); int capacity (void) const { return rep->length (); } int length (void) const { return rep->length (); } // No checking, even for multiple references, ever. T& xelem (int n) { return rep->elem (n); } T xelem (int n) const { return rep->elem (n); } // XXX FIXME XXX -- would be nice to fix this so that we don't // unnecessarily force a copy, but that is not so easy, and I see no // clean way to do it. T& checkelem (int n) { if (n < 0 || n >= rep->length ()) return range_error ("T& Array::checkelem", n); else { make_unique (); return xelem (n); } } T& elem (int n) { make_unique (); return xelem (n); } #if defined (BOUNDS_CHECKING) T& operator () (int n) { return checkelem (n); } #else T& operator () (int n) { return elem (n); } #endif T checkelem (int n) const { if (n < 0 || n >= rep->length ()) return range_error ("T Array::checkelem", n); else return xelem (n); } T elem (int n) const { return xelem (n); } #if defined (BOUNDS_CHECKING) T operator () (int n) const { return checkelem (n); } #else T operator () (int n) const { return elem (n); } #endif void resize (int n); void resize (int n, const T& val); const T *data (void) const { return rep->data; } T *fortran_vec (void); Array& qsort (int (*compare) (const void *, const void *)) { make_unique (); rep->qsort (compare); return *this; } T range_error (const char *fcn, int n) const; T& range_error (const char *fcn, int n); #ifdef HEAVYWEIGHT_INDEXING void set_max_indices (int mi) { max_indices = mi; } void clear_index (void); void set_index (const idx_vector& i); int index_count (void) const { return idx_count; } idx_vector *get_idx (void) const { return idx; } void maybe_delete_elements (idx_vector& i); Array value (void); Array index (idx_vector& i) const; #endif }; template int assign (Array& lhs, const Array& rhs); #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */