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