core/vbl/vbl_array_3d.h
Go to the documentation of this file.
00001 // This is core/vbl/vbl_array_3d.h
00002 #ifndef vbl_array_3dh
00003 #define vbl_array_3dh
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Contains class for templated 3d array
00010 // \author Paul Beardsley, Oxford University, UK
00011 // \date   29 Mar 1996
00012 //
00013 // \verbatim
00014 //  Modifications
00015 //   1996-09-26 AWF Converted to non-fascist C++ :-)
00016 //   1997-02-18 AWF Templated
00017 //   01 Mar 2001 fsm. Converted to fascist C++
00018 //   PDA (Manchester) 21 Mar 2001: Tidied up the documentation
00019 //   Peter Vanroose 3 Jan. 2002 added operator==
00020 //   Peter Vanroose 4 Jan. 2002 bug fix: 3rd arg row2_count_ --> row3_count_
00021 // \endverbatim
00022 
00023 
00024 #include <vcl_compiler.h>
00025 #include <vcl_cstddef.h>
00026 
00027 #ifdef __OPTIMIZE__
00028 # define RANGECHECK(i,j,k) ((void)0)
00029 #else
00030 # include <vcl_cassert.h>
00031 # define RANGECHECK(i,j,k) assert(((size_type)i < row1_count_) && \
00032                    ((size_type)j < row2_count_) && ((size_type)k < row3_count_))
00033 #endif
00034 
00035 //: Templated 3-dimensional array
00036 
00037 export template <class T>
00038 class vbl_array_3d
00039 {
00040  public:
00041   typedef vcl_size_t size_type;
00042   typedef T element_type;
00043 
00044  private:
00045   element_type ***element_;
00046   size_type row1_count_;
00047   size_type row2_count_;
00048   size_type row3_count_;
00049 
00050  public:
00051   typedef T*       iterator;
00052   typedef T const* const_iterator;
00053 
00054   typedef T       &reference;
00055   typedef T const &const_reference;
00056  public:
00057 
00058   vbl_array_3d(): element_(0), row1_count_(0), row2_count_(0), row3_count_(0)
00059   {}
00060 
00061   vbl_array_3d(size_type n1, size_type n2, size_type n3)
00062   { construct(n1, n2, n3); }
00063 
00064   vbl_array_3d(size_type n1, size_type n2, size_type n3, T const* init_values)
00065   {
00066     construct(n1, n2, n3); set(init_values);
00067   }
00068 
00069   vbl_array_3d(size_type n1, size_type n2, size_type n3, T const& fill_value)
00070   {
00071     construct(n1, n2, n3); fill(fill_value);
00072   }
00073 
00074   vbl_array_3d(vbl_array_3d<T> const& that)
00075   : element_(0), row1_count_(0), row2_count_(0), row3_count_(0)
00076   {
00077     if (that.element_) {
00078       construct(that.row1_count_,that.row2_count_,that.row3_count_);
00079       set(that.data_block());
00080     }
00081   }
00082 
00083   ~vbl_array_3d () { destruct(); }
00084   vbl_array_3d<T>& operator=(vbl_array_3d<T> const& that) {
00085     resize(that.row1_count_, that.row2_count_, that.row3_count_);
00086     set(that.data_block());
00087     return *this;
00088   }
00089 
00090   //: Comparison
00091   bool operator==(vbl_array_3d<T> const& that) const {
00092     if (row1_count_ != that.row1_count_ ||
00093         row2_count_ != that.row2_count_ ||
00094         row3_count_ != that.row3_count_)
00095       return false;
00096     const_iterator i = this->begin();
00097     const_iterator j = that.begin();
00098     while (i != this->end())
00099     {
00100       if (!(*i == *j)) // do not assume we have operator!=(T)
00101         return false;
00102       ++i; ++j;
00103     }
00104     return true;
00105   }
00106 
00107   // Data Access---------------------------------------------------------------
00108 
00109   reference       operator() (size_type i1, size_type i2, size_type i3)
00110   {
00111     RANGECHECK(i1,i2,i3);
00112     return element_ [i1][i2][i3];
00113   }
00114 
00115   const_reference operator() (size_type i1, size_type i2, size_type i3) const
00116   {
00117     RANGECHECK(i1,i2,i3);
00118     return element_ [i1][i2][i3];
00119   }
00120 
00121   T      * const* operator[](size_type i1) { return element_[i1]; }
00122   T const* const* operator[](size_type i1) const { return element_[i1]; }
00123 
00124   // dimensions
00125   size_type get_row1_count () const { return row1_count_; }
00126   size_type get_row2_count () const { return row2_count_; }
00127   size_type get_row3_count () const { return row3_count_; }
00128 
00129   size_type size() const { return row1_count_ * row2_count_ * row3_count_; }
00130   size_type capacity() const { return size(); }
00131 
00132   // iterators
00133   iterator begin() { return element_[0][0]; }
00134   iterator end  () { return begin() + size(); }
00135   const_iterator begin() const { return element_[0][0]; }
00136   const_iterator end  () const { return begin() + size(); }
00137 
00138   // data_block will return all elements of the array in sequential storage.
00139   T      * data_block()       { return element_[0][0]; }
00140   T const* data_block() const { return element_[0][0]; }
00141 
00142   void resize(size_type n1, size_type n2, size_type n3); // no malloc unless size changes.
00143   void set(T const* array);
00144   void get(T* array) const;
00145   void fill(T const& value);
00146 
00147  protected:
00148   void construct(size_type, size_type, size_type);
00149   void destruct();
00150 };
00151 
00152 #undef RANGECHECK
00153 
00154 //
00155 // formatted I/O
00156 //
00157 #include <vcl_iosfwd.h>
00158 export template <class T> vcl_ostream& operator<<(vcl_ostream&,
00159                                                   vbl_array_3d<T >const&);
00160 
00161 export template <class T> vcl_istream& operator>>(vcl_istream&,
00162                                                   vbl_array_3d<T >&);
00163 
00164 #define VBL_ARRAY_3D_INSTANTIATE \
00165 extern "please include vbl/vbl_array_3d.txx instead"
00166 #define VBL_ARRAY_3D_IO_INSTANTIATE \
00167 extern "please include vbl/vbl_array_3d.txx instead"
00168 
00169 #endif // vbl_array_3dh