Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

operator/matrixIterator.hh
Go to the documentation of this file.
00001 /* matrix iterators
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   // forward declaration
00015   template<class F>
00016   class Matrix;
00017 
00018   // ************************************************* _Matrix_iterator_base **
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   // ****************************************************** securePointer **
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   // ****************************************************** _Matrix_iterator **
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 //   template <class _Tp, class _Ref, class _Ptr, class G>
00434 //   inline bool
00435 //   operator==(const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __x,
00436 //       const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __y)
00437 //   {
00438 //     return __x.last() && __y.last() ||
00439 //       (!__x.last() && !__y.last() && 
00440 //        __x.row() == __y.row() && __x.col() == __y.col());
00441 //   }
00442 
00443 //   template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR,
00444 //      class G>
00445 //   inline bool
00446 //   operator==(const _Matrix_iterator<_Tp, _RefL, _PtrL, G>& __x,
00447 //       const _Matrix_iterator<_Tp, _RefR, _PtrR, G>& __y)
00448 //   {
00449 //     return __x.last() && __y.last() ||
00450 //       (!__x.last() && !__y.last() && 
00451 //        __x.row() == __y.row() && __x.col() == __y.col());
00452 //   }
00453 
00454 //   template <class _Tp, class _Ref, class _Ptr, class G>
00455 //   inline bool
00456 //   operator!=(const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __x,
00457 //       const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __y)
00458 //   {
00459 //     return !(__x == __y);
00460 //   }
00461 
00462 //   template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR,
00463 //      class G>
00464 //   inline bool
00465 //   operator!=(const _Matrix_iterator<_Tp, _RefL, _PtrL, G>& __x,
00466 //       const _Matrix_iterator<_Tp, _RefR, _PtrR, G>& __y)
00467 //   {
00468 //     return !(__x == __y);
00469 //   }
00470 
00471 //   template <class _Tp, class _Ref, class _Ptr, class G>
00472 //   inline bool
00473 //   operator<(const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __x,
00474 //      const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __y)
00475 //   {
00476 //     return !__x.last() && 
00477 //       (__y.last() || (!__y.last() && __x.row() < __y.row() || 
00478 //          (__x.row() == __y.row() && __x.col() < __y.col())));
00479 //   }
00480 
00481 //   template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR,
00482 //      class G>
00483 //   inline bool
00484 //   operator<(const _Matrix_iterator<_Tp, _RefL, _PtrL, G>& __x,
00485 //      const _Matrix_iterator<_Tp, _RefR, _PtrR, G>& __y)
00486 //   {
00487 //     return !__x.last() && 
00488 //       (__y.last() || (!__y.last() && __x.row() < __y.row() || 
00489 //          (__x.row() == __y.row() && __x.col() < __y.col())));
00490 //   }
00491 
00492 //   template <class _Tp, class _Ref, class _Ptr, class G>
00493 //   inline bool
00494 //   operator>(const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __x,
00495 //      const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __y)
00496 //   {
00497 //     return __y < __x;
00498 //   }
00499 
00500 //   template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR,
00501 //      class G>
00502 //   inline bool
00503 //   operator>(const _Matrix_iterator<_Tp, _RefL, _PtrL, G>& __x,
00504 //      const _Matrix_iterator<_Tp, _RefR, _PtrR, G>& __y)
00505 //   {
00506 //     return __y < __x;
00507 //   }
00508 
00509 //   template <class _Tp, class _Ref, class _Ptr, class G>
00510 //   inline bool
00511 //   operator<=(const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __x,
00512 //       const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __y)
00513 //   {
00514 //     return !(__y < __x);
00515 //   }
00516 
00517 //   template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR,
00518 //      class G>
00519 //   inline bool
00520 //   operator<=(const _Matrix_iterator<_Tp, _RefL, _PtrL, G>& __x,
00521 //       const _Matrix_iterator<_Tp, _RefR, _PtrR, G>& __y)
00522 //   {
00523 //     return !(__y < __x);
00524 //   }
00525 
00526 //   template <class _Tp, class _Ref, class _Ptr, class G>
00527 //   inline bool
00528 //   operator>=(const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __x,
00529 //       const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __y)
00530 //   {
00531 //     return !(__x < __y);
00532 //   }
00533 
00534 //   template <class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR,
00535 //      class G>
00536 //   inline bool
00537 //   operator>=(const _Matrix_iterator<_Tp, _RefL, _PtrL, G>& __x,
00538 //       const _Matrix_iterator<_Tp, _RefR, _PtrR, G>& __y)
00539 //   {
00540 //     return !(__x < __y);
00541 //   }
00542 
00543 //   template <typename _Tp, typename _RefL, typename _PtrL,
00544 //      typename _RefR, typename _PtrR, typename G>
00545 //   inline typename _Matrix_iterator<_Tp, _RefL, _PtrL, G>::difference_type
00546 //   operator-(const _Matrix_iterator<_Tp, _RefL, _PtrL, G>& __x,
00547 //      const _Matrix_iterator<_Tp, _RefR, _PtrR, G>& __y)
00548 //   {
00549 //     if (__x.last())
00550 //       if (__y.last()) return 0;
00551 //       else return __y.nofRows() * (__y.nofCols() - __y.row()) - __y.col();
00552 //     else if (__y.last())
00553 //       return __x.nofRows() * (__x.nofCols() - __x.row()) - __x.col();
00554 //     return _Matrix_iterator<_Tp, _RefL, _PtrL, G>::difference_type
00555 //       (__x.col() - __y.col() + __x.nofCols() * (__x.row() - __y.row()));
00556 //   }
00557 
00558 //   template <class _Tp, class _Ref, class _Ptr, class G>
00559 //   inline _Matrix_iterator<_Tp, _Ref, _Ptr, G>
00560 //   operator+(ptrdiff_t __n, const _Matrix_iterator<_Tp, _Ref, _Ptr, G>& __x)
00561 //   {
00562 //     return __x + __n;
00563 //   }
00564 
00565 } // namespace concepts
00566 
00567 #endif // matrixIterator_hh

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)