core/vbl/vbl_array_2d.h
Go to the documentation of this file.
00001 // This is core/vbl/vbl_array_2d.h
00002 #ifndef vbl_array_2d_h_
00003 #define vbl_array_2d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Contains class for a templated 2d array
00010 // \author Andrew W. Fitzgibbon, Oxford RRG
00011 // \date   05 Aug 96
00012 //
00013 // \verbatim
00014 // Modifications
00015 // Peter Vanroose -13nov98- added copy constructor and assignment operator
00016 // AWF 10/12/98 Added row/column store.  The old split was just too pedantic.
00017 // PDA (Manchester) 21/03/2001: Tidied up the documentation
00018 // \endverbatim
00019 
00020 #include <vcl_iosfwd.h>
00021 #include <vcl_cstddef.h>
00022 
00023 //: simple 2D array
00024 template <class T>
00025 class vbl_array_2d
00026 {
00027  public:
00028   typedef vcl_size_t size_type;
00029  public:
00030 
00031   //: Default constructor
00032   vbl_array_2d() { construct(); }
00033 
00034   //: Construct m-by-n array.
00035   vbl_array_2d(size_type m, size_type n) { construct(m, n); }
00036 
00037   //: Construct and fill an m-by-n array.
00038   vbl_array_2d(size_type m, size_type n, const T &v) { construct(m, n); fill(v);}
00039 
00040   //: Construct from a 2d array
00041   vbl_array_2d(vbl_array_2d<T> const &that) {
00042     construct(that.rows(), that.cols());
00043     operator=(that);
00044   }
00045 
00046   //: Destructor
00047   ~vbl_array_2d() { destruct(); }
00048 
00049   //: Assignment
00050   vbl_array_2d<T>& operator=(vbl_array_2d<T> const &that) {
00051     resize(that.rows(), that.cols());
00052     for (size_type i=0; i<num_rows_; ++i)
00053       for (size_type j=0; j<num_cols_; ++j)
00054         rows_[i][j] = that.rows_[i][j];
00055     return *this;
00056   }
00057 
00058   //: Comparison
00059   bool operator==(vbl_array_2d<T> const &that) const {
00060     if (num_rows_ != that.num_rows_ || num_cols_ != that.num_cols_)
00061       return false;
00062     for (size_type i=0; i<num_rows_; ++i)
00063       for (size_type j=0; j<num_cols_; ++j)
00064         if (!( rows_[i][j] == that.rows_[i][j] )) // do not assume we have operator!=
00065           return false;
00066     return true;
00067   }
00068 
00069   //:
00070   bool operator!=(vbl_array_2d<T> const &that) const {
00071     return ! operator==(that);
00072   }
00073 
00074   //: fill with `value'
00075   void fill(T value) {
00076     for (size_type i=0; i<num_rows_; ++i)
00077       for (size_type j=0; j<num_cols_; ++j)
00078         rows_[i][j] = value;
00079   }
00080 
00081   //: change size.
00082   void resize(size_type m, size_type n) {
00083     if (m != num_rows_ || n != num_cols_) {
00084       destruct();
00085       construct(m, n);
00086     }
00087   }
00088 
00089   //: make as if default-constructed.
00090   void clear() {
00091     if (rows_) {
00092       destruct();
00093       construct();
00094     }
00095   }
00096 
00097   // Data Access---------------------------------------------------------------
00098   T const& operator() (size_type i, size_type j) const { return rows_[i][j]; }
00099   T      & operator() (size_type i, size_type j) { return rows_[i][j]; }
00100 
00101   void put(size_type i, size_type j, T const &x) { rows_[i][j] = x; }
00102   T    get(size_type i, size_type j) const { return rows_[i][j]; }
00103 
00104   T const* operator[] (size_type i) const { return rows_[i]; }
00105   T      * operator[] (size_type i) { return rows_[i]; }
00106 
00107 
00108   //: Return number of rows
00109   size_type rows() const { return num_rows_; }
00110 
00111   //: Return number of columns
00112   size_type cols() const { return num_cols_; }
00113 
00114   //: Return number of columns
00115   size_type columns() const { return num_cols_; }
00116 
00117   //: Return size = (number of rows) * (number of columns)
00118   size_type size() const { return num_rows_ * num_cols_; }
00119 
00120   T      *      * get_rows() { return rows_; }
00121   T const* const* get_rows() const { return rows_; }
00122 
00123   typedef T       *iterator;
00124   iterator begin() { return rows_[0]; }
00125   iterator end  () { return rows_[0] + num_cols_ * num_rows_; }
00126 
00127   typedef T const *const_iterator;
00128   const_iterator begin() const { return rows_[0]; }
00129   const_iterator end  () const { return rows_[0] + num_cols_ * num_rows_; }
00130 
00131  private:
00132   T** rows_;
00133   size_type num_rows_;
00134   size_type num_cols_;
00135 
00136   void construct() {
00137     rows_ = 0;
00138     num_rows_ = 0;
00139     num_cols_ = 0;
00140   }
00141 
00142   void construct(size_type m, size_type n) {
00143     num_rows_ = m;
00144     num_cols_ = n;
00145     if (m && n) {
00146       rows_ = new T * [m];
00147       T* p = new T[m * n];
00148       for (size_type i = 0; i < m; ++i)
00149         rows_[i] = p + i * n;
00150     }
00151     else {
00152       rows_ = 0;
00153     }
00154   }
00155 
00156   void destruct() {
00157     if (rows_) {
00158       delete [] rows_[0];
00159       delete [] rows_;
00160     }
00161   }
00162 };
00163 
00164 export template <class T>
00165 vcl_ostream& operator<<(vcl_ostream &, vbl_array_2d<T> const &);
00166 
00167 #define VBL_ARRAY_2D_INSTANTIATE \
00168 extern "please include vbl/vbl_array_2d.txx instead"
00169 
00170 #endif // vbl_array_2d_h_