00001 // This is core/vnl/vnl_matrix_ref.h 00002 #ifndef vnl_matrix_ref_h_ 00003 #define vnl_matrix_ref_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief vnl_matrix reference to user-supplied storage. 00010 // \author Andrew W. Fitzgibbon, Oxford RRG 00011 // \date 04 Aug 96 00012 // 00013 // \verbatim 00014 // Modifications 00015 // Documentation updated by Ian Scott 12 Mar 2000 00016 // Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line 00017 // \endverbatim 00018 // 00019 //----------------------------------------------------------------------------- 00020 00021 #include <vnl/vnl_matrix.h> 00022 00023 //: vnl_matrix reference to user-supplied storage 00024 // vnl_matrix_ref is a vnl_matrix for which the data space has been 00025 // supplied externally. This is useful for two main tasks: 00026 // (a) Treating some row-based "C" matrix as a vnl_matrix in order to 00027 // perform vnl_matrix operations on it. 00028 // 00029 // This is a dangerous class. I believe that I've covered all the bases, but 00030 // it's really only intended for interfacing with the Fortran routines. 00031 // 00032 // The big warning is that returning a vnl_matrix_ref pointer will free non-heap 00033 // memory if deleted through a vnl_matrix pointer. This should be 00034 // very difficult though, as vnl_matrix_ref objects may not be constructed using 00035 // operator new, and are therefore unlikely to be the unwitting subject 00036 // of an operator delete. 00037 template <class T> 00038 class vnl_matrix_ref : public vnl_matrix<T> 00039 { 00040 typedef vnl_matrix<T> Base; 00041 00042 public: 00043 // Constructors/Destructors-------------------------------------------------- 00044 vnl_matrix_ref(unsigned int m, unsigned int n, T *datablck) { 00045 Base::data = vnl_c_vector<T>::allocate_Tptr(m); 00046 for (unsigned int i = 0; i < m; ++i) 00047 Base::data[i] = datablck + i * n; 00048 Base::num_rows = m; 00049 Base::num_cols = n; 00050 #if VCL_HAS_SLICED_DESTRUCTOR_BUG 00051 this->vnl_matrix_own_data = 0; 00052 #endif 00053 } 00054 00055 vnl_matrix_ref(vnl_matrix_ref<T> const & other) : vnl_matrix<T>() { 00056 Base::data = vnl_c_vector<T>::allocate_Tptr(other.rows()); 00057 for (unsigned int i = 0; i < other.rows(); ++i) 00058 Base::data[i] = const_cast<T*>(other.data_block()) + i * other.cols(); 00059 Base::num_rows = other.rows(); 00060 Base::num_cols = other.cols(); 00061 #if VCL_HAS_SLICED_DESTRUCTOR_BUG 00062 this->vnl_matrix_own_data = 0; 00063 #endif 00064 } 00065 00066 ~vnl_matrix_ref() { 00067 Base::data[0] = 0; // Prevent base dtor from releasing our memory 00068 } 00069 00070 //: Reference to self to make non-const temporaries. 00071 // This is intended for passing vnl_matrix_fixed objects to 00072 // functions that expect non-const vnl_matrix references: 00073 // \code 00074 // void mutator( vnl_matrix<double>& ); 00075 // ... 00076 // vnl_matrix_fixed<double,5,3> my_m; 00077 // mutator( m ); // Both these fail because the temporary vnl_matrix_ref 00078 // mutator( m.as_ref() ); // cannot be bound to the non-const reference 00079 // mutator( m.as_ref().non_const() ); // works 00080 // \endcode 00081 // \attention Use this only to pass the reference to a 00082 // function. Otherwise, the underlying object will be destructed and 00083 // you'll be left with undefined behaviour. 00084 vnl_matrix_ref& non_const() { return *this; } 00085 00086 #if 0 00087 private: 00088 // Private operator new because deleting a pointer to 00089 // one of these through a baseclass pointer will attempt 00090 // to free this in-class memory. 00091 // Therefore disallow newing of these -- if you're paying for 00092 // one malloc, you can afford three. 00093 // fsm: This was wrong for two reasons: 00094 // 1. operator new may not return a null pointer. 00095 // 2. it should be enabled for compilers that need it, 00096 // not disabled for compilers that don't need it. 00097 #include <vcl_new.h> 00098 void* operator new(vcl_size_t) { return 0; } 00099 #endif 00100 00101 private: 00102 //: Resizing is disallowed 00103 bool resize (unsigned int, unsigned int) { return false; } 00104 //: Resizing is disallowed 00105 bool make_size (unsigned int, unsigned int) { return false; } 00106 //: Resizing is disallowed 00107 bool set_size (unsigned int, unsigned int) { return false; } 00108 00109 //: Copy constructor from vnl_matrix<T> is disallowed 00110 // (because it would create a non-const alias to the matrix) 00111 vnl_matrix_ref(vnl_matrix<T> const &) {} 00112 }; 00113 00114 #endif // vnl_matrix_ref_h_