00001 // This is mul/mbl/mbl_data_array_ptr_wrapper.txx 00002 #ifndef mbl_data_array_ptr_wrapper_txx_ 00003 #define mbl_data_array_ptr_wrapper_txx_ 00004 //: 00005 // \file 00006 00007 #include "mbl_data_array_ptr_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_ptr_wrapper<T>::mbl_data_array_ptr_wrapper() 00016 : data_(0),n_(0),index_(0) 00017 { 00018 } 00019 00020 //: Constructor 00021 template<class T> 00022 mbl_data_array_ptr_wrapper<T>::mbl_data_array_ptr_wrapper(const T*const* 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_ptr_wrapper<T>::mbl_data_array_ptr_wrapper(const vcl_vector<const 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[0], data.size()); 00039 } 00040 00041 00042 //: Initialise to return elements from data[i] 00043 template<class T> 00044 void mbl_data_array_ptr_wrapper<T>::set(const T*const* data, unsigned long n) 00045 { 00046 assert (n != ((unsigned long)-1)); // a common mistake 00047 data_ = data; 00048 n_ = n; 00049 index_ = 0; 00050 } 00051 00052 //: Default destructor 00053 template<class T> 00054 mbl_data_array_ptr_wrapper<T>::~mbl_data_array_ptr_wrapper() 00055 { 00056 } 00057 00058 //: Number of objects available 00059 template<class T> 00060 unsigned long mbl_data_array_ptr_wrapper<T>::size() const 00061 { 00062 return n_; 00063 } 00064 00065 //: Reset so that current() returns first object 00066 template<class T> 00067 void mbl_data_array_ptr_wrapper<T>::reset() 00068 { 00069 index_=0; 00070 } 00071 00072 //: Return current object 00073 template<class T> 00074 const T& mbl_data_array_ptr_wrapper<T>::current() 00075 { 00076 return *data_[index_]; 00077 } 00078 00079 //: Move to next object, returning true if is valid 00080 template<class T> 00081 bool mbl_data_array_ptr_wrapper<T>::next() 00082 { 00083 return ++index_<n_; 00084 } 00085 00086 //: Return current index 00087 template<class T> 00088 unsigned long mbl_data_array_ptr_wrapper<T>::index() const 00089 { 00090 return index_; 00091 } 00092 00093 00094 //: Create copy on heap and return base pointer 00095 template<class T> 00096 mbl_data_wrapper< T >* mbl_data_array_ptr_wrapper<T>::clone() const 00097 { 00098 return new mbl_data_array_ptr_wrapper<T>(*this); 00099 } 00100 00101 //: Move to element n 00102 // First example has index 0 00103 template<class T> 00104 void mbl_data_array_ptr_wrapper<T>::set_index(unsigned long n) 00105 { 00106 assert(n != ((unsigned)-1)); 00107 if (n>=n_) 00108 { 00109 vcl_cerr<<"mbl_data_array_ptr_wrapper<T>::set_index(n) :\n" 00110 <<" n = "<<n<<" not in range 0<=n<"<<size()<<vcl_endl; 00111 vcl_abort(); 00112 } 00113 00114 index_=n; 00115 } 00116 00117 template <class T> 00118 bool mbl_data_array_ptr_wrapper<T>::is_class(vcl_string const& s) const 00119 { 00120 return s==is_a(); // no ref to parent's is_class() since that is pure virtual 00121 } 00122 00123 00124 #define MBL_DATA_ARRAY_PTR_WRAPPER_INSTANTIATE(T) \ 00125 VCL_DEFINE_SPECIALIZATION vcl_string mbl_data_array_ptr_wrapper<T >::is_a() const \ 00126 { return vcl_string("mbl_data_array_ptr_wrapper<" #T ">"); } \ 00127 template class mbl_data_array_ptr_wrapper< T > 00128 00129 #endif // mbl_data_array_ptr_wrapper_txx_