00001 // This is core/vnl/vnl_vector_ref.h 00002 #ifndef vnl_vector_ref_h_ 00003 #define vnl_vector_ref_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief vnl_vector using user-supplied storage 00010 // \author Andrew W. Fitzgibbon, Oxford RRG 00011 // \date 04 Aug 96 00012 // 00013 // \verbatim 00014 // Modifications 00015 // LSB (Manchester) 19/03/2001: Tidied up the documentation 00016 // Peter Vanroose 27-Jun-2003 Removed .txx as all methods are inlined 00017 // \endverbatim 00018 //----------------------------------------------------------------------------- 00019 00020 #include <vnl/vnl_vector.h> 00021 00022 //: vnl_vector using user-supplied storage 00023 // vnl_vector for which the data space has 00024 // been supplied externally. 00025 export template <class T> 00026 class vnl_vector_ref : public vnl_vector<T> 00027 { 00028 public: 00029 typedef vnl_vector<T> Base; 00030 00031 //: Constructor 00032 // Do \e not call anything else than the default constructor of vnl_vector<T> 00033 vnl_vector_ref(unsigned n, T *space) : vnl_vector<T>() { 00034 Base::data = space; 00035 Base::num_elmts = n; 00036 #if VCL_HAS_SLICED_DESTRUCTOR_BUG 00037 this->vnl_vector_own_data = 0; 00038 #endif 00039 } 00040 00041 //: Copy constructor 00042 // Do \e not call anything else than the default constructor of vnl_vector<T> 00043 // (That is why the default copy constructor is \e not good.) 00044 vnl_vector_ref(vnl_vector_ref<T> const& v) : vnl_vector<T>() { 00045 Base::data = const_cast<T*>(v.data_block()); // const incorrect! 00046 Base::num_elmts = v.size(); 00047 #if VCL_HAS_SLICED_DESTRUCTOR_BUG 00048 this->vnl_vector_own_data = 0; 00049 #endif 00050 } 00051 00052 //: Destructor 00053 // Prevents base destructor from releasing memory we don't own 00054 ~vnl_vector_ref() { 00055 Base::data = 0; 00056 } 00057 00058 //: Reference to self to make non-const temporaries. 00059 // This is intended for passing vnl_vector_fixed objects to 00060 // functions that expect non-const vnl_vector references: 00061 // \code 00062 // void mutator( vnl_vector<double>& ); 00063 // ... 00064 // vnl_vector_fixed<double,4> my_v; 00065 // mutator( v ); // Both these fail because the temporary vnl_vector_ref 00066 // mutator( v.as_ref() ); // cannot be bound to the non-const reference 00067 // mutator( v.as_ref().non_const() ); // works 00068 // \endcode 00069 // \attention Use this only to pass the reference to a 00070 // function. Otherwise, the underlying object will be destructed and 00071 // you'll be left with undefined behaviour. 00072 vnl_vector_ref& non_const() { return *this; } 00073 00074 private: 00075 00076 //: Copy constructor from vnl_vector<T> is disallowed: 00077 vnl_vector_ref(vnl_vector<T> const&) {} 00078 00079 #if 0 // NOW COMMENTED OUT - PVR, may 97 00080 // Private operator new because deleting a pointer to 00081 // one of these through a baseclass pointer will attempt 00082 // to free the referenced memory. 00083 // Therefore disallow newing of these -- if you're paying for 00084 // one malloc, you can afford two. 00085 void* operator new(vcl_size_t) { return 0; } 00086 00087 public: 00088 // Privatizing other new means we must offer placement new for STL 00089 void* operator new(vcl_size_t, void* space) { return space; } 00090 #endif 00091 }; 00092 00093 //: Create a reference vector with part of an existing vector. 00094 template <class T> 00095 inline const vnl_vector_ref<T> vnl_vector_ref_extract(const vnl_vector <T> &v, unsigned start, unsigned len) 00096 { 00097 return vnl_vector_ref<T>(len, const_cast<T *>(v.data_block()+start)); 00098 } 00099 00100 //: Create a reference vector with part of an existing vector. 00101 template <class T> 00102 inline vnl_vector_ref<T> vnl_vector_ref_extract(vnl_vector <T> &v, unsigned start, unsigned len) 00103 { 00104 return vnl_vector_ref<T>(len, v.data_block()+start); 00105 } 00106 00107 00108 #endif // vnl_vector_ref_h_