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  public:
00043   typedef T element_type;
00044   typedef T* iterator;
00045   typedef T const* const_iterator;
00046 
00047   vbl_array_3d(): element_(0), row1_count_(0), row2_count_(0), row3_count_(0)
00048   {}
00049 
00050   vbl_array_3d(size_type n1, size_type n2, size_type n3) { construct(n1, n2, n3); }
00051 
00052   vbl_array_3d(size_type n1, size_type n2, size_type n3, T const* init_values)
00053   {
00054     construct(n1, n2, n3); set(init_values);
00055   }
00056 
00057   vbl_array_3d(size_type n1, size_type n2, size_type n3, T const& fill_value)
00058   {
00059     construct(n1, n2, n3); fill(fill_value);
00060   }
00061 
00062   vbl_array_3d(vbl_array_3d<T> const& that)
00063   : element_(0), row1_count_(0), row2_count_(0), row3_count_(0)
00064   {
00065     if (that.element_) {
00066       construct(that.row1_count_,that.row2_count_,that.row3_count_);
00067       set(that.data_block());
00068     }
00069   }
00070 
00071   ~vbl_array_3d () { destruct(); }
00072   vbl_array_3d<T>& operator=(vbl_array_3d<T> const& that) {
00073     resize(that.row1_count_, that.row2_count_, that.row3_count_);
00074     set(that.data_block());
00075     return *this;
00076   }
00077 
00078   //: Comparison
00079   bool operator==(vbl_array_3d<T> const& that) const {
00080     if (row1_count_ != that.row1_count_ ||
00081         row2_count_ != that.row2_count_ ||
00082         row3_count_ != that.row3_count_)
00083       return false;
00084     const_iterator i = this->begin();
00085     const_iterator j = that.begin();
00086     while (i != this->end())
00087     {
00088       if (!(*i == *j)) // do not assume we have operator!=(T)
00089         return false;
00090       ++i; ++j;
00091     }
00092     return true;
00093   }
00094 
00095   // Data Access---------------------------------------------------------------
00096 
00097   T      & operator() (size_type i1, size_type i2, size_type i3)
00098   {
00099     RANGECHECK(i1,i2,i3);
00100     return element_ [i1][i2][i3];
00101   }
00102 
00103   T const& operator() (size_type i1, size_type i2, size_type i3) const
00104   {
00105     RANGECHECK(i1,i2,i3);
00106     return element_ [i1][i2][i3];
00107   }
00108 
00109   T      * const* operator[](size_type i1) { return element_[i1]; }
00110   T const* const* operator[](size_type i1) const { return element_[i1]; }
00111 
00112   // dimensions
00113   size_type get_row1_count () const { return row1_count_; }
00114   size_type get_row2_count () const { return row2_count_; }
00115   size_type get_row3_count () const { return row3_count_; }
00116 
00117   // iterators
00118   size_type size() const
00119   {
00120     return row1_count_ * row2_count_ * row3_count_;
00121   }
00122 
00123   iterator begin() { return element_[0][0]; }
00124   iterator end  () { return begin() + size(); }
00125   const_iterator begin() const { return element_[0][0]; }
00126   const_iterator end  () const { return begin() + size(); }
00127 
00128   // data_block will return all elements of the array in sequential storage.
00129   T      * data_block()       { return element_[0][0]; }
00130   T const* data_block() const { return element_[0][0]; }
00131 
00132   void resize(size_type n1, size_type n2, size_type n3); // no malloc unless size changes.
00133   void set(T const* array);
00134   void get(T* array) const;
00135   void fill(T const& value);
00136 
00137  protected:
00138   void construct(size_type, size_type, size_type);
00139   void destruct ();
00140 
00141  private:
00142   T ***element_;
00143   size_type row1_count_;
00144   size_type row2_count_;
00145   size_type row3_count_;
00146 };
00147 
00148 #undef RANGECHECK
00149 
00150 //
00151 // formatted I/O
00152 //
00153 #include <vcl_iosfwd.h>
00154 export template <class T> vcl_ostream& operator<<(vcl_ostream&,
00155                                                   vbl_array_3d<T >const&);
00156 
00157 export template <class T> vcl_istream& operator>>(vcl_istream&,
00158                                                   vbl_array_3d<T >&);
00159 
00160 #define VBL_ARRAY_3D_INSTANTIATE \
00161 extern "please include vbl/vbl_array_3d.txx instead"
00162 #define VBL_ARRAY_3D_IO_INSTANTIATE \
00163 extern "please include vbl/vbl_array_3d.txx instead"
00164 
00165 #endif // vbl_array_3dh