00001 #ifndef vnl_matrix_fixed_ref_h_ 00002 #define vnl_matrix_fixed_ref_h_ 00003 // This is vxl/vnl/vnl_matrix_fixed_ref.h 00004 00005 // 00006 //: \file 00007 // \brief Fixed size stack-stored vnl_matrix 00008 // \author Andrew W. Fitzgibbon, Oxford RRG, 04 Aug 96 00009 // vnl_matrix_fixed_ref is a fixed-size vnl_matrix for which the data space 00010 // has been supplied externally. This is useful for two main tasks: 00011 // 00012 // (a) Treating some row-based "C" matrix as a vnl_matrix in order to 00013 // perform vnl_matrix operations on it. 00014 // 00015 // (b) Declaring a vnl_matrix that uses entirely stack-based storage for the 00016 // matrix. 00017 // 00018 // The big warning is that returning a vnl_matrix_fixed_ref pointer will free 00019 // non-heap memory if deleted through a vnl_matrix pointer. This should be 00020 // very difficult though, as vnl_matrix_fixed_ref objects may not be constructed 00021 // using operator new. This in turn is plausible as the point is to avoid 00022 // such calls. 00023 // 00024 00025 // .Modifications: 00026 // Peter Vanroose, 27 nov 1996: added default constructor, which does 00027 // itself allocate the matrix storage. Necessary because otherwise 00028 // the compiler will itself generate a default constructor. 00029 // 4/4/01 LSB (Manchester) Tidied documentation 00030 // 00031 //----------------------------------------------------------------------------- 00032 00033 #include <vcl_cassert.h> 00034 #include <vcl_cstring.h> // memcpy() 00035 #include <vnl/vnl_matrix.h> 00036 00037 template <class T, int m, int n> 00038 class vnl_matrix_fixed_ref : public vnl_matrix<T> { 00039 typedef vnl_matrix<T> Base; 00040 T* rowspace[m]; 00041 public: 00042 00043 //: Construct a fixed size matrix which points to the row-stored 00044 // data space supplied. The space must remain valid for the lifetime 00045 // of the vnl_matrix_fixed_ref. Alterations to the locations pointed to by 00046 // space will be (obviously) visible to users of the vnl_matrix_fixed_ref 00047 // and vice versa. 00048 vnl_matrix_fixed_ref(T *space = (T*)0) { 00049 Base::data = rowspace; // thf. can't derive this from matrixref 00050 if (!space) space = vnl_c_vector<T>::allocate_T(m*n); 00051 for(int i = 0; i < m; ++i) 00052 Base::data[i] = space + i * n; 00053 Base::num_rows = m; 00054 Base::num_cols = n; 00055 } 00056 00057 //: Destroy this vnl_matrix_fixed_ref after detaching from the space 00058 // supplied to the constructor. 00059 ~vnl_matrix_fixed_ref() { 00060 // Prevent base dtor from releasing our memory 00061 Base::data[0] = 0; 00062 Base::data = 0; 00063 } 00064 00065 //: Copy a vnl_matrix into our space. Will cause an assertion 00066 // failure (i.e. abort) if the rhs is not exactly the same size. 00067 vnl_matrix_fixed_ref<T, m, n>& operator=(const vnl_matrix<T>& rhs) { 00068 assert(rhs.rows() == m && rhs.columns() == n); 00069 memcpy(data[0], rhs.data_block(), m*n*sizeof(T)); 00070 return *this; 00071 } 00072 00073 //: Resizing a vnl_matrix_ref fails. 00074 bool resize (unsigned int, unsigned int) { return 0; } 00075 00076 private: 00077 // Private operator new because deleting a pointer to 00078 // one of these through a baseclass pointer will attempt 00079 // to free this in-class memory. 00080 // Therefore disallow newing of these -- if you're paying for 00081 // one malloc, you can afford three. 00082 00083 // New operator restored to avoid problems constructing STL containers 00084 // - capes Nov 99 00085 00086 // You can't assign one of these from a matrix, cos' you don't have any space 00087 vnl_matrix_fixed_ref(const vnl_matrix<T>&) {} 00088 vnl_matrix_fixed_ref(const vnl_matrix_fixed_ref<T,m,n>&) {} 00089 }; 00090 00091 #endif // vnl_matrix_fixed_ref_h_