00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #ifdef _MSC_VER
00031 # pragma once
00032 # pragma warning( push )
00033 # pragma warning( disable : 4786 )
00034 #endif // _MSC_VER
00035
00036 #ifndef _EXMAT_ITERATORS_H
00037 #define _EXMAT_ITERATORS_H
00038
00039 #include <iterator>
00040 #include "PlatformSpec.h"
00041
00042 namespace exmat {
00043
00046 template< typename Iterator_Type, typename Value_Type,
00047 typename Reference_Type, typename Pointer_Type, typename Difference_Type>
00048 class stride_iterator
00049 {
00050 public:
00051 typedef std::random_access_iterator_tag iterator_category;
00052 typedef Iterator_Type iterator_type;
00053 typedef Value_Type value_type;
00054 typedef Reference_Type reference;
00055 typedef Pointer_Type pointer;
00056 typedef Difference_Type difference_type;
00057 typedef stride_iterator<Iterator_Type,Value_Type,
00058 Reference_Type,Pointer_Type,Difference_Type> self_type;
00059
00060 EXMAT_INLINE2 stride_iterator()
00061 : current_(0), stride_(0) {}
00062 EXMAT_INLINE2 stride_iterator(iterator_type current)
00063 : current_(current), stride_(1) {}
00064 EXMAT_INLINE2 stride_iterator(iterator_type current, difference_type stride)
00065 : current_(current), stride_(stride) {}
00066 EXMAT_INLINE2 stride_iterator(const self_type& rhs)
00067 : current_(rhs.current()),stride_(rhs.stride()) {}
00068 EXMAT_INLINE2 stride_iterator& operator=(const self_type& rhs) {
00069 current_ = rhs.current();
00070 stride_ = rhs.stride();
00071 return *this;
00072 }
00073
00074 EXMAT_INLINE2 reference operator*() const {
00075 return *current_;
00076 }
00077 EXMAT_INLINE2 pointer operator->() const {
00078 return current_;
00079 }
00080 EXMAT_INLINE2 reference operator[](difference_type n) const {
00081 return current_[n * stride_];
00082 }
00083
00084 EXMAT_INLINE2 stride_iterator& operator++() {
00085 current_ += stride_;
00086 return *this;
00087 }
00088 EXMAT_INLINE2 const stride_iterator operator++(int) {
00089 stride_iterator tmp = *this;
00090 ++*this; return tmp;
00091 }
00092 EXMAT_INLINE2 stride_iterator& operator--() {
00093 current_ -= stride_;
00094 return *this;
00095 }
00096 EXMAT_INLINE2 const stride_iterator operator--(int) {
00097 stride_iterator tmp = *this;
00098 --*this; return tmp;
00099 }
00100 EXMAT_INLINE2 stride_iterator operator+(difference_type n) {
00101 return stride_iterator(current_ + n * stride_, stride_);
00102 }
00103 EXMAT_INLINE2 const stride_iterator operator+(difference_type n) const {
00104 return stride_iterator(current_ + n * stride_, stride_);
00105 }
00106 EXMAT_INLINE2 stride_iterator& operator+=(difference_type n) {
00107 current_ += n * stride_;
00108 return *this;
00109 }
00110 EXMAT_INLINE2 stride_iterator operator-(difference_type n) {
00111 return stride_iterator(current_ - n * stride_, stride_);
00112 }
00113 EXMAT_INLINE2 const stride_iterator operator-(difference_type n) const {
00114 return stride_iterator(current_ - n * stride_, stride_);
00115 }
00116 EXMAT_INLINE2 stride_iterator& operator-=(difference_type n) {
00117 current_ -= n * stride_;
00118 return *this;
00119 }
00120
00121 EXMAT_INLINE2 difference_type operator-(const stride_iterator& itr) const {
00122 return (current_ - itr.current_)/stride_;
00123 }
00124
00125 EXMAT_INLINE2 iterator_type current() const {
00126 return current_;
00127 }
00128
00129 EXMAT_INLINE2 difference_type stride() const {
00130 return stride_;
00131 }
00132
00133 private:
00134 iterator_type current_;
00135 const difference_type stride_;
00136 };
00137
00138 template<class Iter, class Val, class Ref, class Ptr, class Diff> EXMAT_INLINE2
00139 const stride_iterator<Iter,Val,Ref,Ptr,Diff> operator+(
00140 Diff n, const stride_iterator<Iter,Val,Ref,Ptr,Diff> itr)
00141 {
00142 return itr + n;
00143 }
00144
00145 template<class Iter, class Val, class Ref, class Ptr, class Diff> EXMAT_INLINE2
00146 bool operator<( const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr1,
00147 const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr2)
00148 {
00149 return itr1.operator->() < itr2.operator->();
00150 }
00151 template<class Iter, class Val, class Ref, class Ptr, class Diff> EXMAT_INLINE2
00152 bool operator<=(const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr1,
00153 const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr2)
00154 {
00155 return itr1.operator->() <= itr2.operator->();
00156 }
00157 template<class Iter, class Val, class Ref, class Ptr, class Diff> EXMAT_INLINE2
00158 bool operator>( const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr1,
00159 const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr2)
00160 {
00161 return itr1.operator->() > itr2.operator->();
00162 }
00163 template<class Iter, class Val, class Ref, class Ptr, class Diff> EXMAT_INLINE2
00164 bool operator>=(const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr1,
00165 const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr2)
00166 {
00167 return itr1.operator->() >= itr2.operator->();
00168 }
00169 template<class Iter, class Val, class Ref, class Ptr, class Diff> EXMAT_INLINE2
00170 bool operator==(const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr1,
00171 const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr2)
00172 {
00173 return itr1.operator->() == itr2.operator->();
00174 }
00175 template<class Iter, class Val, class Ref, class Ptr, class Diff> EXMAT_INLINE2
00176 bool operator!=(const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr1,
00177 const stride_iterator<Iter,Val,Ref,Ptr,Diff>& itr2)
00178 {
00179 return itr1.operator->() != itr2.operator->();
00180 }
00181
00184 template<class MAT>
00185 class mat_iterator
00186 {
00187 public:
00188 typedef std::random_access_iterator_tag iterator_category;
00189 typedef typename MAT::value_type value_type;
00190 typedef typename MAT::reference reference;
00191 typedef value_type* pointer;
00192 typedef ptrdiff_t difference_type;
00193 typedef mat_iterator<MAT> self_type;
00194
00195 EXMAT_INLINE2 mat_iterator(MAT& m, size_t r, size_t c)
00196 : mat_(m), r_(r), c_(c) {}
00197
00198 EXMAT_INLINE2 reference operator*() const {
00199 return mat_.setAt(r_, c_);
00200 }
00201 EXMAT_INLINE2 pointer operator->() const {
00202 return &(mat_.setAt(r_, c_));
00203 }
00204
00205 EXMAT_INLINE2 mat_iterator& operator++() {
00206 c_ = ++c_ >= mat_.cols() ? 0 : c_;
00207 r_ = c_ == 0 ? r_+1 : r_;
00208 return *this;
00209 }
00210 EXMAT_INLINE2 const mat_iterator operator++(int) {
00211 mat_iterator tmp = *this;
00212 ++*this; return tmp;
00213 }
00214 EXMAT_INLINE2 mat_iterator& operator--() {
00215 size_t c = mat_.cols()-1;
00216 c_ = c_ == 0 ? c : c_-1;
00217 r_ = c_ == c ? r_-1 : r_;
00218 return *this;
00219 }
00220 EXMAT_INLINE2 const mat_iterator operator--(int) {
00221 mat_iterator tmp = *this;
00222 --*this; return tmp;
00223 }
00224 EXMAT_INLINE2 mat_iterator operator+(difference_type n) {
00225 size_t abspos = r_ * mat_.cols() + c_ + n;
00226 return mat_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00227 }
00228 EXMAT_INLINE2 const mat_iterator operator+(difference_type n) const {
00229 size_t abspos = r_ * mat_.cols() + c_ + n;
00230 return mat_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00231 }
00232 EXMAT_INLINE2 mat_iterator& operator+=(difference_type n) {
00233 size_t abspos = r_ * mat_.cols() + c_ + n;
00234 r_ = abspos/mat_.rows();
00235 c_ = abspos%mat_.cols();
00236 return *this;
00237 }
00238 EXMAT_INLINE2 mat_iterator operator-(difference_type n) {
00239 size_t abspos = r_ * mat_.cols() + c_ - n;
00240 return mat_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00241 }
00242 EXMAT_INLINE2 const mat_iterator operator-(difference_type n) const {
00243 size_t abspos = r_ * mat_.cols() + c_ - n;
00244 return mat_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00245 }
00246 EXMAT_INLINE2 mat_iterator& operator-=(difference_type n) {
00247 size_t abspos = r_ * mat_.cols() + c_ - n;
00248 r_ = abspos/mat_.rows();
00249 c_ = abspos%mat_.cols();
00250 return *this;
00251 }
00252
00253 EXMAT_INLINE2 difference_type operator-(const mat_iterator& itr) const {
00254 size_t abspos = r_ * mat_.cols() + c_;
00255 size_t abspos2 = itr.r_ * mat_.cols() + itr.c_;
00256 return abspos - abspos2;
00257 }
00258
00260 EXMAT_INLINE2 size_t row() const
00261 { return r_; }
00263 EXMAT_INLINE2 size_t col() const
00264 { return c_; }
00265
00267 EXMAT_INLINE2 size_t rows() const
00268 { return mat_.rows(); }
00270 EXMAT_INLINE2 size_t cols() const
00271 { return mat_.cols(); }
00272
00273 private:
00274 mutable MAT& mat_;
00275 size_t r_;
00276 size_t c_;
00277 };
00278
00279 template<class MAT, typename Diff>
00280 EXMAT_INLINE2 const mat_iterator<MAT>
00281 operator+(Diff n, const mat_iterator<MAT>& itr) {
00282 return itr + n;
00283 }
00284
00285 template<class MAT> EXMAT_INLINE2
00286 bool operator==(const mat_iterator<MAT>& itr1,
00287 const mat_iterator<MAT>& itr2)
00288 {
00289 return (itr1.row() * itr1.cols() + itr1.col()
00290 == itr2.row() * itr2.cols() + itr2.col());
00291 }
00292 template<class MAT> EXMAT_INLINE2
00293 bool operator!=(const mat_iterator<MAT>& itr1,
00294 const mat_iterator<MAT>& itr2)
00295 {
00296 return !(itr1 == itr2);
00297 }
00298 template<class MAT> EXMAT_INLINE2
00299 bool operator<( const mat_iterator<MAT>& itr1,
00300 const mat_iterator<MAT>& itr2)
00301 {
00302 return (itr1.row() * itr1.cols() + itr1.col()
00303 < itr2.row() * itr2.cols() + itr2.col());
00304 }
00305 template<class MAT> EXMAT_INLINE2
00306 bool operator<=(const mat_iterator<MAT>& itr1,
00307 const mat_iterator<MAT>& itr2)
00308 {
00309 return (itr1.row() * itr1.cols() + itr1.col()
00310 <= itr2.row() * itr2.cols() + itr2.col());
00311 }
00312 template<class MAT> EXMAT_INLINE2
00313 bool operator>( const mat_iterator<MAT>& itr1,
00314 const mat_iterator<MAT>& itr2)
00315 {
00316 return (itr1.row() * itr1.cols() + itr1.col()
00317 > itr2.row() * itr2.cols() + itr2.col());
00318 }
00319 template<class MAT> EXMAT_INLINE2
00320 bool operator>=(const mat_iterator<MAT>& itr1,
00321 const mat_iterator<MAT>& itr2)
00322 {
00323 return (itr1.row() * itr1.cols() + itr1.col()
00324 >= itr2.row() * itr2.cols() + itr2.col());
00325 }
00326
00328 template<class MAT>
00329 class const_mat_iterator
00330 {
00331 public:
00332 typedef std::random_access_iterator_tag iterator_category;
00333 typedef typename MAT::value_type value_type;
00334 typedef typename MAT::const_reference reference;
00335 typedef const value_type* pointer;
00336 typedef ptrdiff_t difference_type;
00337 typedef const_mat_iterator<MAT> self_type;
00338
00339 EXMAT_INLINE2 const_mat_iterator(MAT& m, size_t r, size_t c)
00340 : mat_(m), r_(r), c_(c) {}
00341
00342 EXMAT_INLINE2 reference operator*() const {
00343 return mat_.data[r_][c_];
00344 }
00345 EXMAT_INLINE2 pointer operator->() const {
00346 return &(mat_.data[r_][c_]);
00347 }
00348
00349 EXMAT_INLINE2 const_mat_iterator& operator++() {
00350 c_ = ++c_ >= mat_.cols() ? 0 : c_;
00351 r_ = c_ == 0 ? r_+1 : r_;
00352 return *this;
00353 }
00354 EXMAT_INLINE2 const const_mat_iterator operator++(int) {
00355 const_mat_iterator tmp = *this;
00356 ++*this; return tmp;
00357 }
00358 EXMAT_INLINE2 const_mat_iterator& operator--() {
00359 size_t c = mat_.cols()-1;
00360 c_ = c_ == 0 ? c : c_-1;
00361 r_ = c_ == c ? r_-1 : r_;
00362 return *this;
00363 }
00364 EXMAT_INLINE2 const const_mat_iterator operator--(int) {
00365 const_mat_iterator tmp = *this;
00366 --*this; return tmp;
00367 }
00368 EXMAT_INLINE2 const_mat_iterator operator+(difference_type n) {
00369 size_t abspos = r_ * mat_.cols() + c_ + n;
00370 return const_mat_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00371 }
00372 EXMAT_INLINE2 const const_mat_iterator operator+(difference_type n) const {
00373 size_t abspos = r_ * mat_.cols() + c_ + n;
00374 return const_mat_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00375 }
00376 EXMAT_INLINE2 const_mat_iterator& operator+=(difference_type n) {
00377 size_t abspos = r_ * mat_.cols() + c_ + n;
00378 r_ = abspos/mat_.rows();
00379 c_ = abspos%mat_.cols();
00380 return *this;
00381 }
00382 EXMAT_INLINE2 const_mat_iterator operator-(difference_type n) {
00383 size_t abspos = r_ * mat_.cols() + c_ - n;
00384 return const_mat_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00385 }
00386 EXMAT_INLINE2 const const_mat_iterator operator-(difference_type n) const {
00387 size_t abspos = r_ * mat_.cols() + c_ - n;
00388 return const_mat_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00389 }
00390 EXMAT_INLINE2 const_mat_iterator& operator-=(difference_type n) {
00391 size_t abspos = r_ * mat_.cols() + c_ - n;
00392 r_ = abspos/mat_.rows();
00393 c_ = abspos%mat_.cols();
00394 return *this;
00395 }
00396
00397 EXMAT_INLINE2 difference_type operator-(const const_mat_iterator& itr) const {
00398 size_t abspos = r_ * mat_.cols() + c_;
00399 size_t abspos2 = itr.r_ * mat_.cols() + itr.c_;
00400 return abspos - abspos2;
00401 }
00402
00404 EXMAT_INLINE2 size_t row() const
00405 { return r_; }
00407 EXMAT_INLINE2 size_t col() const
00408 { return c_; }
00409
00411 EXMAT_INLINE2 size_t rows() const
00412 { return mat_.rows(); }
00414 EXMAT_INLINE2 size_t cols() const
00415 { return mat_.cols(); }
00416
00417 private:
00418 mutable MAT& mat_;
00419 size_t r_;
00420 size_t c_;
00421 };
00422
00423 template<class MAT, typename Diff>
00424 EXMAT_INLINE2 const const_mat_iterator<MAT>
00425 operator+(Diff n, const const_mat_iterator<MAT>& itr) {
00426 return itr + n;
00427 }
00428
00429 template<class MAT> EXMAT_INLINE2
00430 bool operator==(const const_mat_iterator<MAT>& itr1,
00431 const const_mat_iterator<MAT>& itr2)
00432 {
00433 return (itr1.row() * itr1.cols() + itr1.col()
00434 == itr2.row() * itr2.cols() + itr2.col());
00435 }
00436 template<class MAT> EXMAT_INLINE2
00437 bool operator!=(const const_mat_iterator<MAT>& itr1,
00438 const const_mat_iterator<MAT>& itr2)
00439 {
00440 return !(itr1 == itr2);
00441 }
00442 template<class MAT> EXMAT_INLINE2
00443 bool operator<( const const_mat_iterator<MAT>& itr1,
00444 const const_mat_iterator<MAT>& itr2)
00445 {
00446 return (itr1.row() * itr1.cols() + itr1.col()
00447 < itr2.row() * itr2.cols() + itr2.col());
00448 }
00449 template<class MAT> EXMAT_INLINE2
00450 bool operator<=(const const_mat_iterator<MAT>& itr1,
00451 const const_mat_iterator<MAT>& itr2)
00452 {
00453 return (itr1.row() * itr1.cols() + itr1.col()
00454 <= itr2.row() * itr2.cols() + itr2.col());
00455 }
00456 template<class MAT> EXMAT_INLINE2
00457 bool operator>( const const_mat_iterator<MAT>& itr1,
00458 const const_mat_iterator<MAT>& itr2)
00459 {
00460 return (itr1.row() * itr1.cols() + itr1.col()
00461 > itr2.row() * itr2.cols() + itr2.col());
00462 }
00463 template<class MAT> EXMAT_INLINE2
00464 bool operator>=(const const_mat_iterator<MAT>& itr1,
00465 const const_mat_iterator<MAT>& itr2)
00466 {
00467 return (itr1.row() * itr1.cols() + itr1.col()
00468 >= itr2.row() * itr2.cols() + itr2.col());
00469 }
00470
00473
00474 template<class MAT>
00475 class mat_ctg_iterator
00476 {
00477 public:
00478 typedef std::random_access_iterator_tag iterator_category;
00479 typedef typename MAT::value_type value_type;
00480 typedef typename MAT::reference reference;
00481 typedef value_type* pointer;
00482 typedef ptrdiff_t difference_type;
00483 typedef mat_ctg_iterator<MAT> self_type;
00484
00485 EXMAT_INLINE2 mat_ctg_iterator(MAT& m, size_t r, size_t c)
00486 : mat_(m), r_(r), c_(c) {}
00487
00488 EXMAT_INLINE2 reference operator*() const {
00489 return mat_.data[r_*mat_.CCOLS+c_];
00490 }
00491 EXMAT_INLINE2 pointer operator->() const {
00492 return &(mat_.data[r_*mat_.CCOLS+c_]);
00493 }
00494
00495 EXMAT_INLINE2 mat_ctg_iterator& operator++() {
00496 c_ = ++c_ >= mat_.cols() ? 0 : c_;
00497 r_ = c_ == 0 ? r_+1 : r_;
00498 return *this;
00499 }
00500 EXMAT_INLINE2 const mat_ctg_iterator operator++(int) {
00501 mat_ctg_iterator tmp = *this;
00502 ++*this; return tmp;
00503 }
00504 EXMAT_INLINE2 mat_ctg_iterator& operator--() {
00505 size_t c = mat_.cols()-1;
00506 c_ = c_ == 0 ? c : c_-1;
00507 r_ = c_ == c ? r_-1 : r_;
00508 return *this;
00509 }
00510 EXMAT_INLINE2 const mat_ctg_iterator operator--(int) {
00511 mat_ctg_iterator tmp = *this;
00512 --*this; return tmp;
00513 }
00514 EXMAT_INLINE2 mat_ctg_iterator operator+(difference_type n) {
00515 size_t abspos = r_ * mat_.cols() + c_ + n;
00516 return mat_ctg_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00517 }
00518 EXMAT_INLINE2 const mat_ctg_iterator operator+(difference_type n) const {
00519 size_t abspos = r_ * mat_.cols() + c_ + n;
00520 return mat_ctg_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00521 }
00522 EXMAT_INLINE2 mat_ctg_iterator& operator+=(difference_type n) {
00523 size_t abspos = r_ * mat_.cols() + c_ + n;
00524 r_ = abspos/mat_.rows();
00525 c_ = abspos%mat_.cols();
00526 return *this;
00527 }
00528 EXMAT_INLINE2 mat_ctg_iterator operator-(difference_type n) {
00529 size_t abspos = r_ * mat_.cols() + c_ - n;
00530 return mat_ctg_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00531 }
00532 EXMAT_INLINE2 const mat_ctg_iterator operator-(difference_type n) const {
00533 size_t abspos = r_ * mat_.cols() + c_ - n;
00534 return mat_ctg_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00535 }
00536 EXMAT_INLINE2 mat_ctg_iterator& operator-=(difference_type n) {
00537 size_t abspos = r_ * mat_.cols() + c_ - n;
00538 r_ = abspos/mat_.rows();
00539 c_ = abspos%mat_.cols();
00540 return *this;
00541 }
00542
00543 EXMAT_INLINE2 difference_type operator-(const mat_ctg_iterator& itr) const {
00544 size_t abspos = r_ * mat_.cols() + c_;
00545 size_t abspos2 = itr.r_ * mat_.cols() + itr.c_;
00546 return abspos - abspos2;
00547 }
00548
00550 EXMAT_INLINE2 size_t row() const
00551 { return r_; }
00553 EXMAT_INLINE2 size_t col() const
00554 { return c_; }
00555
00557 EXMAT_INLINE2 size_t rows() const
00558 { return mat_.rows(); }
00560 EXMAT_INLINE2 size_t cols() const
00561 { return mat_.cols(); }
00562
00563 private:
00564 mutable MAT& mat_;
00565 size_t r_;
00566 size_t c_;
00567 };
00568
00569 template<class MAT, typename Diff>
00570 EXMAT_INLINE2 const mat_ctg_iterator<MAT>
00571 operator+(Diff n, const mat_ctg_iterator<MAT>& itr) {
00572 return itr + n;
00573 }
00574
00575 template<class MAT> EXMAT_INLINE2
00576 bool operator==(const mat_ctg_iterator<MAT>& itr1,
00577 const mat_ctg_iterator<MAT>& itr2)
00578 {
00579 return (itr1.row() * itr1.cols() + itr1.col()
00580 == itr2.row() * itr2.cols() + itr2.col());
00581 }
00582 template<class MAT> EXMAT_INLINE2
00583 bool operator!=(const mat_ctg_iterator<MAT>& itr1,
00584 const mat_ctg_iterator<MAT>& itr2)
00585 {
00586 return !(itr1 == itr2);
00587 }
00588 template<class MAT> EXMAT_INLINE2
00589 bool operator<( const mat_ctg_iterator<MAT>& itr1,
00590 const mat_ctg_iterator<MAT>& itr2)
00591 {
00592 return (itr1.row() * itr1.cols() + itr1.col()
00593 < itr2.row() * itr2.cols() + itr2.col());
00594 }
00595 template<class MAT> EXMAT_INLINE2
00596 bool operator<=(const mat_ctg_iterator<MAT>& itr1,
00597 const mat_ctg_iterator<MAT>& itr2)
00598 {
00599 return (itr1.row() * itr1.cols() + itr1.col()
00600 <= itr2.row() * itr2.cols() + itr2.col());
00601 }
00602 template<class MAT> EXMAT_INLINE2
00603 bool operator>( const mat_ctg_iterator<MAT>& itr1,
00604 const mat_ctg_iterator<MAT>& itr2)
00605 {
00606 return (itr1.row() * itr1.cols() + itr1.col()
00607 > itr2.row() * itr2.cols() + itr2.col());
00608 }
00609 template<class MAT> EXMAT_INLINE2
00610 bool operator>=(const mat_ctg_iterator<MAT>& itr1,
00611 const mat_ctg_iterator<MAT>& itr2)
00612 {
00613 return (itr1.row() * itr1.cols() + itr1.col()
00614 >= itr2.row() * itr2.cols() + itr2.col());
00615 }
00616
00619
00620 template<class MAT>
00621 class const_mat_ctg_iterator
00622 {
00623 public:
00624 typedef std::random_access_iterator_tag iterator_category;
00625 typedef typename MAT::value_type value_type;
00626 typedef typename MAT::const_reference reference;
00627 typedef const value_type* pointer;
00628 typedef ptrdiff_t difference_type;
00629 typedef const_mat_ctg_iterator<MAT> self_type;
00630
00631 EXMAT_INLINE2 const_mat_ctg_iterator(MAT& m, size_t r, size_t c)
00632 : mat_(m), r_(r), c_(c) {}
00633
00634 EXMAT_INLINE2 reference operator*() const {
00635 return mat_.data[r_*mat_.CCOLS+c_];
00636 }
00637 EXMAT_INLINE2 pointer operator->() const {
00638 return &(mat_.data[r_*mat_.CCOLS+c_]);
00639 }
00640
00641 EXMAT_INLINE2 const_mat_ctg_iterator& operator++() {
00642 c_ = ++c_ >= mat_.cols() ? 0 : c_;
00643 r_ = c_ == 0 ? r_+1 : r_;
00644 return *this;
00645 }
00646 EXMAT_INLINE2 const const_mat_ctg_iterator operator++(int) {
00647 const_mat_ctg_iterator tmp = *this;
00648 ++*this; return tmp;
00649 }
00650 EXMAT_INLINE2 const_mat_ctg_iterator& operator--() {
00651 size_t c = mat_.cols()-1;
00652 c_ = c_ == 0 ? c : c_-1;
00653 r_ = c_ == c ? r_-1 : r_;
00654 return *this;
00655 }
00656 EXMAT_INLINE2 const const_mat_ctg_iterator operator--(int) {
00657 const_mat_ctg_iterator tmp = *this;
00658 --*this; return tmp;
00659 }
00660 EXMAT_INLINE2 const_mat_ctg_iterator operator+(difference_type n) {
00661 size_t abspos = r_ * mat_.cols() + c_ + n;
00662 return const_mat_ctg_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00663 }
00664 EXMAT_INLINE2 const const_mat_ctg_iterator operator+(difference_type n) const {
00665 size_t abspos = r_ * mat_.cols() + c_ + n;
00666 return const_mat_ctg_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00667 }
00668 EXMAT_INLINE2 const_mat_ctg_iterator& operator+=(difference_type n) {
00669 size_t abspos = r_ * mat_.cols() + c_ + n;
00670 r_ = abspos/mat_.rows();
00671 c_ = abspos%mat_.cols();
00672 return *this;
00673 }
00674 EXMAT_INLINE2 const_mat_ctg_iterator operator-(difference_type n) {
00675 size_t abspos = r_ * mat_.cols() + c_ - n;
00676 return const_mat_ctg_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00677 }
00678 EXMAT_INLINE2 const const_mat_ctg_iterator operator-(difference_type n) const {
00679 size_t abspos = r_ * mat_.cols() + c_ - n;
00680 return const_mat_ctg_iterator(mat_, abspos/mat_.rows(), abspos%mat_.cols());
00681 }
00682 EXMAT_INLINE2 const_mat_ctg_iterator& operator-=(difference_type n) {
00683 size_t abspos = r_ * mat_.cols() + c_ - n;
00684 r_ = abspos/mat_.rows();
00685 c_ = abspos%mat_.cols();
00686 return *this;
00687 }
00688
00689 EXMAT_INLINE2 difference_type operator-(const const_mat_ctg_iterator& itr) const {
00690 size_t abspos = r_ * mat_.cols() + c_;
00691 size_t abspos2 = itr.r_ * mat_.cols() + itr.c_;
00692 return abspos - abspos2;
00693 }
00694
00696 EXMAT_INLINE2 size_t row() const
00697 { return r_; }
00699 EXMAT_INLINE2 size_t col() const
00700 { return c_; }
00701
00703 EXMAT_INLINE2 size_t rows() const
00704 { return mat_.rows(); }
00706 EXMAT_INLINE2 size_t cols() const
00707 { return mat_.cols(); }
00708
00709 private:
00710 mutable MAT& mat_;
00711 size_t r_;
00712 size_t c_;
00713 };
00714
00715 template<class MAT, typename Diff>
00716 EXMAT_INLINE2 const const_mat_ctg_iterator<MAT>
00717 operator+(Diff n, const const_mat_ctg_iterator<MAT>& itr) {
00718 return itr + n;
00719 }
00720
00721 template<class MAT> EXMAT_INLINE2
00722 bool operator==(const const_mat_ctg_iterator<MAT>& itr1,
00723 const const_mat_ctg_iterator<MAT>& itr2)
00724 {
00725 return (itr1.row() * itr1.cols() + itr1.col()
00726 == itr2.row() * itr2.cols() + itr2.col());
00727 }
00728 template<class MAT> EXMAT_INLINE2
00729 bool operator!=(const const_mat_ctg_iterator<MAT>& itr1,
00730 const const_mat_ctg_iterator<MAT>& itr2)
00731 {
00732 return !(itr1 == itr2);
00733 }
00734 template<class MAT> EXMAT_INLINE2
00735 bool operator<( const const_mat_ctg_iterator<MAT>& itr1,
00736 const const_mat_ctg_iterator<MAT>& itr2)
00737 {
00738 return (itr1.row() * itr1.cols() + itr1.col()
00739 < itr2.row() * itr2.cols() + itr2.col());
00740 }
00741 template<class MAT> EXMAT_INLINE2
00742 bool operator<=(const const_mat_ctg_iterator<MAT>& itr1,
00743 const const_mat_ctg_iterator<MAT>& itr2)
00744 {
00745 return (itr1.row() * itr1.cols() + itr1.col()
00746 <= itr2.row() * itr2.cols() + itr2.col());
00747 }
00748 template<class MAT> EXMAT_INLINE2
00749 bool operator>( const const_mat_ctg_iterator<MAT>& itr1,
00750 const const_mat_ctg_iterator<MAT>& itr2)
00751 {
00752 return (itr1.row() * itr1.cols() + itr1.col()
00753 > itr2.row() * itr2.cols() + itr2.col());
00754 }
00755 template<class MAT> EXMAT_INLINE2
00756 bool operator>=(const const_mat_ctg_iterator<MAT>& itr1,
00757 const const_mat_ctg_iterator<MAT>& itr2)
00758 {
00759 return (itr1.row() * itr1.cols() + itr1.col()
00760 >= itr2.row() * itr2.cols() + itr2.col());
00761 }
00762
00763 }
00764
00765 #ifdef _MSC_VER
00766 # pragma warning( pop )
00767 #endif // _MSC_VER
00768
00769 #endif // _EXMAT_ITERATORS_H