Go to the documentation of this file.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