00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef mrpt_matrix_iterators_H
00029 #define mrpt_matrix_iterators_H
00030
00031 #include <mrpt/math/math_frwds.h>
00032
00033 #include <algorithm>
00034 #include <iterator>
00035
00036
00037 #define DECLARE_MRPT_MATRIX_ITERATORS \
00038 \
00039 typedef mrpt::math::detail::CGenericMatrixIterator<mrpt_autotype> iterator; \
00040 typedef mrpt::math::detail::CGenericMatrixConstIterator<mrpt_autotype> const_iterator; \
00041 typedef std::reverse_iterator<iterator> reverse_iterator; \
00042 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; \
00043 inline iterator begin() { return iterator(*this,0,0); } \
00044 inline iterator end() { return iterator(*this,mrpt_autotype::getRowCount(),0); } \
00045 inline const_iterator begin() const { return const_iterator(*this,0,0); } \
00046 inline const_iterator end() const { return const_iterator(*this,mrpt_autotype::getRowCount(),0); } \
00047 inline reverse_iterator rbegin() { return reverse_iterator(end()); } \
00048 inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } \
00049 inline reverse_iterator rend() { return reverse_iterator(begin()); } \
00050 inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } \
00051 \
00052
00053
00054 namespace mrpt {
00055 namespace math {
00056 namespace detail {
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 template <class MATRIXTYPE>
00068 struct CGenericMatrixIterator : public std::iterator<std::random_access_iterator_tag,typename MATRIXTYPE::value_type>
00069 {
00070 private:
00071 typedef std::iterator<std::random_access_iterator_tag,typename MATRIXTYPE::value_type> iterator_base;
00072 MATRIXTYPE *m_matrix;
00073 size_t m_cur_row, m_cur_col;
00074 typedef typename MATRIXTYPE::value_type T;
00075
00076 inline void check_limits(bool allow_end = false) const
00077 {
00078 #ifdef _DEBUG
00079 ASSERTMSG_(m_matrix!=NULL,"non initialized iterator");
00080 if (m_cur_col>=m_matrix->getColCount()) THROW_EXCEPTION("Column index out of range in iterator.")
00081 if (!allow_end)
00082 {
00083 if (m_cur_row>=m_matrix->getRowCount()) { THROW_EXCEPTION("Row index out of range in iterator.") }
00084 else if (m_cur_row>m_matrix->getRowCount()) THROW_EXCEPTION("Row index out of range in iterator.")
00085 }
00086 #endif
00087 }
00088
00089 public:
00090 inline bool operator <(const CGenericMatrixIterator<MATRIXTYPE> &it2) const
00091 {
00092 if (m_cur_row<m_cur_col) return true;
00093 else if (m_cur_row==it2.m_cur_row)
00094 return m_cur_col<it2.m_cur_col;
00095 else return false;
00096 }
00097 inline bool operator >(const CGenericMatrixIterator<MATRIXTYPE> &it2) const
00098 {
00099 if (m_cur_row<m_cur_col) return false;
00100 else if (m_cur_row==it2.m_cur_row)
00101 return m_cur_col>it2.m_cur_col;
00102 else return true;
00103 }
00104
00105 inline size_t getCol() const { return m_cur_col; }
00106 inline size_t getRow() const { return m_cur_row; }
00107
00108 inline CGenericMatrixIterator() : m_matrix(NULL),m_cur_row(0),m_cur_col(0) { }
00109 inline CGenericMatrixIterator(MATRIXTYPE &obj, size_t start_row, size_t start_col)
00110 : m_matrix(&obj),m_cur_row(start_row),m_cur_col(start_col)
00111 {
00112 check_limits(true);
00113 }
00114 inline typename MATRIXTYPE::reference operator*() const {
00115 check_limits();
00116 return m_matrix->get_unsafe(m_cur_row,m_cur_col);
00117 }
00118 inline CGenericMatrixIterator<MATRIXTYPE> &operator++() {
00119 check_limits();
00120 if (++m_cur_col>=m_matrix->getColCount()) { m_cur_col=0; ++m_cur_row; }
00121 return *this;
00122 }
00123 inline CGenericMatrixIterator<MATRIXTYPE> operator++(int) {
00124 CGenericMatrixIterator<MATRIXTYPE> it=*this;
00125 ++*this;
00126 return it;
00127 }
00128 inline CGenericMatrixIterator<MATRIXTYPE> &operator--() {
00129 if (!m_cur_col) {
00130 m_cur_col = m_matrix->getColCount()-1;
00131 --m_cur_row;
00132 }
00133 else --m_cur_col;
00134 check_limits();
00135 return *this;
00136 }
00137 inline CGenericMatrixIterator<MATRIXTYPE> operator--(int) {
00138 CGenericMatrixIterator<MATRIXTYPE> it=*this;
00139 --*this;
00140 return it;
00141 }
00142 CGenericMatrixIterator<MATRIXTYPE> &operator+=(typename iterator_base::difference_type off) {
00143 const size_t N = m_matrix->getColCount();
00144 if (off>=0)
00145 {
00146 m_cur_col+=off;
00147 m_cur_row+=m_cur_col/N;
00148 m_cur_col=m_cur_col%N;
00149 }
00150 else
00151 {
00152 const size_t idx=(m_cur_col+(m_cur_row*N)) + off;
00153 m_cur_row = idx/N;
00154 m_cur_col = idx%N;
00155 }
00156 check_limits(true);
00157 return *this;
00158 }
00159 inline CGenericMatrixIterator<MATRIXTYPE> operator+(typename iterator_base::difference_type off) const {
00160 CGenericMatrixIterator<MATRIXTYPE> it=*this;
00161 it+=off;
00162 return it;
00163 }
00164 inline CGenericMatrixIterator<MATRIXTYPE> &operator-=(typename iterator_base::difference_type off) {
00165 return (*this)+=(-off);
00166 }
00167 inline CGenericMatrixIterator<MATRIXTYPE> operator-(typename iterator_base::difference_type off) const {
00168 CGenericMatrixIterator<MATRIXTYPE> it=*this;
00169 it-=off;
00170 return it;
00171 }
00172 typename iterator_base::difference_type operator-(const CGenericMatrixIterator<MATRIXTYPE> &it) const {
00173 return m_matrix->getColCount()*( m_cur_row-it.m_cur_row ) + ( m_cur_col-it.m_cur_col);
00174 }
00175 inline typename MATRIXTYPE::reference operator[](typename iterator_base::difference_type off) const {
00176 const size_t incr_row = off / m_matrix->getColCount();
00177 const size_t incr_col = off % m_matrix->getColCount();
00178 return (*m_matrix)(m_cur_row+incr_row,m_cur_col+incr_col);
00179 }
00180 inline bool operator==(const CGenericMatrixIterator<MATRIXTYPE> &it) const {
00181 return (m_cur_col==it.m_cur_col)&&(m_cur_row==it.m_cur_row)&&(m_matrix==it.m_matrix);
00182 }
00183 inline bool operator!=(const CGenericMatrixIterator<MATRIXTYPE> &it) const {
00184 return !(operator==(it));
00185 }
00186 };
00187
00188
00189
00190
00191
00192
00193
00194 template <class MATRIXTYPE>
00195 struct CGenericMatrixConstIterator : public std::iterator<std::random_access_iterator_tag,typename MATRIXTYPE::value_type>
00196 {
00197 private:
00198 typedef std::iterator<std::random_access_iterator_tag,typename MATRIXTYPE::value_type> iterator_base;
00199 const MATRIXTYPE *m_matrix;
00200 size_t m_cur_row, m_cur_col;
00201 typedef typename MATRIXTYPE::value_type T;
00202
00203 inline void check_limits(bool allow_end = false) const
00204 {
00205 #ifdef _DEBUG
00206 ASSERTMSG_(m_matrix!=NULL,"non initialized iterator");
00207 if (m_cur_col>=m_matrix->getColCount()) THROW_EXCEPTION("Column index out of range in iterator.")
00208 if (!allow_end)
00209 {
00210 if (m_cur_row>=m_matrix->getRowCount()) { THROW_EXCEPTION("Row index out of range in iterator.") }
00211 else if (m_cur_row>m_matrix->getRowCount()) THROW_EXCEPTION("Row index out of range in iterator.")
00212 }
00213 #endif
00214 }
00215
00216 public:
00217 inline bool operator <(const CGenericMatrixConstIterator<MATRIXTYPE> &it2) const
00218 {
00219 if (m_cur_row<m_cur_col) return true;
00220 else if (m_cur_row==it2.m_cur_row)
00221 return m_cur_col<it2.m_cur_col;
00222 else return false;
00223 }
00224 inline bool operator >(const CGenericMatrixConstIterator<MATRIXTYPE> &it2) const
00225 {
00226 if (m_cur_row<m_cur_col) return false;
00227 else if (m_cur_row==it2.m_cur_row)
00228 return m_cur_col>it2.m_cur_col;
00229 else return true;
00230 }
00231
00232 inline size_t getCol() const { return m_cur_col; }
00233 inline size_t getRow() const { return m_cur_row; }
00234
00235 inline CGenericMatrixConstIterator() : m_matrix(NULL),m_cur_row(0),m_cur_col(0) { }
00236 inline CGenericMatrixConstIterator(const MATRIXTYPE &obj,size_t start_row, size_t start_col)
00237 : m_matrix(&obj),m_cur_row(start_row),m_cur_col(start_col)
00238 {
00239 check_limits(true);
00240 }
00241 inline typename MATRIXTYPE::const_reference operator*() const {
00242 check_limits();
00243 return m_matrix->get_unsafe(m_cur_row,m_cur_col);
00244 }
00245 inline CGenericMatrixConstIterator<MATRIXTYPE> &operator++() {
00246 check_limits();
00247 if (++m_cur_col>=m_matrix->getColCount()) { m_cur_col=0; ++m_cur_row; }
00248 return *this;
00249 }
00250 inline CGenericMatrixConstIterator<MATRIXTYPE> operator++(int) {
00251 CGenericMatrixConstIterator<MATRIXTYPE> it=*this;
00252 ++*this;
00253 return it;
00254 }
00255 inline CGenericMatrixConstIterator<MATRIXTYPE> &operator--() {
00256 if (!m_cur_col) {
00257 m_cur_col = m_matrix->getColCount()-1;
00258 --m_cur_row;
00259 }
00260 else --m_cur_col;
00261 check_limits();
00262 return *this;
00263 }
00264 inline CGenericMatrixConstIterator<MATRIXTYPE> operator--(int) {
00265 CGenericMatrixConstIterator<MATRIXTYPE> it=*this;
00266 --*this;
00267 return it;
00268 }
00269 CGenericMatrixConstIterator<MATRIXTYPE> &operator+=(typename iterator_base::difference_type off) {
00270 const size_t N = m_matrix->getColCount();
00271 if (off>=0)
00272 {
00273 m_cur_col+=off;
00274 m_cur_row+=m_cur_col/N;
00275 m_cur_col=m_cur_col%N;
00276 }
00277 else
00278 {
00279 const size_t idx=(m_cur_col+m_cur_row*N) + off;
00280 m_cur_row = idx/N;
00281 m_cur_col = idx%N;
00282 }
00283 check_limits(true);
00284 return *this;
00285 }
00286 inline CGenericMatrixConstIterator<MATRIXTYPE> operator+(typename iterator_base::difference_type off) const {
00287 CGenericMatrixConstIterator<MATRIXTYPE> it=*this;
00288 it+=off;
00289 return it;
00290 }
00291 CGenericMatrixConstIterator<MATRIXTYPE> &operator-=(typename iterator_base::difference_type off) {
00292 return (*this)+=(-off);
00293 }
00294 inline CGenericMatrixConstIterator<MATRIXTYPE> operator-(typename iterator_base::difference_type off) const {
00295 CGenericMatrixConstIterator<MATRIXTYPE> it=*this;
00296 it-=off;
00297 return it;
00298 }
00299 typename iterator_base::difference_type operator-(const CGenericMatrixConstIterator<MATRIXTYPE> &it) const {
00300 return m_matrix->getColCount()*( m_cur_row-it.m_cur_row ) + ( m_cur_col-it.m_cur_col);
00301 }
00302 inline typename MATRIXTYPE::const_reference operator[](typename iterator_base::difference_type off) const {
00303 const size_t incr_row = off / m_matrix->getColCount();
00304 const size_t incr_col = off % m_matrix->getColCount();
00305 return (*m_matrix)(m_cur_row+incr_row,m_cur_col+incr_col);
00306 }
00307 inline bool operator==(const CGenericMatrixConstIterator<MATRIXTYPE> &it) const {
00308 return (m_cur_col==it.m_cur_col)&&(m_cur_row==it.m_cur_row)&&(m_matrix==it.m_matrix);
00309 }
00310 inline bool operator!=(const CGenericMatrixConstIterator<MATRIXTYPE> &it) const {
00311 return !(operator==(it));
00312 }
00313 };
00314
00315
00316
00317
00318 }
00319 }
00320 }
00321
00322
00323 #endif