![]() |
Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms
|
00001 // 00002 // Copyright (c) 2000-2002 00003 // Joerg Walter, Mathias Koch 00004 // 00005 // Distributed under the Boost Software License, Version 1.0. (See 00006 // accompanying file LICENSE_1_0.txt or copy at 00007 // http://www.boost.org/LICENSE_1_0.txt) 00008 // 00009 // The authors gratefully acknowledge the support of 00010 // GeNeSys mbH & Co. KG in producing this work. 00011 // 00012 00013 #ifndef _BOOST_UBLAS_ITERATOR_ 00014 #define _BOOST_UBLAS_ITERATOR_ 00015 00016 #include <boost/numeric/ublas/exception.hpp> 00017 #include <iterator> 00018 00019 00020 namespace boost { namespace numeric { namespace ublas { 00021 00027 template<class C> 00028 class container_const_reference: 00029 private nonassignable { 00030 public: 00031 typedef C container_type; 00032 00033 BOOST_UBLAS_INLINE 00034 container_const_reference (): 00035 c_ (0) {} 00036 BOOST_UBLAS_INLINE 00037 container_const_reference (const container_type &c): 00038 c_ (&c) {} 00039 00040 BOOST_UBLAS_INLINE 00041 const container_type &operator () () const { 00042 return *c_; 00043 } 00044 00045 BOOST_UBLAS_INLINE 00046 container_const_reference &assign (const container_type *c) { 00047 c_ = c; 00048 return *this; 00049 } 00050 00051 // Closure comparison 00052 BOOST_UBLAS_INLINE 00053 bool same_closure (const container_const_reference &cr) const { 00054 return c_ == cr.c_; 00055 } 00056 00057 private: 00058 const container_type *c_; 00059 }; 00060 00066 template<class C> 00067 class container_reference: 00068 private nonassignable { 00069 public: 00070 typedef C container_type; 00071 00072 BOOST_UBLAS_INLINE 00073 container_reference (): 00074 c_ (0) {} 00075 BOOST_UBLAS_INLINE 00076 container_reference (container_type &c): 00077 c_ (&c) {} 00078 00079 BOOST_UBLAS_INLINE 00080 container_type &operator () () const { 00081 return *c_; 00082 } 00083 00084 BOOST_UBLAS_INLINE 00085 container_reference &assign (container_type *c) { 00086 c_ = c; 00087 return *this; 00088 } 00089 00090 // Closure comparison 00091 BOOST_UBLAS_INLINE 00092 bool same_closure (const container_reference &cr) const { 00093 return c_ == cr.c_; 00094 } 00095 00096 private: 00097 container_type *c_; 00098 }; 00099 00109 template<class IC, class I, class T> 00110 struct forward_iterator_base: 00111 public std::iterator<IC, T> { 00112 typedef I derived_iterator_type; 00113 typedef T derived_value_type; 00114 00115 // Arithmetic 00116 BOOST_UBLAS_INLINE 00117 derived_iterator_type operator ++ (int) { 00118 derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this)); 00119 derived_iterator_type tmp (d); 00120 ++ d; 00121 return tmp; 00122 } 00123 BOOST_UBLAS_INLINE 00124 friend derived_iterator_type operator ++ (derived_iterator_type &d, int) { 00125 derived_iterator_type tmp (d); 00126 ++ d; 00127 return tmp; 00128 } 00129 00130 // Comparison 00131 BOOST_UBLAS_INLINE 00132 bool operator != (const derived_iterator_type &it) const { 00133 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this); 00134 return ! (*d == it); 00135 } 00136 }; 00137 00147 template<class IC, class I, class T> 00148 struct bidirectional_iterator_base: 00149 public std::iterator<IC, T> { 00150 typedef I derived_iterator_type; 00151 typedef T derived_value_type; 00152 00153 // Arithmetic 00154 BOOST_UBLAS_INLINE 00155 derived_iterator_type operator ++ (int) { 00156 derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this)); 00157 derived_iterator_type tmp (d); 00158 ++ d; 00159 return tmp; 00160 } 00161 BOOST_UBLAS_INLINE 00162 friend derived_iterator_type operator ++ (derived_iterator_type &d, int) { 00163 derived_iterator_type tmp (d); 00164 ++ d; 00165 return tmp; 00166 } 00167 BOOST_UBLAS_INLINE 00168 derived_iterator_type operator -- (int) { 00169 derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this)); 00170 derived_iterator_type tmp (d); 00171 -- d; 00172 return tmp; 00173 } 00174 BOOST_UBLAS_INLINE 00175 friend derived_iterator_type operator -- (derived_iterator_type &d, int) { 00176 derived_iterator_type tmp (d); 00177 -- d; 00178 return tmp; 00179 } 00180 00181 // Comparison 00182 BOOST_UBLAS_INLINE 00183 bool operator != (const derived_iterator_type &it) const { 00184 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this); 00185 return ! (*d == it); 00186 } 00187 }; 00188 00201 template<class IC, class I, class T, class D = std::ptrdiff_t> 00202 // ISSUE the default for D seems rather dangerous as it can easily be (silently) incorrect 00203 struct random_access_iterator_base: 00204 public std::iterator<IC, T> { 00205 typedef I derived_iterator_type; 00206 typedef T derived_value_type; 00207 typedef D derived_difference_type; 00208 00209 /* FIXME Need to explicitly pass derived_reference_type as otherwise I undefined type or forward declared 00210 typedef typename derived_iterator_type::reference derived_reference_type; 00211 // Indexed element 00212 BOOST_UBLAS_INLINE 00213 derived_reference_type operator [] (derived_difference_type n) { 00214 return *(*this + n); 00215 } 00216 */ 00217 00218 // Arithmetic 00219 BOOST_UBLAS_INLINE 00220 derived_iterator_type operator ++ (int) { 00221 derived_iterator_type &d (*static_cast<derived_iterator_type *> (this)); 00222 derived_iterator_type tmp (d); 00223 ++ d; 00224 return tmp; 00225 } 00226 BOOST_UBLAS_INLINE 00227 friend derived_iterator_type operator ++ (derived_iterator_type &d, int) { 00228 derived_iterator_type tmp (d); 00229 ++ d; 00230 return tmp; 00231 } 00232 BOOST_UBLAS_INLINE 00233 derived_iterator_type operator -- (int) { 00234 derived_iterator_type &d (*static_cast<derived_iterator_type *> (this)); 00235 derived_iterator_type tmp (d); 00236 -- d; 00237 return tmp; 00238 } 00239 BOOST_UBLAS_INLINE 00240 friend derived_iterator_type operator -- (derived_iterator_type &d, int) { 00241 derived_iterator_type tmp (d); 00242 -- d; 00243 return tmp; 00244 } 00245 BOOST_UBLAS_INLINE 00246 derived_iterator_type operator + (derived_difference_type n) const { 00247 derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this)); 00248 return tmp += n; 00249 } 00250 BOOST_UBLAS_INLINE 00251 friend derived_iterator_type operator + (const derived_iterator_type &d, derived_difference_type n) { 00252 derived_iterator_type tmp (d); 00253 return tmp += n; 00254 } 00255 BOOST_UBLAS_INLINE 00256 friend derived_iterator_type operator + (derived_difference_type n, const derived_iterator_type &d) { 00257 derived_iterator_type tmp (d); 00258 return tmp += n; 00259 } 00260 BOOST_UBLAS_INLINE 00261 derived_iterator_type operator - (derived_difference_type n) const { 00262 derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this)); 00263 return tmp -= n; 00264 } 00265 BOOST_UBLAS_INLINE 00266 friend derived_iterator_type operator - (const derived_iterator_type &d, derived_difference_type n) { 00267 derived_iterator_type tmp (d); 00268 return tmp -= n; 00269 } 00270 00271 // Comparison 00272 BOOST_UBLAS_INLINE 00273 bool operator != (const derived_iterator_type &it) const { 00274 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this); 00275 return ! (*d == it); 00276 } 00277 BOOST_UBLAS_INLINE 00278 bool operator <= (const derived_iterator_type &it) const { 00279 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this); 00280 return ! (it < *d); 00281 } 00282 BOOST_UBLAS_INLINE 00283 bool operator >= (const derived_iterator_type &it) const { 00284 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this); 00285 return ! (*d < it); 00286 } 00287 BOOST_UBLAS_INLINE 00288 bool operator > (const derived_iterator_type &it) const { 00289 const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this); 00290 return it < *d; 00291 } 00292 }; 00293 00307 // Renamed this class from reverse_iterator to get 00308 // typedef reverse_iterator<...> reverse_iterator 00309 // working. Thanks to Gabriel Dos Reis for explaining this. 00310 template <class I> 00311 class reverse_iterator_base: 00312 public std::reverse_iterator<I> { 00313 public: 00314 typedef typename I::container_type container_type; 00315 typedef typename container_type::size_type size_type; 00316 typedef typename I::difference_type difference_type; 00317 typedef I iterator_type; 00318 00319 // Construction and destruction 00320 BOOST_UBLAS_INLINE 00321 reverse_iterator_base (): 00322 std::reverse_iterator<iterator_type> () {} 00323 BOOST_UBLAS_INLINE 00324 reverse_iterator_base (const iterator_type &it): 00325 std::reverse_iterator<iterator_type> (it) {} 00326 00327 // Arithmetic 00328 BOOST_UBLAS_INLINE 00329 reverse_iterator_base &operator ++ () { 00330 return *this = -- this->base (); 00331 } 00332 BOOST_UBLAS_INLINE 00333 reverse_iterator_base operator ++ (int) { 00334 reverse_iterator_base tmp (*this); 00335 *this = -- this->base (); 00336 return tmp; 00337 } 00338 BOOST_UBLAS_INLINE 00339 reverse_iterator_base &operator -- () { 00340 return *this = ++ this->base (); 00341 } 00342 BOOST_UBLAS_INLINE 00343 reverse_iterator_base operator -- (int) { 00344 reverse_iterator_base tmp (*this); 00345 *this = ++ this->base (); 00346 return tmp; 00347 } 00348 BOOST_UBLAS_INLINE 00349 reverse_iterator_base &operator += (difference_type n) { 00350 return *this = this->base () - n; 00351 } 00352 BOOST_UBLAS_INLINE 00353 reverse_iterator_base &operator -= (difference_type n) { 00354 return *this = this->base () + n; 00355 } 00356 00357 BOOST_UBLAS_INLINE 00358 friend reverse_iterator_base operator + (const reverse_iterator_base &it, difference_type n) { 00359 reverse_iterator_base tmp (it); 00360 return tmp += n; 00361 } 00362 BOOST_UBLAS_INLINE 00363 friend reverse_iterator_base operator + (difference_type n, const reverse_iterator_base &it) { 00364 reverse_iterator_base tmp (it); 00365 return tmp += n; 00366 } 00367 BOOST_UBLAS_INLINE 00368 friend reverse_iterator_base operator - (const reverse_iterator_base &it, difference_type n) { 00369 reverse_iterator_base tmp (it); 00370 return tmp -= n; 00371 } 00372 BOOST_UBLAS_INLINE 00373 friend difference_type operator - (const reverse_iterator_base &it1, const reverse_iterator_base &it2) { 00374 return it2.base () - it1.base (); 00375 } 00376 00377 BOOST_UBLAS_INLINE 00378 const container_type &operator () () const { 00379 return this->base () (); 00380 } 00381 00382 BOOST_UBLAS_INLINE 00383 size_type index () const { 00384 iterator_type tmp (this->base ()); 00385 return (-- tmp).index (); 00386 } 00387 }; 00388 00401 // Renamed this class from reverse_iterator1 to get 00402 // typedef reverse_iterator1<...> reverse_iterator1 00403 // working. Thanks to Gabriel Dos Reis for explaining this. 00404 template <class I> 00405 class reverse_iterator_base1: 00406 public std::reverse_iterator<I> { 00407 public: 00408 typedef typename I::container_type container_type; 00409 typedef typename container_type::size_type size_type; 00410 typedef typename I::difference_type difference_type; 00411 typedef I iterator_type; 00412 typedef typename I::dual_iterator_type dual_iterator_type; 00413 typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type; 00414 00415 // Construction and destruction 00416 BOOST_UBLAS_INLINE 00417 reverse_iterator_base1 (): 00418 std::reverse_iterator<iterator_type> () {} 00419 BOOST_UBLAS_INLINE 00420 reverse_iterator_base1 (const iterator_type &it): 00421 std::reverse_iterator<iterator_type> (it) {} 00422 00423 // Arithmetic 00424 BOOST_UBLAS_INLINE 00425 reverse_iterator_base1 &operator ++ () { 00426 return *this = -- this->base (); 00427 } 00428 BOOST_UBLAS_INLINE 00429 reverse_iterator_base1 operator ++ (int) { 00430 reverse_iterator_base1 tmp (*this); 00431 *this = -- this->base (); 00432 return tmp; 00433 } 00434 BOOST_UBLAS_INLINE 00435 reverse_iterator_base1 &operator -- () { 00436 return *this = ++ this->base (); 00437 } 00438 BOOST_UBLAS_INLINE 00439 reverse_iterator_base1 operator -- (int) { 00440 reverse_iterator_base1 tmp (*this); 00441 *this = ++ this->base (); 00442 return tmp; 00443 } 00444 BOOST_UBLAS_INLINE 00445 reverse_iterator_base1 &operator += (difference_type n) { 00446 return *this = this->base () - n; 00447 } 00448 BOOST_UBLAS_INLINE 00449 reverse_iterator_base1 &operator -= (difference_type n) { 00450 return *this = this->base () + n; 00451 } 00452 00453 BOOST_UBLAS_INLINE 00454 friend reverse_iterator_base1 operator + (const reverse_iterator_base1 &it, difference_type n) { 00455 reverse_iterator_base1 tmp (it); 00456 return tmp += n; 00457 } 00458 BOOST_UBLAS_INLINE 00459 friend reverse_iterator_base1 operator + (difference_type n, const reverse_iterator_base1 &it) { 00460 reverse_iterator_base1 tmp (it); 00461 return tmp += n; 00462 } 00463 BOOST_UBLAS_INLINE 00464 friend reverse_iterator_base1 operator - (const reverse_iterator_base1 &it, difference_type n) { 00465 reverse_iterator_base1 tmp (it); 00466 return tmp -= n; 00467 } 00468 BOOST_UBLAS_INLINE 00469 friend difference_type operator - (const reverse_iterator_base1 &it1, const reverse_iterator_base1 &it2) { 00470 return it2.base () - it1.base (); 00471 } 00472 00473 BOOST_UBLAS_INLINE 00474 const container_type &operator () () const { 00475 return this->base () (); 00476 } 00477 00478 BOOST_UBLAS_INLINE 00479 size_type index1 () const { 00480 iterator_type tmp (this->base ()); 00481 return (-- tmp).index1 (); 00482 } 00483 BOOST_UBLAS_INLINE 00484 size_type index2 () const { 00485 iterator_type tmp (this->base ()); 00486 return (-- tmp).index2 (); 00487 } 00488 00489 BOOST_UBLAS_INLINE 00490 dual_iterator_type begin () const { 00491 iterator_type tmp (this->base ()); 00492 return (-- tmp).begin (); 00493 } 00494 BOOST_UBLAS_INLINE 00495 dual_iterator_type end () const { 00496 iterator_type tmp (this->base ()); 00497 return (-- tmp).end (); 00498 } 00499 BOOST_UBLAS_INLINE 00500 dual_reverse_iterator_type rbegin () const { 00501 return dual_reverse_iterator_type (end ()); 00502 } 00503 BOOST_UBLAS_INLINE 00504 dual_reverse_iterator_type rend () const { 00505 return dual_reverse_iterator_type (begin ()); 00506 } 00507 }; 00508 00523 // Renamed this class from reverse_iterator2 to get 00524 // typedef reverse_iterator2<...> reverse_iterator2 00525 // working. Thanks to Gabriel Dos Reis for explaining this. 00526 template <class I> 00527 class reverse_iterator_base2: 00528 public std::reverse_iterator<I> { 00529 public: 00530 typedef typename I::container_type container_type; 00531 typedef typename container_type::size_type size_type; 00532 typedef typename I::difference_type difference_type; 00533 typedef I iterator_type; 00534 typedef typename I::dual_iterator_type dual_iterator_type; 00535 typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type; 00536 00537 // Construction and destruction 00538 BOOST_UBLAS_INLINE 00539 reverse_iterator_base2 (): 00540 std::reverse_iterator<iterator_type> () {} 00541 BOOST_UBLAS_INLINE 00542 reverse_iterator_base2 (const iterator_type &it): 00543 std::reverse_iterator<iterator_type> (it) {} 00544 00545 // Arithmetic 00546 BOOST_UBLAS_INLINE 00547 reverse_iterator_base2 &operator ++ () { 00548 return *this = -- this->base (); 00549 } 00550 BOOST_UBLAS_INLINE 00551 reverse_iterator_base2 operator ++ (int) { 00552 reverse_iterator_base2 tmp (*this); 00553 *this = -- this->base (); 00554 return tmp; 00555 } 00556 BOOST_UBLAS_INLINE 00557 reverse_iterator_base2 &operator -- () { 00558 return *this = ++ this->base (); 00559 } 00560 BOOST_UBLAS_INLINE 00561 reverse_iterator_base2 operator -- (int) { 00562 reverse_iterator_base2 tmp (*this); 00563 *this = ++ this->base (); 00564 return tmp; 00565 } 00566 BOOST_UBLAS_INLINE 00567 reverse_iterator_base2 &operator += (difference_type n) { 00568 return *this = this->base () - n; 00569 } 00570 BOOST_UBLAS_INLINE 00571 reverse_iterator_base2 &operator -= (difference_type n) { 00572 return *this = this->base () + n; 00573 } 00574 00575 BOOST_UBLAS_INLINE 00576 friend reverse_iterator_base2 operator + (const reverse_iterator_base2 &it, difference_type n) { 00577 reverse_iterator_base2 tmp (it); 00578 return tmp += n; 00579 } 00580 BOOST_UBLAS_INLINE 00581 friend reverse_iterator_base2 operator + (difference_type n, const reverse_iterator_base2 &it) { 00582 reverse_iterator_base2 tmp (it); 00583 return tmp += n; 00584 } 00585 BOOST_UBLAS_INLINE 00586 friend reverse_iterator_base2 operator - (const reverse_iterator_base2 &it, difference_type n) { 00587 reverse_iterator_base2 tmp (it); 00588 return tmp -= n; 00589 } 00590 BOOST_UBLAS_INLINE 00591 friend difference_type operator - (const reverse_iterator_base2 &it1, const reverse_iterator_base2 &it2) { 00592 return it2.base () - it1.base (); 00593 } 00594 00595 BOOST_UBLAS_INLINE 00596 const container_type &operator () () const { 00597 return this->base () (); 00598 } 00599 00600 BOOST_UBLAS_INLINE 00601 size_type index1 () const { 00602 iterator_type tmp (this->base ()); 00603 return (-- tmp).index1 (); 00604 } 00605 BOOST_UBLAS_INLINE 00606 size_type index2 () const { 00607 iterator_type tmp (this->base ()); 00608 return (-- tmp).index2 (); 00609 } 00610 00611 BOOST_UBLAS_INLINE 00612 dual_iterator_type begin () const { 00613 iterator_type tmp (this->base ()); 00614 return (-- tmp).begin (); 00615 } 00616 BOOST_UBLAS_INLINE 00617 dual_iterator_type end () const { 00618 iterator_type tmp (this->base ()); 00619 return (-- tmp).end (); 00620 } 00621 BOOST_UBLAS_INLINE 00622 dual_reverse_iterator_type rbegin () const { 00623 return dual_reverse_iterator_type (end ()); 00624 } 00625 BOOST_UBLAS_INLINE 00626 dual_reverse_iterator_type rend () const { 00627 return dual_reverse_iterator_type (begin ()); 00628 } 00629 }; 00630 00643 template<class C, class IC> 00644 class indexed_iterator: 00645 public container_reference<C>, 00646 public random_access_iterator_base<IC, 00647 indexed_iterator<C, IC>, 00648 typename C::value_type, 00649 typename C::difference_type> { 00650 public: 00651 typedef C container_type; 00652 typedef IC iterator_category; 00653 typedef typename container_type::size_type size_type; 00654 typedef typename container_type::difference_type difference_type; 00655 typedef typename container_type::value_type value_type; 00656 typedef typename container_type::reference reference; 00657 00658 // Construction and destruction 00659 BOOST_UBLAS_INLINE 00660 indexed_iterator (): 00661 container_reference<container_type> (), it_ () {} 00662 BOOST_UBLAS_INLINE 00663 indexed_iterator (container_type &c, size_type it): 00664 container_reference<container_type> (c), it_ (it) {} 00665 00666 // Arithmetic 00667 BOOST_UBLAS_INLINE 00668 indexed_iterator &operator ++ () { 00669 ++ it_; 00670 return *this; 00671 } 00672 BOOST_UBLAS_INLINE 00673 indexed_iterator &operator -- () { 00674 -- it_; 00675 return *this; 00676 } 00677 BOOST_UBLAS_INLINE 00678 indexed_iterator &operator += (difference_type n) { 00679 it_ += n; 00680 return *this; 00681 } 00682 BOOST_UBLAS_INLINE 00683 indexed_iterator &operator -= (difference_type n) { 00684 it_ -= n; 00685 return *this; 00686 } 00687 BOOST_UBLAS_INLINE 00688 difference_type operator - (const indexed_iterator &it) const { 00689 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00690 return it_ - it.it_; 00691 } 00692 00693 // Dereference 00694 BOOST_UBLAS_INLINE 00695 reference operator * () const { 00696 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); 00697 return (*this) () (it_); 00698 } 00699 BOOST_UBLAS_INLINE 00700 reference operator [] (difference_type n) const { 00701 return *((*this) + n); 00702 } 00703 00704 // Index 00705 BOOST_UBLAS_INLINE 00706 size_type index () const { 00707 return it_; 00708 } 00709 00710 // Assignment 00711 BOOST_UBLAS_INLINE 00712 indexed_iterator &operator = (const indexed_iterator &it) { 00713 // FIX: ICC needs full qualification?! 00714 // assign (&it ()); 00715 container_reference<C>::assign (&it ()); 00716 it_ = it.it_; 00717 return *this; 00718 } 00719 00720 // Comparison 00721 BOOST_UBLAS_INLINE 00722 bool operator == (const indexed_iterator &it) const { 00723 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00724 return it_ == it.it_; 00725 } 00726 BOOST_UBLAS_INLINE 00727 bool operator < (const indexed_iterator &it) const { 00728 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00729 return it_ < it.it_; 00730 } 00731 00732 private: 00733 size_type it_; 00734 }; 00735 00751 template<class C, class IC> 00752 class indexed_const_iterator: 00753 public container_const_reference<C>, 00754 public random_access_iterator_base<IC, 00755 indexed_const_iterator<C, IC>, 00756 typename C::value_type, 00757 typename C::difference_type> { 00758 public: 00759 typedef C container_type; 00760 typedef IC iterator_category; 00761 typedef typename container_type::size_type size_type; 00762 typedef typename container_type::difference_type difference_type; 00763 typedef typename container_type::value_type value_type; 00764 typedef typename container_type::const_reference reference; 00765 typedef indexed_iterator<container_type, iterator_category> iterator_type; 00766 00767 // Construction and destruction 00768 BOOST_UBLAS_INLINE 00769 indexed_const_iterator (): 00770 container_const_reference<container_type> (), it_ () {} 00771 BOOST_UBLAS_INLINE 00772 indexed_const_iterator (const container_type &c, size_type it): 00773 container_const_reference<container_type> (c), it_ (it) {} 00774 BOOST_UBLAS_INLINE 00775 indexed_const_iterator (const iterator_type &it): 00776 container_const_reference<container_type> (it ()), it_ (it.index ()) {} 00777 00778 // Arithmetic 00779 BOOST_UBLAS_INLINE 00780 indexed_const_iterator &operator ++ () { 00781 ++ it_; 00782 return *this; 00783 } 00784 BOOST_UBLAS_INLINE 00785 indexed_const_iterator &operator -- () { 00786 -- it_; 00787 return *this; 00788 } 00789 BOOST_UBLAS_INLINE 00790 indexed_const_iterator &operator += (difference_type n) { 00791 it_ += n; 00792 return *this; 00793 } 00794 BOOST_UBLAS_INLINE 00795 indexed_const_iterator &operator -= (difference_type n) { 00796 it_ -= n; 00797 return *this; 00798 } 00799 BOOST_UBLAS_INLINE 00800 difference_type operator - (const indexed_const_iterator &it) const { 00801 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00802 return it_ - it.it_; 00803 } 00804 00805 // Dereference 00806 BOOST_UBLAS_INLINE 00807 reference operator * () const { 00808 BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ()); 00809 return (*this) () (it_); 00810 } 00811 BOOST_UBLAS_INLINE 00812 reference operator [] (difference_type n) const { 00813 return *((*this) + n); 00814 } 00815 00816 // Index 00817 BOOST_UBLAS_INLINE 00818 size_type index () const { 00819 return it_; 00820 } 00821 00822 // Assignment 00823 BOOST_UBLAS_INLINE 00824 indexed_const_iterator &operator = (const indexed_const_iterator &it) { 00825 // FIX: ICC needs full qualification?! 00826 // assign (&it ()); 00827 container_const_reference<C>::assign (&it ()); 00828 it_ = it.it_; 00829 return *this; 00830 } 00831 00832 // Comparison 00833 BOOST_UBLAS_INLINE 00834 bool operator == (const indexed_const_iterator &it) const { 00835 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00836 return it_ == it.it_; 00837 } 00838 BOOST_UBLAS_INLINE 00839 bool operator < (const indexed_const_iterator &it) const { 00840 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00841 return it_ < it.it_; 00842 } 00843 00844 private: 00845 size_type it_; 00846 00847 friend class indexed_iterator<container_type, iterator_category>; 00848 }; 00849 00850 template<class C, class IC> 00851 class indexed_iterator2; 00852 00871 template<class C, class IC> 00872 class indexed_iterator1: 00873 public container_reference<C>, 00874 public random_access_iterator_base<IC, 00875 indexed_iterator1<C, IC>, 00876 typename C::value_type, 00877 typename C::difference_type> { 00878 public: 00879 typedef C container_type; 00880 typedef IC iterator_category; 00881 typedef typename container_type::size_type size_type; 00882 typedef typename container_type::difference_type difference_type; 00883 typedef typename container_type::value_type value_type; 00884 typedef typename container_type::reference reference; 00885 00886 typedef indexed_iterator2<container_type, iterator_category> dual_iterator_type; 00887 typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type; 00888 00889 // Construction and destruction 00890 BOOST_UBLAS_INLINE 00891 indexed_iterator1 (): 00892 container_reference<container_type> (), it1_ (), it2_ () {} 00893 BOOST_UBLAS_INLINE 00894 indexed_iterator1 (container_type &c, size_type it1, size_type it2): 00895 container_reference<container_type> (c), it1_ (it1), it2_ (it2) {} 00896 00897 // Arithmetic 00898 BOOST_UBLAS_INLINE 00899 indexed_iterator1 &operator ++ () { 00900 ++ it1_; 00901 return *this; 00902 } 00903 BOOST_UBLAS_INLINE 00904 indexed_iterator1 &operator -- () { 00905 -- it1_; 00906 return *this; 00907 } 00908 BOOST_UBLAS_INLINE 00909 indexed_iterator1 &operator += (difference_type n) { 00910 it1_ += n; 00911 return *this; 00912 } 00913 BOOST_UBLAS_INLINE 00914 indexed_iterator1 &operator -= (difference_type n) { 00915 it1_ -= n; 00916 return *this; 00917 } 00918 BOOST_UBLAS_INLINE 00919 difference_type operator - (const indexed_iterator1 &it) const { 00920 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00921 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00922 return it1_ - it.it1_; 00923 } 00924 00925 // Dereference 00926 BOOST_UBLAS_INLINE 00927 reference operator * () const { 00928 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 00929 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 00930 return (*this) () (it1_, it2_); 00931 } 00932 BOOST_UBLAS_INLINE 00933 reference operator [] (difference_type n) const { 00934 return *((*this) + n); 00935 } 00936 00937 // Index 00938 BOOST_UBLAS_INLINE 00939 size_type index1 () const { 00940 return it1_; 00941 } 00942 BOOST_UBLAS_INLINE 00943 size_type index2 () const { 00944 return it2_; 00945 } 00946 00947 BOOST_UBLAS_INLINE 00948 dual_iterator_type begin () const { 00949 return (*this) ().find2 (1, index1 (), 0); 00950 } 00951 BOOST_UBLAS_INLINE 00952 dual_iterator_type end () const { 00953 return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); 00954 } 00955 BOOST_UBLAS_INLINE 00956 dual_reverse_iterator_type rbegin () const { 00957 return dual_reverse_iterator_type (end ()); 00958 } 00959 BOOST_UBLAS_INLINE 00960 dual_reverse_iterator_type rend () const { 00961 return dual_reverse_iterator_type (begin ()); 00962 } 00963 00964 // Assignment 00965 BOOST_UBLAS_INLINE 00966 indexed_iterator1 &operator = (const indexed_iterator1 &it) { 00967 // FIX: ICC needs full qualification?! 00968 // assign (&it ()); 00969 container_reference<C>::assign (&it ()); 00970 it1_ = it.it1_; 00971 it2_ = it.it2_; 00972 return *this; 00973 } 00974 00975 // Comparison 00976 BOOST_UBLAS_INLINE 00977 bool operator == (const indexed_iterator1 &it) const { 00978 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00979 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00980 return it1_ == it.it1_; 00981 } 00982 BOOST_UBLAS_INLINE 00983 bool operator < (const indexed_iterator1 &it) const { 00984 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00985 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00986 return it1_ < it.it1_; 00987 } 00988 00989 private: 00990 size_type it1_; 00991 size_type it2_; 00992 }; 00993 00994 template<class C, class IC> 00995 class indexed_const_iterator2; 00996 01017 template<class C, class IC> 01018 class indexed_const_iterator1: 01019 public container_const_reference<C>, 01020 public random_access_iterator_base<IC, 01021 indexed_const_iterator1<C, IC>, 01022 typename C::value_type, 01023 typename C::difference_type> { 01024 public: 01025 typedef C container_type; 01026 typedef IC iterator_category; 01027 typedef typename container_type::size_type size_type; 01028 typedef typename container_type::difference_type difference_type; 01029 typedef typename container_type::value_type value_type; 01030 typedef typename container_type::const_reference reference; 01031 01032 typedef indexed_iterator1<container_type, iterator_category> iterator_type; 01033 typedef indexed_const_iterator2<container_type, iterator_category> dual_iterator_type; 01034 typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type; 01035 01036 // Construction and destruction 01037 BOOST_UBLAS_INLINE 01038 indexed_const_iterator1 (): 01039 container_const_reference<container_type> (), it1_ (), it2_ () {} 01040 BOOST_UBLAS_INLINE 01041 indexed_const_iterator1 (const container_type &c, size_type it1, size_type it2): 01042 container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {} 01043 BOOST_UBLAS_INLINE 01044 indexed_const_iterator1 (const iterator_type &it): 01045 container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {} 01046 01047 // Arithmetic 01048 BOOST_UBLAS_INLINE 01049 indexed_const_iterator1 &operator ++ () { 01050 ++ it1_; 01051 return *this; 01052 } 01053 BOOST_UBLAS_INLINE 01054 indexed_const_iterator1 &operator -- () { 01055 -- it1_; 01056 return *this; 01057 } 01058 BOOST_UBLAS_INLINE 01059 indexed_const_iterator1 &operator += (difference_type n) { 01060 it1_ += n; 01061 return *this; 01062 } 01063 BOOST_UBLAS_INLINE 01064 indexed_const_iterator1 &operator -= (difference_type n) { 01065 it1_ -= n; 01066 return *this; 01067 } 01068 BOOST_UBLAS_INLINE 01069 difference_type operator - (const indexed_const_iterator1 &it) const { 01070 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01071 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 01072 return it1_ - it.it1_; 01073 } 01074 01075 // Dereference 01076 BOOST_UBLAS_INLINE 01077 reference operator * () const { 01078 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 01079 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 01080 return (*this) () (it1_, it2_); 01081 } 01082 BOOST_UBLAS_INLINE 01083 reference operator [] (difference_type n) const { 01084 return *((*this) + n); 01085 } 01086 01087 // Index 01088 BOOST_UBLAS_INLINE 01089 size_type index1 () const { 01090 return it1_; 01091 } 01092 BOOST_UBLAS_INLINE 01093 size_type index2 () const { 01094 return it2_; 01095 } 01096 01097 BOOST_UBLAS_INLINE 01098 dual_iterator_type begin () const { 01099 return (*this) ().find2 (1, index1 (), 0); 01100 } 01101 BOOST_UBLAS_INLINE 01102 dual_iterator_type end () const { 01103 return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); 01104 } 01105 BOOST_UBLAS_INLINE 01106 dual_reverse_iterator_type rbegin () const { 01107 return dual_reverse_iterator_type (end ()); 01108 } 01109 BOOST_UBLAS_INLINE 01110 dual_reverse_iterator_type rend () const { 01111 return dual_reverse_iterator_type (begin ()); 01112 } 01113 01114 // Assignment 01115 BOOST_UBLAS_INLINE 01116 indexed_const_iterator1 &operator = (const indexed_const_iterator1 &it) { 01117 // FIX: ICC needs full qualification?! 01118 // assign (&it ()); 01119 container_const_reference<C>::assign (&it ()); 01120 it1_ = it.it1_; 01121 it2_ = it.it2_; 01122 return *this; 01123 } 01124 01125 // Comparison 01126 BOOST_UBLAS_INLINE 01127 bool operator == (const indexed_const_iterator1 &it) const { 01128 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01129 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 01130 return it1_ == it.it1_; 01131 } 01132 BOOST_UBLAS_INLINE 01133 bool operator < (const indexed_const_iterator1 &it) const { 01134 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01135 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 01136 return it1_ < it.it1_; 01137 } 01138 01139 private: 01140 size_type it1_; 01141 size_type it2_; 01142 01143 friend class indexed_iterator1<container_type, iterator_category>; 01144 }; 01145 01162 template<class C, class IC> 01163 class indexed_iterator2: 01164 public container_reference<C>, 01165 public random_access_iterator_base<IC, 01166 indexed_iterator2<C, IC>, 01167 typename C::value_type, 01168 typename C::difference_type> { 01169 public: 01170 typedef C container_type; 01171 typedef IC iterator_category; 01172 typedef typename container_type::size_type size_type; 01173 typedef typename container_type::difference_type difference_type; 01174 typedef typename container_type::value_type value_type; 01175 typedef typename container_type::reference reference; 01176 01177 typedef indexed_iterator1<container_type, iterator_category> dual_iterator_type; 01178 typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type; 01179 01180 // Construction and destruction 01181 BOOST_UBLAS_INLINE 01182 indexed_iterator2 (): 01183 container_reference<container_type> (), it1_ (), it2_ () {} 01184 BOOST_UBLAS_INLINE 01185 indexed_iterator2 (container_type &c, size_type it1, size_type it2): 01186 container_reference<container_type> (c), it1_ (it1), it2_ (it2) {} 01187 01188 // Arithmetic 01189 BOOST_UBLAS_INLINE 01190 indexed_iterator2 &operator ++ () { 01191 ++ it2_; 01192 return *this; 01193 } 01194 BOOST_UBLAS_INLINE 01195 indexed_iterator2 &operator -- () { 01196 -- it2_; 01197 return *this; 01198 } 01199 BOOST_UBLAS_INLINE 01200 indexed_iterator2 &operator += (difference_type n) { 01201 it2_ += n; 01202 return *this; 01203 } 01204 BOOST_UBLAS_INLINE 01205 indexed_iterator2 &operator -= (difference_type n) { 01206 it2_ -= n; 01207 return *this; 01208 } 01209 BOOST_UBLAS_INLINE 01210 difference_type operator - (const indexed_iterator2 &it) const { 01211 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01212 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 01213 return it2_ - it.it2_; 01214 } 01215 01216 // Dereference 01217 BOOST_UBLAS_INLINE 01218 reference operator * () const { 01219 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 01220 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 01221 return (*this) () (it1_, it2_); 01222 } 01223 BOOST_UBLAS_INLINE 01224 reference operator [] (difference_type n) const { 01225 return *((*this) + n); 01226 } 01227 01228 // Index 01229 BOOST_UBLAS_INLINE 01230 size_type index1 () const { 01231 return it1_; 01232 } 01233 BOOST_UBLAS_INLINE 01234 size_type index2 () const { 01235 return it2_; 01236 } 01237 01238 BOOST_UBLAS_INLINE 01239 dual_iterator_type begin () const { 01240 return (*this) ().find1 (1, 0, index2 ()); 01241 } 01242 BOOST_UBLAS_INLINE 01243 dual_iterator_type end () const { 01244 return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); 01245 } 01246 BOOST_UBLAS_INLINE 01247 dual_reverse_iterator_type rbegin () const { 01248 return dual_reverse_iterator_type (end ()); 01249 } 01250 BOOST_UBLAS_INLINE 01251 dual_reverse_iterator_type rend () const { 01252 return dual_reverse_iterator_type (begin ()); 01253 } 01254 01255 // Assignment 01256 BOOST_UBLAS_INLINE 01257 indexed_iterator2 &operator = (const indexed_iterator2 &it) { 01258 // FIX: ICC needs full qualification?! 01259 // assign (&it ()); 01260 container_reference<C>::assign (&it ()); 01261 it1_ = it.it1_; 01262 it2_ = it.it2_; 01263 return *this; 01264 } 01265 01266 // Comparison 01267 BOOST_UBLAS_INLINE 01268 bool operator == (const indexed_iterator2 &it) const { 01269 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01270 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 01271 return it2_ == it.it2_; 01272 } 01273 BOOST_UBLAS_INLINE 01274 bool operator < (const indexed_iterator2 &it) const { 01275 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01276 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 01277 return it2_ < it.it2_; 01278 } 01279 01280 private: 01281 size_type it1_; 01282 size_type it2_; 01283 }; 01284 01305 template<class C, class IC> 01306 class indexed_const_iterator2: 01307 public container_const_reference<C>, 01308 public random_access_iterator_base<IC, 01309 indexed_const_iterator2<C, IC>, 01310 typename C::value_type, 01311 typename C::difference_type> { 01312 public: 01313 typedef C container_type; 01314 typedef IC iterator_category; 01315 typedef typename container_type::size_type size_type; 01316 typedef typename container_type::difference_type difference_type; 01317 typedef typename container_type::value_type value_type; 01318 typedef typename container_type::const_reference reference; 01319 01320 typedef indexed_iterator2<container_type, iterator_category> iterator_type; 01321 typedef indexed_const_iterator1<container_type, iterator_category> dual_iterator_type; 01322 typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type; 01323 01324 // Construction and destruction 01325 BOOST_UBLAS_INLINE 01326 indexed_const_iterator2 (): 01327 container_const_reference<container_type> (), it1_ (), it2_ () {} 01328 BOOST_UBLAS_INLINE 01329 indexed_const_iterator2 (const container_type &c, size_type it1, size_type it2): 01330 container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {} 01331 BOOST_UBLAS_INLINE 01332 indexed_const_iterator2 (const iterator_type &it): 01333 container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {} 01334 01335 // Arithmetic 01336 BOOST_UBLAS_INLINE 01337 indexed_const_iterator2 &operator ++ () { 01338 ++ it2_; 01339 return *this; 01340 } 01341 BOOST_UBLAS_INLINE 01342 indexed_const_iterator2 &operator -- () { 01343 -- it2_; 01344 return *this; 01345 } 01346 BOOST_UBLAS_INLINE 01347 indexed_const_iterator2 &operator += (difference_type n) { 01348 it2_ += n; 01349 return *this; 01350 } 01351 BOOST_UBLAS_INLINE 01352 indexed_const_iterator2 &operator -= (difference_type n) { 01353 it2_ -= n; 01354 return *this; 01355 } 01356 BOOST_UBLAS_INLINE 01357 difference_type operator - (const indexed_const_iterator2 &it) const { 01358 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01359 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 01360 return it2_ - it.it2_; 01361 } 01362 01363 // Dereference 01364 BOOST_UBLAS_INLINE 01365 reference operator * () const { 01366 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 01367 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 01368 return (*this) () (it1_, it2_); 01369 } 01370 BOOST_UBLAS_INLINE 01371 reference operator [] (difference_type n) const { 01372 return *((*this) + n); 01373 } 01374 01375 // Index 01376 BOOST_UBLAS_INLINE 01377 size_type index1 () const { 01378 return it1_; 01379 } 01380 BOOST_UBLAS_INLINE 01381 size_type index2 () const { 01382 return it2_; 01383 } 01384 01385 BOOST_UBLAS_INLINE 01386 dual_iterator_type begin () const { 01387 return (*this) ().find1 (1, 0, index2 ()); 01388 } 01389 BOOST_UBLAS_INLINE 01390 dual_iterator_type end () const { 01391 return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); 01392 } 01393 BOOST_UBLAS_INLINE 01394 dual_reverse_iterator_type rbegin () const { 01395 return dual_reverse_iterator_type (end ()); 01396 } 01397 BOOST_UBLAS_INLINE 01398 dual_reverse_iterator_type rend () const { 01399 return dual_reverse_iterator_type (begin ()); 01400 } 01401 01402 // Assignment 01403 BOOST_UBLAS_INLINE 01404 indexed_const_iterator2 &operator = (const indexed_const_iterator2 &it) { 01405 // FIX: ICC needs full qualification?! 01406 // assign (&it ()); 01407 container_const_reference<C>::assign (&it ()); 01408 it1_ = it.it1_; 01409 it2_ = it.it2_; 01410 return *this; 01411 } 01412 01413 // Comparison 01414 BOOST_UBLAS_INLINE 01415 bool operator == (const indexed_const_iterator2 &it) const { 01416 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01417 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 01418 return it2_ == it.it2_; 01419 } 01420 BOOST_UBLAS_INLINE 01421 bool operator < (const indexed_const_iterator2 &it) const { 01422 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01423 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 01424 return it2_ < it.it2_; 01425 } 01426 01427 private: 01428 size_type it1_; 01429 size_type it2_; 01430 01431 friend class indexed_iterator2<container_type, iterator_category>; 01432 }; 01433 01434 }}} 01435 01436 #endif