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   typedef T element_type;
00030 
00031  private:
00032   element_type** rows_;
00033   size_type num_rows_;
00034   size_type num_cols_;
00035 
00036  public:
00037   typedef T       *iterator;
00038   typedef T const *const_iterator;
00039 
00040   typedef T       &reference;
00041   typedef T const &const_reference;
00042  public:
00043 
00044   //: Default constructor
00045   vbl_array_2d() { construct(); }
00046 
00047   //: Construct m-by-n array.
00048   vbl_array_2d(size_type m, size_type n) { construct(m, n); }
00049 
00050   //: Construct and fill an m-by-n array.
00051   vbl_array_2d(size_type m, size_type n, const T &v) { construct(m, n); fill(v);}
00052 
00053   //: Construct from a 2d array
00054   vbl_array_2d(vbl_array_2d<T> const &that) {
00055     construct(that.rows(), that.cols());
00056     operator=(that);
00057   }
00058 
00059   //: Destructor
00060   ~vbl_array_2d() { destruct(); }
00061 
00062   //: Assignment
00063   vbl_array_2d<T>& operator=(vbl_array_2d<T> const &that) {
00064     resize(that.rows(), that.cols());
00065     for (size_type i=0; i<num_rows_; ++i)
00066       for (size_type j=0; j<num_cols_; ++j)
00067         rows_[i][j] = that.rows_[i][j];
00068     return *this;
00069   }
00070 
00071   //: Comparison
00072   bool operator==(vbl_array_2d<T> const &that) const {
00073     if (num_rows_ != that.num_rows_ || num_cols_ != that.num_cols_)
00074       return false;
00075     for (size_type i=0; i<num_rows_; ++i)
00076       for (size_type j=0; j<num_cols_; ++j)
00077         if (!( rows_[i][j] == that.rows_[i][j] )) // do not assume we have operator!=
00078           return false;
00079     return true;
00080   }
00081 
00082   //:
00083   bool operator!=(vbl_array_2d<T> const &that) const {
00084     return ! operator==(that);
00085   }
00086 
00087   //: fill with `value'
00088   void fill(T value) {
00089     for (size_type i=0; i<num_rows_; ++i)
00090       for (size_type j=0; j<num_cols_; ++j)
00091         rows_[i][j] = value;
00092   }
00093 
00094   //: change size.
00095   void resize(size_type m, size_type n) {
00096     if (m != num_rows_ || n != num_cols_) {
00097       destruct();
00098       construct(m, n);
00099     }
00100   }
00101 
00102   //: make as if default-constructed.
00103   void clear() {
00104     if (rows_) {
00105       destruct();
00106       construct();
00107     }
00108   }
00109 
00110   // Data Access---------------------------------------------------------------
00111   const_reference operator() (size_type i, size_type j) const { return rows_[i][j]; }
00112   reference       operator() (size_type i, size_type j) { return rows_[i][j]; }
00113 
00114   void put(size_type i, size_type j, T const &x) { rows_[i][j] = x; }
00115   T    get(size_type i, size_type j) const { return rows_[i][j]; }
00116 
00117   T const* operator[] (size_type i) const { return rows_[i]; }
00118   T      * operator[] (size_type i) { return rows_[i]; }
00119 
00120 
00121   //: Return number of rows
00122   size_type rows() const { return num_rows_; }
00123 
00124   //: Return number of columns
00125   size_type cols() const { return num_cols_; }
00126 
00127   //: Return number of columns
00128   size_type columns() const { return num_cols_; }
00129 
00130   //: Return size = (number of rows) * (number of columns)
00131   size_type size() const { return num_rows_ * num_cols_; }
00132   size_type capacity() const { return size(); }
00133 
00134   T      *      * get_rows() { return rows_; }
00135   T const* const* get_rows() const { return rows_; }
00136 
00137   // iterators
00138   iterator begin() { return rows_[0]; }
00139   iterator end  () { return rows_[0] + num_cols_ * num_rows_; }
00140 
00141   const_iterator begin() const { return rows_[0]; }
00142   const_iterator end  () const { return rows_[0] + num_cols_ * num_rows_; }
00143 
00144  private:
00145   void construct() {
00146     rows_ = 0;
00147     num_rows_ = 0;
00148     num_cols_ = 0;
00149   }
00150 
00151   void construct(size_type m, size_type n) {
00152     num_rows_ = m;
00153     num_cols_ = n;
00154     if (m && n) {
00155       rows_ = new T * [m];
00156       T* p = new T[m * n];
00157       for (size_type i = 0; i < m; ++i)
00158         rows_[i] = p + i * n;
00159     }
00160     else {
00161       rows_ = 0;
00162     }
00163   }
00164 
00165   void destruct() {
00166     if (rows_) {
00167       delete [] rows_[0];
00168       delete [] rows_;
00169     }
00170   }
00171 };
00172 
00173 export template <class T>
00174 vcl_ostream& operator<<(vcl_ostream &, vbl_array_2d<T> const &);
00175 
00176 #define VBL_ARRAY_2D_INSTANTIATE \
00177 extern "please include vbl/vbl_array_2d.txx instead"
00178 
00179 #endif // vbl_array_2d_h_