00001 // This is mul/mbl/mbl_data_array_wrapper.txx 00002 #ifndef mbl_data_array_wrapper_txx_ 00003 #define mbl_data_array_wrapper_txx_ 00004 //: 00005 // \file 00006 00007 #include "mbl_data_array_wrapper.h" 00008 00009 #include <vcl_iostream.h> 00010 #include <vcl_cstdlib.h> 00011 #include <vcl_cassert.h> 00012 00013 //: Default constructor 00014 template<class T> 00015 mbl_data_array_wrapper<T>::mbl_data_array_wrapper() 00016 : data_(0),n_(0),index_(0) 00017 { 00018 } 00019 00020 //: Constructor 00021 template<class T> 00022 mbl_data_array_wrapper<T>::mbl_data_array_wrapper(const T* data, unsigned long n) 00023 { 00024 set(data,n); 00025 } 00026 00027 //: Constructor 00028 // Sets up object to wrap a vcl_vector. 00029 // The data must be kept in scope, this does not take a copy. 00030 template<class T> 00031 mbl_data_array_wrapper<T>::mbl_data_array_wrapper(const vcl_vector<T > &data) 00032 { 00033 // There is nothing in the STL standard that says that vector<> has 00034 // to store its data in a contiguous memory block. However, most 00035 // implementations do store data this way. 00036 // Check this assumption holds. 00037 assert(data.size() == 0 || &data[data.size() - 1] + 1 == &data[0] + data.size()); 00038 set(data.empty()?0:&data[0], data.size()); 00039 } 00040 00041 //: Copy Constructor 00042 // The copy will point to the same data as the original. 00043 // The data must be kept in scope, this does not take a copy. 00044 template <class T> 00045 mbl_data_array_wrapper<T>::mbl_data_array_wrapper(const mbl_data_array_wrapper<T > &orig) 00046 : mbl_data_wrapper<T>() 00047 { 00048 set(orig.data_, orig.size()); 00049 } 00050 00051 //: Initialise to return elements from data[i] 00052 template<class T> 00053 void mbl_data_array_wrapper<T>::set(const T* data, unsigned long n) 00054 { 00055 assert (n != ((unsigned long)-1)); // a common mistake 00056 data_ = data; 00057 n_ = n; 00058 index_ = 0; 00059 } 00060 00061 //: Default destructor 00062 template<class T> 00063 mbl_data_array_wrapper<T>::~mbl_data_array_wrapper() 00064 { 00065 } 00066 00067 //: Number of objects available 00068 template<class T> 00069 unsigned long mbl_data_array_wrapper<T>::size() const 00070 { 00071 return n_; 00072 } 00073 00074 //: Reset so that current() returns first object 00075 template<class T> 00076 void mbl_data_array_wrapper<T>::reset() 00077 { 00078 index_=0; 00079 } 00080 00081 //: Return current object 00082 template<class T> 00083 const T& mbl_data_array_wrapper<T>::current() 00084 { 00085 return data_[index_]; 00086 } 00087 00088 //: Move to next object, returning true if is valid 00089 template<class T> 00090 bool mbl_data_array_wrapper<T>::next() 00091 { 00092 index_++; 00093 return index_<n_; 00094 } 00095 00096 //: Return current index 00097 template<class T> 00098 unsigned long mbl_data_array_wrapper<T>::index() const 00099 { 00100 return index_; 00101 } 00102 00103 //: Create copy on heap and return base pointer 00104 template<class T> 00105 mbl_data_wrapper< T >* mbl_data_array_wrapper<T>::clone() const 00106 { 00107 return new mbl_data_array_wrapper<T>(*this); 00108 } 00109 00110 //: Move to element n 00111 // First example has index 0 00112 template<class T> 00113 void mbl_data_array_wrapper<T>::set_index(unsigned long n) 00114 { 00115 assert(n != ((unsigned)-1)); 00116 if (n>=n_) 00117 { 00118 vcl_cerr<<"mbl_data_array_wrapper<T>::set_index(n) :\n" 00119 <<" n = "<<n<<" not in range 0<=n<"<<size()<<vcl_endl; 00120 vcl_abort(); 00121 } 00122 00123 index_=n; 00124 } 00125 00126 template <class T> 00127 bool mbl_data_array_wrapper<T>::is_class(vcl_string const& s) const 00128 { 00129 return s==is_a(); // no ref to parent's is_class() since that is pure virtual 00130 } 00131 00132 00133 #define MBL_DATA_ARRAY_WRAPPER_INSTANTIATE(T) \ 00134 VCL_DEFINE_SPECIALIZATION vcl_string mbl_data_array_wrapper<T >::is_a() const \ 00135 { return vcl_string("mbl_data_array_wrapper<" #T ">"); } \ 00136 template class mbl_data_array_wrapper< T > 00137 00138 #endif // mbl_data_array_wrapper_txx_