00001
00002
00003
00004 #ifndef matrixIterator_hh
00005 #define matrixIterator_hh
00006
00007 #include <cstddef>
00008 #include <bits/stl_iterator_base_types.h>
00009 #include "basics/exceptions.hh"
00010 #include "basics/outputOperator.hh"
00011
00012 namespace concepts {
00013
00014
00015 template<class F>
00016 class Matrix;
00017
00018
00019
00025 template <class _Tp, class _Ref, class _Ptr>
00026 class _Matrix_iterator_base : public OutputOperator {
00027 public:
00028 typedef _Matrix_iterator_base<_Tp, _Tp&, _Tp*> iterator;
00029 typedef _Matrix_iterator_base<_Tp, const _Tp&, const _Tp*> const_iterator;
00030
00035 template<class _Tp_>
00036 struct ReturnType;
00037
00038 typedef _Tp value_type;
00039 typedef _Ptr pointer;
00040 typedef _Ref reference;
00041 typedef size_t size_type;
00042 typedef ptrdiff_t difference_type;
00043 typedef typename ReturnType<_Ref>::type return_type;
00044 typedef _Matrix_iterator_base _Self;
00045
00053 _Matrix_iterator_base(const uint nofRows, const uint nofCols,
00054 const uint r, const uint c);
00056 _Matrix_iterator_base();
00061 template<class _RefR, class _PtrR>
00062 _Matrix_iterator_base(const _Matrix_iterator_base<_Tp, _RefR, _PtrR>& __x)
00063 : nofRows_(__x.nofRows()), nofCols_(__x.nofCols()),
00064 row_(__x.row()), col_(__x.col()), last_(__x.last()) {}
00065
00067 inline const uint nofRows() const { return nofRows_; }
00069 inline const uint nofCols() const { return nofCols_; }
00071 inline uint row() const { return row_; }
00073 inline uint col() const { return col_; }
00075 inline bool last() const { return last_; }
00076
00078 _Self& operator=(const iterator& __x) {
00079 conceptsAssert(nofRows_ == __x.nofRows() && nofCols_ == __x.nofCols(),
00080 Assertion());
00081 row_ = __x.row();
00082 col_ = __x.col();
00083 last_ = __x.last();
00084 return *this;
00085 }
00086 protected:
00087 virtual std::ostream& info(std::ostream& os) const;
00089 const uint nofRows_, nofCols_;
00091 uint row_, col_;
00093 bool last_;
00094 };
00095
00099 template <class _Tp, class _Ref, class _Ptr>
00100 template<class _Tp_>
00101 struct _Matrix_iterator_base<_Tp, _Ref, _Ptr>::ReturnType {
00102 typedef _Tp_ type;
00103 };
00104
00108 template <class _Tp, class _Ref, class _Ptr>
00109 template<class _Tp_>
00110 struct _Matrix_iterator_base<_Tp, _Ref, _Ptr>::ReturnType<const _Tp_&> {
00111 typedef const _Tp_ type;
00112 };
00113
00114 template <class _Tp, class _Ref, class _Ptr>
00115 std::ostream&
00116 _Matrix_iterator_base<_Tp, _Ref, _Ptr>::info(std::ostream& os) const {
00117 os << "_Matrix_iterator_base(pos = ";
00118 if (!last_)
00119 os << "(" << row_ << ", " << col_ << ")";
00120 else os << "end)";
00121 return os;
00122 }
00123
00124
00125
00126 template <class _Tp, class _Ref, class _Ptr>
00127 inline bool
00128 operator==(const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __x,
00129 const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __y)
00130 {
00131 return (__x.last() && __y.last()) ||
00132 (!__x.last() && !__y.last() &&
00133 __x.row() == __y.row() && __x.col() == __y.col());
00134 }
00135
00136 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
00137 inline bool
00138 operator==(const _Matrix_iterator_base<_Tp, _RefL, _PtrL>& __x,
00139 const _Matrix_iterator_base<_Tp, _RefR, _PtrR>& __y)
00140 {
00141 return (__x.last() && __y.last()) ||
00142 (!__x.last() && !__y.last() &&
00143 __x.row() == __y.row() && __x.col() == __y.col());
00144 }
00145
00146 template <class _Tp, class _Ref, class _Ptr>
00147 inline bool
00148 operator!=(const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __x,
00149 const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __y)
00150 {
00151 return !(__x == __y);
00152 }
00153
00154 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
00155 inline bool
00156 operator!=(const _Matrix_iterator_base<_Tp, _RefL, _PtrL>& __x,
00157 const _Matrix_iterator_base<_Tp, _RefR, _PtrR>& __y)
00158 {
00159 return !(__x == __y);
00160 }
00161
00162 template <class _Tp, class _Ref, class _Ptr>
00163 inline bool
00164 operator<(const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __x,
00165 const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __y)
00166 {
00167 return !__x.last() &&
00168 (__y.last() || ((!__y.last() && __x.row() < __y.row()) ||
00169 (__x.row() == __y.row() && __x.col() < __y.col())));
00170 }
00171
00172 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
00173 inline bool
00174 operator<(const _Matrix_iterator_base<_Tp, _RefL, _PtrL>& __x,
00175 const _Matrix_iterator_base<_Tp, _RefR, _PtrR>& __y)
00176 {
00177 return !__x.last() &&
00178 (__y.last() || (!__y.last() && __x.row() < __y.row() ||
00179 (__x.row() == __y.row() && __x.col() < __y.col())));
00180 }
00181
00182 template <class _Tp, class _Ref, class _Ptr>
00183 inline bool
00184 operator>(const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __x,
00185 const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __y)
00186 {
00187 return __y < __x;
00188 }
00189
00190 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
00191 inline bool
00192 operator>(const _Matrix_iterator_base<_Tp, _RefL, _PtrL>& __x,
00193 const _Matrix_iterator_base<_Tp, _RefR, _PtrR>& __y)
00194 {
00195 return __y < __x;
00196 }
00197
00198 template <class _Tp, class _Ref, class _Ptr>
00199 inline bool
00200 operator<=(const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __x,
00201 const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __y)
00202 {
00203 return !(__y < __x);
00204 }
00205
00206 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
00207 inline bool
00208 operator<=(const _Matrix_iterator_base<_Tp, _RefL, _PtrL>& __x,
00209 const _Matrix_iterator_base<_Tp, _RefR, _PtrR>& __y)
00210 {
00211 return !(__y < __x);
00212 }
00213
00214 template <class _Tp, class _Ref, class _Ptr>
00215 inline bool
00216 operator>=(const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __x,
00217 const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __y)
00218 {
00219 return !(__x < __y);
00220 }
00221
00222 template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR>
00223 inline bool
00224 operator>=(const _Matrix_iterator_base<_Tp, _RefL, _PtrL>& __x,
00225 const _Matrix_iterator_base<_Tp, _RefR, _PtrR>& __y)
00226 {
00227 return !(__x < __y);
00228 }
00229
00230 template <typename _Tp, typename _RefL, typename _PtrL,
00231 typename _RefR, typename _PtrR>
00232 inline typename _Matrix_iterator_base<_Tp, _RefL, _PtrL>::difference_type
00233 operator-(const _Matrix_iterator_base<_Tp, _RefL, _PtrL>& __x,
00234 const _Matrix_iterator_base<_Tp, _RefR, _PtrR>& __y)
00235 {
00236 if (__x.last())
00237 if (__y.last()) return 0;
00238 else return __y.nofRows() * (__y.nofCols() - __y.row()) - __y.col();
00239 else if (__y.last())
00240 return __x.nofRows() * (__x.nofCols() - __x.row()) - __x.col();
00241 return typename _Matrix_iterator_base<_Tp, _RefL, _PtrL>::difference_type
00242 (__x.col() - __y.col() + __x.nofCols() * (__x.row() - __y.row()));
00243 }
00244
00245 template <class _Tp, class _Ref, class _Ptr>
00246 inline _Matrix_iterator_base<_Tp, _Ref, _Ptr>
00247 operator+(ptrdiff_t __n, const _Matrix_iterator_base<_Tp, _Ref, _Ptr>& __x)
00248 {
00249 return __x + __n;
00250 }
00251
00252
00253
00259 template<class F, class G>
00260 F* securePointer(F& value, G* matrix) { return &value; }
00261
00262 template<class F, class G>
00263 F* securePointer(const F value, const G* matrix) {
00264 throw conceptsException(MissingFeature
00265 ("inapplicable for constant matrices"));
00266 return 0;
00267 }
00268
00269
00270
00275 template <class _Tp, class _Ref, class _Ptr>
00276 class _Matrix_iterator : public _Matrix_iterator_base<_Tp, _Ref, _Ptr> {
00277 public:
00278 typedef _Matrix_iterator<_Tp, _Tp&, _Tp*> iterator;
00279 typedef _Matrix_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
00280
00281 template<class _Tp_, class _Ref_, class _Ptr_>
00282 struct MatrixType;
00283
00284 typedef std::random_access_iterator_tag iterator_category;
00285 typedef _Tp value_type;
00286 typedef _Ptr pointer;
00287 typedef _Ref reference;
00288 typedef size_t size_type;
00289 typedef ptrdiff_t difference_type;
00290 typedef _Matrix_iterator _Self;
00291 typedef _Matrix_iterator_base<_Tp, _Ref, _Ptr> _Base;
00292 typedef typename MatrixType<_Tp, _Ref, _Ptr>::type matrix_type;
00293 typedef typename _Base::return_type return_type;
00294
00301 _Matrix_iterator(matrix_type& m, const uint r = 0, const uint c = 0);
00303 _Matrix_iterator();
00305 template<class _RefR, class _PtrR>
00306 _Matrix_iterator(const _Matrix_iterator<_Tp, _RefR, _PtrR>& __x)
00307 : _Base(__x), matrix_(__x.matrix()) {}
00308
00310 return_type operator*() const {
00311 conceptsAssert(matrix_, Assertion());
00312 return (*matrix_)(this->row_, this->col_);
00313 }
00320 pointer operator->() const {
00321 conceptsAssert(matrix_, Assertion());
00322 return securePointer((*matrix_)(this->row_, this->col_), matrix_);
00323 }
00324
00326 inline matrix_type* matrix() const { return matrix_; }
00327
00329 _Self& operator=(const iterator& __x) {
00330 conceptsAssert(matrix_ == __x.matrix(), Assertion());
00331 _Base::operator=(__x);
00332 return *this;
00333 }
00334
00335 _Self& operator++() {
00336 if (!this->last_) {
00337 if (++this->col_ >= this->nofCols_) {
00338 ++this->row_;
00339 this->col_ = 0;
00340 }
00341 this->last_ = this->row_ >= this->nofRows_;
00342 }
00343 return *this;
00344 }
00345 _Self operator++(int) {
00346 _Self __tmp = *this;
00347 ++*this;
00348 return __tmp;
00349 }
00350
00351 _Self& operator--() {
00352 if (this->last_) {
00353 conceptsAssert(matrix_, Assertion());
00354 this->col_ = this->nofCols_ - 1;
00355 this->row_ = this->nofRows_ - 1;
00356 this->last_ = false;
00357 } else {
00358 if (this->col_ > 0) --this->col_;
00359 else {
00360 conceptsAssert(this->row_ > 0, Assertion());
00361 --this->row_;
00362 this->col_ = this->nofCols_ - 1;
00363 }
00364 }
00365 return *this;
00366 }
00367 _Self operator--(int) {
00368 _Self __tmp = *this;
00369 --*this;
00370 return __tmp;
00371 }
00372
00373 _Self& operator+=(difference_type __n)
00374 {
00375 if (this->last_ && __n < 0) {
00376 this->col_ = 0;
00377 this->row_ = this->nofRows_;
00378 this->last_ = false;
00379 }
00380 if (!this->last_) {
00381 conceptsAssert(this->nofCols_, Assertion());
00382 int col = __n + this->col_;
00383 int row = col / (int)this->nofCols_ + this->row_;
00384 conceptsAssert(row >= 0 , Assertion());
00385 this->row_ = row;
00386 this->col_ = col % this->nofCols_;
00387 this->last_ = this->row_ >= this->nofRows_;
00388 }
00389 return *this;
00390 }
00391
00392 _Self operator+(difference_type __n) const
00393 {
00394 _Self __tmp = *this;
00395 return __tmp += __n;
00396 }
00397
00398 _Self& operator-=(difference_type __n) { return *this += -__n; }
00399
00400 _Self operator-(difference_type __n) const {
00401 _Self __tmp = *this;
00402 return __tmp -= __n;
00403 }
00404
00405 return_type operator[](difference_type __n) const {
00406 return *(*this + __n);
00407 }
00408 protected:
00409 virtual std::ostream& info(std::ostream& os) const;
00410 private:
00412 matrix_type* matrix_;
00413 };
00414
00416 template <class _Tp, class _Ref, class _Ptr>
00417 template<class _Tp_, class _Ref_, class _Ptr_>
00418 struct _Matrix_iterator<_Tp, _Ref, _Ptr>::MatrixType {
00419 typedef Matrix<_Tp_> type;
00420 };
00421
00423 template <class _Tp, class _Ref, class _Ptr>
00424 template<class _Tp_>
00425 struct _Matrix_iterator<_Tp, _Ref, _Ptr>::
00426 MatrixType<_Tp_, const _Tp_&, const _Tp_*>
00427 {
00428 typedef const Matrix<_Tp_> type;
00429 };
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 }
00566
00567 #endif // matrixIterator_hh