core/vbl/vbl_array_3d.txx
Go to the documentation of this file.
00001 // This is core/vbl/vbl_array_3d.txx
00002 #ifndef vbl_array_3d_txx_
00003 #define vbl_array_3d_txx_
00004 
00005 //:
00006 // \file
00007 
00008 #include "vbl_array_3d.h"
00009 #include <vcl_cassert.h>
00010 
00011 //--------------------------------------------------------------
00012 //
00013 // Constructor and Destructor Functions
00014 //
00015 //--------------------------------------------------------------
00016 
00017 //: Constructor utility.
00018 // This allocates a 3D array which can be referenced using the form myarray[a][b][c].
00019 // Useful in C although maybe superfluous here as access is via a get function anyway.
00020 template <class T>
00021 void vbl_array_3d<T>::construct(size_type n1, size_type n2, size_type n3)
00022 {
00023   row1_count_ = n1;
00024   row2_count_ = n2;
00025   row3_count_ = n3;
00026 
00027   // If any of the dimensions are 0, don't allocate memory, just return.
00028   if ((n1 * n2 * n3)==0) {
00029     element_ = 0;
00030     return;
00031   }
00032 
00033   // allocate the memory for the first level pointers.
00034   element_ = new T** [n1];
00035 
00036   // set the first level pointers and allocate the memory for the second level pointers.
00037   {
00038     element_[0] = new T* [n1 * n2];
00039     for (size_type row1_index = 0; row1_index < n1; row1_index++)
00040       element_ [row1_index] = element_[0] + n2 * row1_index;
00041   }
00042 
00043   T* array_ptr = new T [n1*n2*n3];
00044 
00045   // set the second level pointers.
00046   for (size_type row1_index = 0; row1_index < n1; row1_index++)
00047     for (size_type row2_index = 0; row2_index < n2; row2_index++) {
00048       element_ [row1_index][row2_index] = array_ptr;
00049       array_ptr += n3;
00050     }
00051 }
00052 
00053 template <class T>
00054 void vbl_array_3d<T>::destruct()
00055 {
00056   if (element_) {
00057     // remove the actual members.
00058     delete [] element_ [0][0];
00059 
00060     // remove the second level pointers.
00061     delete [] element_ [0];
00062 
00063     // remove the first level pointers.
00064     delete [] element_;
00065   }
00066 }
00067 
00068 template <class T>
00069 void vbl_array_3d<T>::resize(size_type n1, size_type n2, size_type n3)
00070 {
00071   if (n1 == row1_count_ && n2 == row2_count_ && n3 == row3_count_)
00072     return;
00073   destruct();
00074   construct(n1, n2, n3);
00075 }
00076 
00077 //: Fill from static array of Ts.
00078 //  The final index fills fastest, so if we consider the tensor as a set of
00079 // matrices (M[i])[j][k] then the matrices are filled in the usual C order.
00080 template <class T>
00081 void vbl_array_3d<T>::set(T const* p)
00082 {
00083   for (size_type row1_index = 0; row1_index < row1_count_; row1_index++)
00084     for (size_type row2_index = 0; row2_index < row2_count_; row2_index++)
00085       for (size_type row3_index = 0; row3_index < row3_count_; row3_index++)
00086         element_ [row1_index][row2_index][row3_index] = *p++;
00087 }
00088 
00089 //: Get into array
00090 template <class T>
00091 void vbl_array_3d<T>::get(T* p) const
00092 {
00093   for (size_type row1_index = 0; row1_index < row1_count_; row1_index++)
00094     for (size_type row2_index = 0; row2_index < row2_count_; row2_index++)
00095       for (size_type row3_index = 0; row3_index < row3_count_; row3_index++)
00096         *p++ = element_ [row1_index][row2_index][row3_index];
00097 }
00098 
00099 //: Fill with constant
00100 template <class T>
00101 void vbl_array_3d<T>::fill(T const& value)
00102 {
00103   size_type n = row1_count_ * row2_count_ * row3_count_;
00104   T* d = data_block();
00105   T* e = d + n;
00106   while (d < e)
00107     *d++ = value;
00108 }
00109 
00110 //--------------------------------------------------------------------------------
00111 
00112 #include <vcl_iostream.h>
00113 
00114 template <class T>
00115 vcl_ostream & operator<<(vcl_ostream& os, vbl_array_3d<T> const& A)
00116 {
00117   typedef typename vbl_array_3d<T>::size_type size_type;
00118   os << "vbl_array_3d [";
00119   for (size_type i=0; i<A.get_row1_count(); ++i) {
00120     os << vcl_endl << "  <" << i << '>';
00121     for (size_type j=0; j<A.get_row2_count(); ++j) {
00122       os << vcl_endl << "   ";
00123       for (size_type k=0; k<A.get_row3_count(); ++k) {
00124         os << ' ' << A(i,j,k);
00125       }
00126     }
00127   }
00128   os << "\n             ]" << vcl_endl;
00129   return os;
00130 }
00131 
00132 template <class T>
00133 vcl_istream & operator>>(vcl_istream& is, vbl_array_3d<T>& A)
00134 {
00135   typedef typename vbl_array_3d<T>::size_type size_type;
00136   for (size_type i=0; i<A.get_row1_count(); ++i)
00137     for (size_type j=0; j<A.get_row2_count(); ++j)
00138       for (size_type k=0; k<A.get_row3_count(); ++k)
00139         is >> A(i,j,k);
00140   return is;
00141 }
00142 
00143 //--------------------------------------------------------------------------------
00144 
00145 #undef VBL_ARRAY_3D_INSTANTIATE
00146 #define VBL_ARRAY_3D_INSTANTIATE(T) template class vbl_array_3d<T >
00147 
00148 #undef VBL_ARRAY_3D_IO_INSTANTIATE
00149 #define VBL_ARRAY_3D_IO_INSTANTIATE(T) \
00150 template vcl_ostream & operator<<(vcl_ostream &,vbl_array_3d<T > const &); \
00151 template vcl_istream & operator>>(vcl_istream &,vbl_array_3d<T > &)
00152 
00153 #endif // vbl_array_3d_txx_