core/vnl/vnl_matrix_ref.h
Go to the documentation of this file.
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_