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