...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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_BANDED_ 00014 #define _BOOST_UBLAS_BANDED_ 00015 00016 #include <boost/numeric/ublas/matrix.hpp> 00017 #include <boost/numeric/ublas/detail/temporary.hpp> 00018 00019 // Iterators based on ideas of Jeremy Siek 00020 00021 namespace boost { namespace numeric { namespace ublas { 00022 00035 template<class T, class L, class A> 00036 class banded_matrix: 00037 public matrix_container<banded_matrix<T, L, A> > { 00038 00039 typedef T *pointer; 00040 typedef L layout_type; 00041 typedef banded_matrix<T, L, A> self_type; 00042 public: 00043 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 00044 using matrix_container<self_type>::operator (); 00045 #endif 00046 typedef typename A::size_type size_type; 00047 typedef typename A::difference_type difference_type; 00048 typedef T value_type; 00049 typedef const T &const_reference; 00050 typedef T &reference; 00051 typedef A array_type; 00052 typedef const matrix_reference<const self_type> const_closure_type; 00053 typedef matrix_reference<self_type> closure_type; 00054 typedef vector<T, A> vector_temporary_type; 00055 typedef matrix<T, L, A> matrix_temporary_type; // general sub-matrix 00056 typedef packed_tag storage_category; 00057 typedef typename L::orientation_category orientation_category; 00058 00059 // Construction and destruction 00060 BOOST_UBLAS_INLINE 00061 banded_matrix (): 00062 matrix_container<self_type> (), 00063 size1_ (0), size2_ (0), 00064 lower_ (0), upper_ (0), data_ (0) {} 00065 BOOST_UBLAS_INLINE 00066 banded_matrix (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0): 00067 matrix_container<self_type> (), 00068 size1_ (size1), size2_ (size2), 00069 lower_ (lower), upper_ (upper), data_ ((std::max) (size1, size2) * (lower + 1 + upper)) { 00070 } 00071 BOOST_UBLAS_INLINE 00072 banded_matrix (size_type size1, size_type size2, size_type lower, size_type upper, const array_type &data): 00073 matrix_container<self_type> (), 00074 size1_ (size1), size2_ (size2), 00075 lower_ (lower), upper_ (upper), data_ (data) {} 00076 BOOST_UBLAS_INLINE 00077 banded_matrix (const banded_matrix &m): 00078 matrix_container<self_type> (), 00079 size1_ (m.size1_), size2_ (m.size2_), 00080 lower_ (m.lower_), upper_ (m.upper_), data_ (m.data_) {} 00081 template<class AE> 00082 BOOST_UBLAS_INLINE 00083 banded_matrix (const matrix_expression<AE> &ae, size_type lower = 0, size_type upper = 0): 00084 matrix_container<self_type> (), 00085 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), 00086 lower_ (lower), upper_ (upper), 00087 data_ ((std::max) (size1_, size2_) * (lower_ + 1 + upper_)) { 00088 matrix_assign<scalar_assign> (*this, ae); 00089 } 00090 00091 // Accessors 00092 BOOST_UBLAS_INLINE 00093 size_type size1 () const { 00094 return size1_; 00095 } 00096 BOOST_UBLAS_INLINE 00097 size_type size2 () const { 00098 return size2_; 00099 } 00100 BOOST_UBLAS_INLINE 00101 size_type lower () const { 00102 return lower_; 00103 } 00104 BOOST_UBLAS_INLINE 00105 size_type upper () const { 00106 return upper_; 00107 } 00108 00109 // Storage accessors 00110 BOOST_UBLAS_INLINE 00111 const array_type &data () const { 00112 return data_; 00113 } 00114 BOOST_UBLAS_INLINE 00115 array_type &data () { 00116 return data_; 00117 } 00118 00119 // Resizing 00120 BOOST_UBLAS_INLINE 00121 void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) { 00122 if (preserve) { 00123 self_type temporary (size1, size2, lower, upper); 00124 detail::matrix_resize_preserve<layout_type> (*this, temporary); 00125 } 00126 else { 00127 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper)); 00128 size1_ = size1; 00129 size2_ = size2; 00130 lower_ = lower; 00131 upper_ = upper; 00132 } 00133 } 00134 00135 BOOST_UBLAS_INLINE 00136 void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) { 00137 size1_ = size1; 00138 size2_ = size2; 00139 lower_ = lower; 00140 upper_ = upper; 00141 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ()); 00142 } 00143 00144 // Element access 00145 BOOST_UBLAS_INLINE 00146 const_reference operator () (size_type i, size_type j) const { 00147 BOOST_UBLAS_CHECK (i < size1_, bad_index ()); 00148 BOOST_UBLAS_CHECK (j < size2_, bad_index ()); 00149 #ifdef BOOST_UBLAS_OWN_BANDED 00150 const size_type k = (std::max) (i, j); 00151 const size_type l = lower_ + j - i; 00152 if (k < (std::max) (size1_, size2_) && 00153 l < lower_ + 1 + upper_) 00154 return data () [layout_type::element (k, (std::max) (size1_, size2_), 00155 l, lower_ + 1 + upper_)]; 00156 #else 00157 const size_type k = j; 00158 const size_type l = upper_ + i - j; 00159 if (k < size2_ && 00160 l < lower_ + 1 + upper_) 00161 return data () [layout_type::element (k, size2_, 00162 l, lower_ + 1 + upper_)]; 00163 #endif 00164 return zero_; 00165 } 00166 BOOST_UBLAS_INLINE 00167 reference at_element (size_type i, size_type j) { 00168 BOOST_UBLAS_CHECK (i < size1_, bad_index ()); 00169 BOOST_UBLAS_CHECK (j < size2_, bad_index ()); 00170 #ifdef BOOST_UBLAS_OWN_BANDED 00171 const size_type k = (std::max) (i, j); 00172 const size_type l = lower_ + j - i; 00173 return data () [layout_type::element (k, (std::max) (size1_, size2_), 00174 l, lower_ + 1 + upper_)]; 00175 #else 00176 const size_type k = j; 00177 const size_type l = upper_ + i - j; 00178 return data () [layout_type::element (k, size2_, 00179 l, lower_ + 1 + upper_)]; 00180 #endif 00181 } 00182 BOOST_UBLAS_INLINE 00183 reference operator () (size_type i, size_type j) { 00184 BOOST_UBLAS_CHECK (i < size1_, bad_index ()); 00185 BOOST_UBLAS_CHECK (j < size2_, bad_index ()); 00186 #ifdef BOOST_UBLAS_OWN_BANDED 00187 const size_type k = (std::max) (i, j); 00188 const size_type l = lower_ + j - i; 00189 if (! (k < (std::max) (size1_, size2_) && 00190 l < lower_ + 1 + upper_) ) { 00191 bad_index ().raise (); 00192 // NEVER reached 00193 } 00194 return data () [layout_type::element (k, (std::max) (size1_, size2_), 00195 l, lower_ + 1 + upper_)]; 00196 #else 00197 const size_type k = j; 00198 const size_type l = upper_ + i - j; 00199 if (! (k < size2_ && 00200 l < lower_ + 1 + upper_) ) { 00201 bad_index ().raise (); 00202 // NEVER reached 00203 } 00204 return data () [layout_type::element (k, size2_, 00205 l, lower_ + 1 + upper_)]; 00206 #endif 00207 } 00208 00209 // Element assignment 00210 BOOST_UBLAS_INLINE 00211 reference insert_element (size_type i, size_type j, const_reference t) { 00212 return (operator () (i, j) = t); 00213 } 00214 BOOST_UBLAS_INLINE 00215 void erase_element (size_type i, size_type j) { 00216 operator () (i, j) = value_type/*zero*/(); 00217 } 00218 00219 // Zeroing 00220 BOOST_UBLAS_INLINE 00221 void clear () { 00222 std::fill (data ().begin (), data ().end (), value_type/*zero*/()); 00223 } 00224 00225 // Assignment 00226 BOOST_UBLAS_INLINE 00227 banded_matrix &operator = (const banded_matrix &m) { 00228 size1_ = m.size1_; 00229 size2_ = m.size2_; 00230 lower_ = m.lower_; 00231 upper_ = m.upper_; 00232 data () = m.data (); 00233 return *this; 00234 } 00235 BOOST_UBLAS_INLINE 00236 banded_matrix &assign_temporary (banded_matrix &m) { 00237 swap (m); 00238 return *this; 00239 } 00240 template<class AE> 00241 BOOST_UBLAS_INLINE 00242 banded_matrix &operator = (const matrix_expression<AE> &ae) { 00243 self_type temporary (ae, lower_, upper_); 00244 return assign_temporary (temporary); 00245 } 00246 template<class AE> 00247 BOOST_UBLAS_INLINE 00248 banded_matrix &assign (const matrix_expression<AE> &ae) { 00249 matrix_assign<scalar_assign> (*this, ae); 00250 return *this; 00251 } 00252 template<class AE> 00253 BOOST_UBLAS_INLINE 00254 banded_matrix& operator += (const matrix_expression<AE> &ae) { 00255 self_type temporary (*this + ae, lower_, upper_); 00256 return assign_temporary (temporary); 00257 } 00258 template<class AE> 00259 BOOST_UBLAS_INLINE 00260 banded_matrix &plus_assign (const matrix_expression<AE> &ae) { 00261 matrix_assign<scalar_plus_assign> (*this, ae); 00262 return *this; 00263 } 00264 template<class AE> 00265 BOOST_UBLAS_INLINE 00266 banded_matrix& operator -= (const matrix_expression<AE> &ae) { 00267 self_type temporary (*this - ae, lower_, upper_); 00268 return assign_temporary (temporary); 00269 } 00270 template<class AE> 00271 BOOST_UBLAS_INLINE 00272 banded_matrix &minus_assign (const matrix_expression<AE> &ae) { 00273 matrix_assign<scalar_minus_assign> (*this, ae); 00274 return *this; 00275 } 00276 template<class AT> 00277 BOOST_UBLAS_INLINE 00278 banded_matrix& operator *= (const AT &at) { 00279 matrix_assign_scalar<scalar_multiplies_assign> (*this, at); 00280 return *this; 00281 } 00282 template<class AT> 00283 BOOST_UBLAS_INLINE 00284 banded_matrix& operator /= (const AT &at) { 00285 matrix_assign_scalar<scalar_divides_assign> (*this, at); 00286 return *this; 00287 } 00288 00289 // Swapping 00290 BOOST_UBLAS_INLINE 00291 void swap (banded_matrix &m) { 00292 if (this != &m) { 00293 std::swap (size1_, m.size1_); 00294 std::swap (size2_, m.size2_); 00295 std::swap (lower_, m.lower_); 00296 std::swap (upper_, m.upper_); 00297 data ().swap (m.data ()); 00298 } 00299 } 00300 BOOST_UBLAS_INLINE 00301 friend void swap (banded_matrix &m1, banded_matrix &m2) { 00302 m1.swap (m2); 00303 } 00304 00305 // Iterator types 00306 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00307 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1; 00308 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2; 00309 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1; 00310 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2; 00311 #else 00312 class const_iterator1; 00313 class iterator1; 00314 class const_iterator2; 00315 class iterator2; 00316 #endif 00317 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 00318 typedef reverse_iterator_base1<iterator1> reverse_iterator1; 00319 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 00320 typedef reverse_iterator_base2<iterator2> reverse_iterator2; 00321 00322 // Element lookup 00323 BOOST_UBLAS_INLINE 00324 const_iterator1 find1 (int rank, size_type i, size_type j) const { 00325 if (rank == 1) { 00326 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0)); 00327 i = (std::max) (i, lower_i); 00328 size_type upper_i = (std::min) (j + 1 + lower_, size1_); 00329 i = (std::min) (i, upper_i); 00330 } 00331 return const_iterator1 (*this, i, j); 00332 } 00333 BOOST_UBLAS_INLINE 00334 iterator1 find1 (int rank, size_type i, size_type j) { 00335 if (rank == 1) { 00336 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0)); 00337 i = (std::max) (i, lower_i); 00338 size_type upper_i = (std::min) (j + 1 + lower_, size1_); 00339 i = (std::min) (i, upper_i); 00340 } 00341 return iterator1 (*this, i, j); 00342 } 00343 BOOST_UBLAS_INLINE 00344 const_iterator2 find2 (int rank, size_type i, size_type j) const { 00345 if (rank == 1) { 00346 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0)); 00347 j = (std::max) (j, lower_j); 00348 size_type upper_j = (std::min) (i + 1 + upper_, size2_); 00349 j = (std::min) (j, upper_j); 00350 } 00351 return const_iterator2 (*this, i, j); 00352 } 00353 BOOST_UBLAS_INLINE 00354 iterator2 find2 (int rank, size_type i, size_type j) { 00355 if (rank == 1) { 00356 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0)); 00357 j = (std::max) (j, lower_j); 00358 size_type upper_j = (std::min) (i + 1 + upper_, size2_); 00359 j = (std::min) (j, upper_j); 00360 } 00361 return iterator2 (*this, i, j); 00362 } 00363 00364 // Iterators simply are indices. 00365 00366 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00367 class const_iterator1: 00368 public container_const_reference<banded_matrix>, 00369 public random_access_iterator_base<packed_random_access_iterator_tag, 00370 const_iterator1, value_type> { 00371 public: 00372 typedef typename banded_matrix::value_type value_type; 00373 typedef typename banded_matrix::difference_type difference_type; 00374 typedef typename banded_matrix::const_reference reference; 00375 typedef const typename banded_matrix::pointer pointer; 00376 00377 typedef const_iterator2 dual_iterator_type; 00378 typedef const_reverse_iterator2 dual_reverse_iterator_type; 00379 00380 // Construction and destruction 00381 BOOST_UBLAS_INLINE 00382 const_iterator1 (): 00383 container_const_reference<self_type> (), it1_ (), it2_ () {} 00384 BOOST_UBLAS_INLINE 00385 const_iterator1 (const self_type &m, size_type it1, size_type it2): 00386 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {} 00387 BOOST_UBLAS_INLINE 00388 const_iterator1 (const iterator1 &it): 00389 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 00390 00391 // Arithmetic 00392 BOOST_UBLAS_INLINE 00393 const_iterator1 &operator ++ () { 00394 ++ it1_; 00395 return *this; 00396 } 00397 BOOST_UBLAS_INLINE 00398 const_iterator1 &operator -- () { 00399 -- it1_; 00400 return *this; 00401 } 00402 BOOST_UBLAS_INLINE 00403 const_iterator1 &operator += (difference_type n) { 00404 it1_ += n; 00405 return *this; 00406 } 00407 BOOST_UBLAS_INLINE 00408 const_iterator1 &operator -= (difference_type n) { 00409 it1_ -= n; 00410 return *this; 00411 } 00412 BOOST_UBLAS_INLINE 00413 difference_type operator - (const const_iterator1 &it) const { 00414 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00415 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00416 return it1_ - it.it1_; 00417 } 00418 00419 // Dereference 00420 BOOST_UBLAS_INLINE 00421 const_reference operator * () const { 00422 return (*this) () (it1_, it2_); 00423 } 00424 BOOST_UBLAS_INLINE 00425 const_reference operator [] (difference_type n) const { 00426 return *(*this + n); 00427 } 00428 00429 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 00430 BOOST_UBLAS_INLINE 00431 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00432 typename self_type:: 00433 #endif 00434 const_iterator2 begin () const { 00435 return (*this) ().find2 (1, it1_, 0); 00436 } 00437 BOOST_UBLAS_INLINE 00438 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00439 typename self_type:: 00440 #endif 00441 const_iterator2 end () const { 00442 return (*this) ().find2 (1, it1_, (*this) ().size2 ()); 00443 } 00444 BOOST_UBLAS_INLINE 00445 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00446 typename self_type:: 00447 #endif 00448 const_reverse_iterator2 rbegin () const { 00449 return const_reverse_iterator2 (end ()); 00450 } 00451 BOOST_UBLAS_INLINE 00452 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00453 typename self_type:: 00454 #endif 00455 const_reverse_iterator2 rend () const { 00456 return const_reverse_iterator2 (begin ()); 00457 } 00458 #endif 00459 00460 // Indices 00461 BOOST_UBLAS_INLINE 00462 size_type index1 () const { 00463 return it1_; 00464 } 00465 BOOST_UBLAS_INLINE 00466 size_type index2 () const { 00467 return it2_; 00468 } 00469 00470 // Assignment 00471 BOOST_UBLAS_INLINE 00472 const_iterator1 &operator = (const const_iterator1 &it) { 00473 container_const_reference<self_type>::assign (&it ()); 00474 it1_ = it.it1_; 00475 it2_ = it.it2_; 00476 return *this; 00477 } 00478 00479 // Comparison 00480 BOOST_UBLAS_INLINE 00481 bool operator == (const const_iterator1 &it) const { 00482 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00483 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00484 return it1_ == it.it1_; 00485 } 00486 BOOST_UBLAS_INLINE 00487 bool operator < (const const_iterator1 &it) const { 00488 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00489 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00490 return it1_ < it.it1_; 00491 } 00492 00493 private: 00494 size_type it1_; 00495 size_type it2_; 00496 }; 00497 #endif 00498 00499 BOOST_UBLAS_INLINE 00500 const_iterator1 begin1 () const { 00501 return find1 (0, 0, 0); 00502 } 00503 BOOST_UBLAS_INLINE 00504 const_iterator1 end1 () const { 00505 return find1 (0, size1_, 0); 00506 } 00507 00508 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00509 class iterator1: 00510 public container_reference<banded_matrix>, 00511 public random_access_iterator_base<packed_random_access_iterator_tag, 00512 iterator1, value_type> { 00513 public: 00514 typedef typename banded_matrix::value_type value_type; 00515 typedef typename banded_matrix::difference_type difference_type; 00516 typedef typename banded_matrix::reference reference; 00517 typedef typename banded_matrix::pointer pointer; 00518 00519 typedef iterator2 dual_iterator_type; 00520 typedef reverse_iterator2 dual_reverse_iterator_type; 00521 00522 // Construction and destruction 00523 BOOST_UBLAS_INLINE 00524 iterator1 (): 00525 container_reference<self_type> (), it1_ (), it2_ () {} 00526 BOOST_UBLAS_INLINE 00527 iterator1 (self_type &m, size_type it1, size_type it2): 00528 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {} 00529 00530 // Arithmetic 00531 BOOST_UBLAS_INLINE 00532 iterator1 &operator ++ () { 00533 ++ it1_; 00534 return *this; 00535 } 00536 BOOST_UBLAS_INLINE 00537 iterator1 &operator -- () { 00538 -- it1_; 00539 return *this; 00540 } 00541 BOOST_UBLAS_INLINE 00542 iterator1 &operator += (difference_type n) { 00543 it1_ += n; 00544 return *this; 00545 } 00546 BOOST_UBLAS_INLINE 00547 iterator1 &operator -= (difference_type n) { 00548 it1_ -= n; 00549 return *this; 00550 } 00551 BOOST_UBLAS_INLINE 00552 difference_type operator - (const iterator1 &it) const { 00553 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00554 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00555 return it1_ - it.it1_; 00556 } 00557 00558 // Dereference 00559 BOOST_UBLAS_INLINE 00560 reference operator * () const { 00561 return (*this) ().at_element (it1_, it2_); 00562 } 00563 BOOST_UBLAS_INLINE 00564 reference operator [] (difference_type n) const { 00565 return *(*this + n); 00566 } 00567 00568 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 00569 BOOST_UBLAS_INLINE 00570 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00571 typename self_type:: 00572 #endif 00573 iterator2 begin () const { 00574 return (*this) ().find2 (1, it1_, 0); 00575 } 00576 BOOST_UBLAS_INLINE 00577 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00578 typename self_type:: 00579 #endif 00580 iterator2 end () const { 00581 return (*this) ().find2 (1, it1_, (*this) ().size2 ()); 00582 } 00583 BOOST_UBLAS_INLINE 00584 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00585 typename self_type:: 00586 #endif 00587 reverse_iterator2 rbegin () const { 00588 return reverse_iterator2 (end ()); 00589 } 00590 BOOST_UBLAS_INLINE 00591 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00592 typename self_type:: 00593 #endif 00594 reverse_iterator2 rend () const { 00595 return reverse_iterator2 (begin ()); 00596 } 00597 #endif 00598 00599 // Indices 00600 BOOST_UBLAS_INLINE 00601 size_type index1 () const { 00602 return it1_; 00603 } 00604 BOOST_UBLAS_INLINE 00605 size_type index2 () const { 00606 return it2_; 00607 } 00608 00609 // Assignment 00610 BOOST_UBLAS_INLINE 00611 iterator1 &operator = (const iterator1 &it) { 00612 container_reference<self_type>::assign (&it ()); 00613 it1_ = it.it1_; 00614 it2_ = it.it2_; 00615 return *this; 00616 } 00617 00618 // Comparison 00619 BOOST_UBLAS_INLINE 00620 bool operator == (const iterator1 &it) const { 00621 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00622 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00623 return it1_ == it.it1_; 00624 } 00625 BOOST_UBLAS_INLINE 00626 bool operator < (const iterator1 &it) const { 00627 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00628 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 00629 return it1_ < it.it1_; 00630 } 00631 00632 private: 00633 size_type it1_; 00634 size_type it2_; 00635 00636 friend class const_iterator1; 00637 }; 00638 #endif 00639 00640 BOOST_UBLAS_INLINE 00641 iterator1 begin1 () { 00642 return find1 (0, 0, 0); 00643 } 00644 BOOST_UBLAS_INLINE 00645 iterator1 end1 () { 00646 return find1 (0, size1_, 0); 00647 } 00648 00649 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00650 class const_iterator2: 00651 public container_const_reference<banded_matrix>, 00652 public random_access_iterator_base<packed_random_access_iterator_tag, 00653 const_iterator2, value_type> { 00654 public: 00655 typedef typename banded_matrix::value_type value_type; 00656 typedef typename banded_matrix::difference_type difference_type; 00657 typedef typename banded_matrix::const_reference reference; 00658 typedef const typename banded_matrix::pointer pointer; 00659 00660 typedef const_iterator1 dual_iterator_type; 00661 typedef const_reverse_iterator1 dual_reverse_iterator_type; 00662 00663 // Construction and destruction 00664 BOOST_UBLAS_INLINE 00665 const_iterator2 (): 00666 container_const_reference<self_type> (), it1_ (), it2_ () {} 00667 BOOST_UBLAS_INLINE 00668 const_iterator2 (const self_type &m, size_type it1, size_type it2): 00669 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {} 00670 BOOST_UBLAS_INLINE 00671 const_iterator2 (const iterator2 &it): 00672 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {} 00673 00674 // Arithmetic 00675 BOOST_UBLAS_INLINE 00676 const_iterator2 &operator ++ () { 00677 ++ it2_; 00678 return *this; 00679 } 00680 BOOST_UBLAS_INLINE 00681 const_iterator2 &operator -- () { 00682 -- it2_; 00683 return *this; 00684 } 00685 BOOST_UBLAS_INLINE 00686 const_iterator2 &operator += (difference_type n) { 00687 it2_ += n; 00688 return *this; 00689 } 00690 BOOST_UBLAS_INLINE 00691 const_iterator2 &operator -= (difference_type n) { 00692 it2_ -= n; 00693 return *this; 00694 } 00695 BOOST_UBLAS_INLINE 00696 difference_type operator - (const const_iterator2 &it) const { 00697 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00698 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 00699 return it2_ - it.it2_; 00700 } 00701 00702 // Dereference 00703 BOOST_UBLAS_INLINE 00704 const_reference operator * () const { 00705 return (*this) () (it1_, it2_); 00706 } 00707 BOOST_UBLAS_INLINE 00708 const_reference operator [] (difference_type n) const { 00709 return *(*this + n); 00710 } 00711 00712 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 00713 BOOST_UBLAS_INLINE 00714 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00715 typename self_type:: 00716 #endif 00717 const_iterator1 begin () const { 00718 return (*this) ().find1 (1, 0, it2_); 00719 } 00720 BOOST_UBLAS_INLINE 00721 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00722 typename self_type:: 00723 #endif 00724 const_iterator1 end () const { 00725 return (*this) ().find1 (1, (*this) ().size1 (), it2_); 00726 } 00727 BOOST_UBLAS_INLINE 00728 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00729 typename self_type:: 00730 #endif 00731 const_reverse_iterator1 rbegin () const { 00732 return const_reverse_iterator1 (end ()); 00733 } 00734 BOOST_UBLAS_INLINE 00735 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00736 typename self_type:: 00737 #endif 00738 const_reverse_iterator1 rend () const { 00739 return const_reverse_iterator1 (begin ()); 00740 } 00741 #endif 00742 00743 // Indices 00744 BOOST_UBLAS_INLINE 00745 size_type index1 () const { 00746 return it1_; 00747 } 00748 BOOST_UBLAS_INLINE 00749 size_type index2 () const { 00750 return it2_; 00751 } 00752 00753 // Assignment 00754 BOOST_UBLAS_INLINE 00755 const_iterator2 &operator = (const const_iterator2 &it) { 00756 container_const_reference<self_type>::assign (&it ()); 00757 it1_ = it.it1_; 00758 it2_ = it.it2_; 00759 return *this; 00760 } 00761 00762 // Comparison 00763 BOOST_UBLAS_INLINE 00764 bool operator == (const const_iterator2 &it) const { 00765 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00766 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 00767 return it2_ == it.it2_; 00768 } 00769 BOOST_UBLAS_INLINE 00770 bool operator < (const const_iterator2 &it) const { 00771 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00772 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 00773 return it2_ < it.it2_; 00774 } 00775 00776 private: 00777 size_type it1_; 00778 size_type it2_; 00779 }; 00780 #endif 00781 00782 BOOST_UBLAS_INLINE 00783 const_iterator2 begin2 () const { 00784 return find2 (0, 0, 0); 00785 } 00786 BOOST_UBLAS_INLINE 00787 const_iterator2 end2 () const { 00788 return find2 (0, 0, size2_); 00789 } 00790 00791 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00792 class iterator2: 00793 public container_reference<banded_matrix>, 00794 public random_access_iterator_base<packed_random_access_iterator_tag, 00795 iterator2, value_type> { 00796 public: 00797 typedef typename banded_matrix::value_type value_type; 00798 typedef typename banded_matrix::difference_type difference_type; 00799 typedef typename banded_matrix::reference reference; 00800 typedef typename banded_matrix::pointer pointer; 00801 00802 typedef iterator1 dual_iterator_type; 00803 typedef reverse_iterator1 dual_reverse_iterator_type; 00804 00805 // Construction and destruction 00806 BOOST_UBLAS_INLINE 00807 iterator2 (): 00808 container_reference<self_type> (), it1_ (), it2_ () {} 00809 BOOST_UBLAS_INLINE 00810 iterator2 (self_type &m, size_type it1, size_type it2): 00811 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {} 00812 00813 // Arithmetic 00814 BOOST_UBLAS_INLINE 00815 iterator2 &operator ++ () { 00816 ++ it2_; 00817 return *this; 00818 } 00819 BOOST_UBLAS_INLINE 00820 iterator2 &operator -- () { 00821 -- it2_; 00822 return *this; 00823 } 00824 BOOST_UBLAS_INLINE 00825 iterator2 &operator += (difference_type n) { 00826 it2_ += n; 00827 return *this; 00828 } 00829 BOOST_UBLAS_INLINE 00830 iterator2 &operator -= (difference_type n) { 00831 it2_ -= n; 00832 return *this; 00833 } 00834 BOOST_UBLAS_INLINE 00835 difference_type operator - (const iterator2 &it) const { 00836 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00837 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 00838 return it2_ - it.it2_; 00839 } 00840 00841 // Dereference 00842 BOOST_UBLAS_INLINE 00843 reference operator * () const { 00844 return (*this) ().at_element (it1_, it2_); 00845 } 00846 BOOST_UBLAS_INLINE 00847 reference operator [] (difference_type n) const { 00848 return *(*this + n); 00849 } 00850 00851 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 00852 BOOST_UBLAS_INLINE 00853 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00854 typename self_type:: 00855 #endif 00856 iterator1 begin () const { 00857 return (*this) ().find1 (1, 0, it2_); 00858 } 00859 BOOST_UBLAS_INLINE 00860 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00861 typename self_type:: 00862 #endif 00863 iterator1 end () const { 00864 return (*this) ().find1 (1, (*this) ().size1 (), it2_); 00865 } 00866 BOOST_UBLAS_INLINE 00867 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00868 typename self_type:: 00869 #endif 00870 reverse_iterator1 rbegin () const { 00871 return reverse_iterator1 (end ()); 00872 } 00873 BOOST_UBLAS_INLINE 00874 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00875 typename self_type:: 00876 #endif 00877 reverse_iterator1 rend () const { 00878 return reverse_iterator1 (begin ()); 00879 } 00880 #endif 00881 00882 // Indices 00883 BOOST_UBLAS_INLINE 00884 size_type index1 () const { 00885 return it1_; 00886 } 00887 BOOST_UBLAS_INLINE 00888 size_type index2 () const { 00889 return it2_; 00890 } 00891 00892 // Assignment 00893 BOOST_UBLAS_INLINE 00894 iterator2 &operator = (const iterator2 &it) { 00895 container_reference<self_type>::assign (&it ()); 00896 it1_ = it.it1_; 00897 it2_ = it.it2_; 00898 return *this; 00899 } 00900 00901 // Comparison 00902 BOOST_UBLAS_INLINE 00903 bool operator == (const iterator2 &it) const { 00904 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00905 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 00906 return it2_ == it.it2_; 00907 } 00908 BOOST_UBLAS_INLINE 00909 bool operator < (const iterator2 &it) const { 00910 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00911 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 00912 return it2_ < it.it2_; 00913 } 00914 00915 private: 00916 size_type it1_; 00917 size_type it2_; 00918 00919 friend class const_iterator2; 00920 }; 00921 #endif 00922 00923 BOOST_UBLAS_INLINE 00924 iterator2 begin2 () { 00925 return find2 (0, 0, 0); 00926 } 00927 BOOST_UBLAS_INLINE 00928 iterator2 end2 () { 00929 return find2 (0, 0, size2_); 00930 } 00931 00932 // Reverse iterators 00933 00934 BOOST_UBLAS_INLINE 00935 const_reverse_iterator1 rbegin1 () const { 00936 return const_reverse_iterator1 (end1 ()); 00937 } 00938 BOOST_UBLAS_INLINE 00939 const_reverse_iterator1 rend1 () const { 00940 return const_reverse_iterator1 (begin1 ()); 00941 } 00942 00943 BOOST_UBLAS_INLINE 00944 reverse_iterator1 rbegin1 () { 00945 return reverse_iterator1 (end1 ()); 00946 } 00947 BOOST_UBLAS_INLINE 00948 reverse_iterator1 rend1 () { 00949 return reverse_iterator1 (begin1 ()); 00950 } 00951 00952 BOOST_UBLAS_INLINE 00953 const_reverse_iterator2 rbegin2 () const { 00954 return const_reverse_iterator2 (end2 ()); 00955 } 00956 BOOST_UBLAS_INLINE 00957 const_reverse_iterator2 rend2 () const { 00958 return const_reverse_iterator2 (begin2 ()); 00959 } 00960 00961 BOOST_UBLAS_INLINE 00962 reverse_iterator2 rbegin2 () { 00963 return reverse_iterator2 (end2 ()); 00964 } 00965 BOOST_UBLAS_INLINE 00966 reverse_iterator2 rend2 () { 00967 return reverse_iterator2 (begin2 ()); 00968 } 00969 00970 private: 00971 size_type size1_; 00972 size_type size2_; 00973 size_type lower_; 00974 size_type upper_; 00975 array_type data_; 00976 typedef const value_type const_value_type; 00977 static const_value_type zero_; 00978 }; 00979 00980 template<class T, class L, class A> 00981 typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type/*zero*/(); 00982 00983 00999 template<class T, class L, class A> 01000 class diagonal_matrix: 01001 public banded_matrix<T, L, A> { 01002 public: 01003 typedef typename A::size_type size_type; 01004 typedef banded_matrix<T, L, A> matrix_type; 01005 typedef A array_type; 01006 01007 // Construction and destruction 01008 BOOST_UBLAS_INLINE 01009 diagonal_matrix (): 01010 matrix_type () {} 01011 BOOST_UBLAS_INLINE 01012 diagonal_matrix (size_type size): 01013 matrix_type (size, size) {} 01014 BOOST_UBLAS_INLINE 01015 diagonal_matrix (size_type size, const array_type& data): 01016 matrix_type (size, size, 0, 0, data) {} 01017 BOOST_UBLAS_INLINE 01018 diagonal_matrix (size_type size1, size_type size2): 01019 matrix_type (size1, size2) {} 01020 template<class AE> 01021 BOOST_UBLAS_INLINE 01022 diagonal_matrix (const matrix_expression<AE> &ae): 01023 matrix_type (ae) {} 01024 BOOST_UBLAS_INLINE 01025 ~diagonal_matrix () {} 01026 01027 // Assignment 01028 BOOST_UBLAS_INLINE 01029 diagonal_matrix &operator = (const diagonal_matrix &m) { 01030 matrix_type::operator = (m); 01031 return *this; 01032 } 01033 template<class AE> 01034 BOOST_UBLAS_INLINE 01035 diagonal_matrix &operator = (const matrix_expression<AE> &ae) { 01036 matrix_type::operator = (ae); 01037 return *this; 01038 } 01039 }; 01040 01053 template<class M> 01054 class banded_adaptor: 01055 public matrix_expression<banded_adaptor<M> > { 01056 01057 typedef banded_adaptor<M> self_type; 01058 public: 01059 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 01060 using matrix_expression<self_type>::operator (); 01061 #endif 01062 typedef const M const_matrix_type; 01063 typedef M matrix_type; 01064 typedef typename M::size_type size_type; 01065 typedef typename M::difference_type difference_type; 01066 typedef typename M::value_type value_type; 01067 typedef typename M::const_reference const_reference; 01068 typedef typename boost::mpl::if_<boost::is_const<M>, 01069 typename M::const_reference, 01070 typename M::reference>::type reference; 01071 typedef typename boost::mpl::if_<boost::is_const<M>, 01072 typename M::const_closure_type, 01073 typename M::closure_type>::type matrix_closure_type; 01074 typedef const self_type const_closure_type; 01075 typedef self_type closure_type; 01076 // Replaced by _temporary_traits to avoid type requirements on M 01077 //typedef typename M::vector_temporary_type vector_temporary_type; 01078 //typedef typename M::matrix_temporary_type matrix_temporary_type; 01079 typedef typename storage_restrict_traits<typename M::storage_category, 01080 packed_proxy_tag>::storage_category storage_category; 01081 typedef typename M::orientation_category orientation_category; 01082 01083 // Construction and destruction 01084 BOOST_UBLAS_INLINE 01085 banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0): 01086 matrix_expression<self_type> (), 01087 data_ (data), lower_ (lower), upper_ (upper) {} 01088 BOOST_UBLAS_INLINE 01089 banded_adaptor (const banded_adaptor &m): 01090 matrix_expression<self_type> (), 01091 data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {} 01092 01093 // Accessors 01094 BOOST_UBLAS_INLINE 01095 size_type size1 () const { 01096 return data_.size1 (); 01097 } 01098 BOOST_UBLAS_INLINE 01099 size_type size2 () const { 01100 return data_.size2 (); 01101 } 01102 BOOST_UBLAS_INLINE 01103 size_type lower () const { 01104 return lower_; 01105 } 01106 BOOST_UBLAS_INLINE 01107 size_type upper () const { 01108 return upper_; 01109 } 01110 01111 // Storage accessors 01112 BOOST_UBLAS_INLINE 01113 const matrix_closure_type &data () const { 01114 return data_; 01115 } 01116 BOOST_UBLAS_INLINE 01117 matrix_closure_type &data () { 01118 return data_; 01119 } 01120 01121 // Element access 01122 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER 01123 BOOST_UBLAS_INLINE 01124 const_reference operator () (size_type i, size_type j) const { 01125 BOOST_UBLAS_CHECK (i < size1 (), bad_index ()); 01126 BOOST_UBLAS_CHECK (j < size2 (), bad_index ()); 01127 #ifdef BOOST_UBLAS_OWN_BANDED 01128 size_type k = (std::max) (i, j); 01129 size_type l = lower_ + j - i; 01130 if (k < (std::max) (size1 (), size2 ()) && 01131 l < lower_ + 1 + upper_) 01132 return data () (i, j); 01133 #else 01134 size_type k = j; 01135 size_type l = upper_ + i - j; 01136 if (k < size2 () && 01137 l < lower_ + 1 + upper_) 01138 return data () (i, j); 01139 #endif 01140 return zero_; 01141 } 01142 BOOST_UBLAS_INLINE 01143 reference operator () (size_type i, size_type j) { 01144 BOOST_UBLAS_CHECK (i < size1 (), bad_index ()); 01145 BOOST_UBLAS_CHECK (j < size2 (), bad_index ()); 01146 #ifdef BOOST_UBLAS_OWN_BANDED 01147 size_type k = (std::max) (i, j); 01148 size_type l = lower_ + j - i; 01149 if (k < (std::max) (size1 (), size2 ()) && 01150 l < lower_ + 1 + upper_) 01151 return data () (i, j); 01152 #else 01153 size_type k = j; 01154 size_type l = upper_ + i - j; 01155 if (k < size2 () && 01156 l < lower_ + 1 + upper_) 01157 return data () (i, j); 01158 #endif 01159 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER 01160 bad_index ().raise (); 01161 #endif 01162 return const_cast<reference>(zero_); 01163 } 01164 #else 01165 BOOST_UBLAS_INLINE 01166 reference operator () (size_type i, size_type j) const { 01167 BOOST_UBLAS_CHECK (i < size1 (), bad_index ()); 01168 BOOST_UBLAS_CHECK (j < size2 (), bad_index ()); 01169 #ifdef BOOST_UBLAS_OWN_BANDED 01170 size_type k = (std::max) (i, j); 01171 size_type l = lower_ + j - i; 01172 if (k < (std::max) (size1 (), size2 ()) && 01173 l < lower_ + 1 + upper_) 01174 return data () (i, j); 01175 #else 01176 size_type k = j; 01177 size_type l = upper_ + i - j; 01178 if (k < size2 () && 01179 l < lower_ + 1 + upper_) 01180 return data () (i, j); 01181 #endif 01182 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER 01183 bad_index ().raise (); 01184 #endif 01185 return const_cast<reference>(zero_); 01186 } 01187 #endif 01188 01189 // Assignment 01190 BOOST_UBLAS_INLINE 01191 banded_adaptor &operator = (const banded_adaptor &m) { 01192 matrix_assign<scalar_assign> (*this, m); 01193 return *this; 01194 } 01195 BOOST_UBLAS_INLINE 01196 banded_adaptor &assign_temporary (banded_adaptor &m) { 01197 *this = m; 01198 return *this; 01199 } 01200 template<class AE> 01201 BOOST_UBLAS_INLINE 01202 banded_adaptor &operator = (const matrix_expression<AE> &ae) { 01203 matrix_assign<scalar_assign> (*this, matrix<value_type> (ae)); 01204 return *this; 01205 } 01206 template<class AE> 01207 BOOST_UBLAS_INLINE 01208 banded_adaptor &assign (const matrix_expression<AE> &ae) { 01209 matrix_assign<scalar_assign> (*this, ae); 01210 return *this; 01211 } 01212 template<class AE> 01213 BOOST_UBLAS_INLINE 01214 banded_adaptor& operator += (const matrix_expression<AE> &ae) { 01215 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae)); 01216 return *this; 01217 } 01218 template<class AE> 01219 BOOST_UBLAS_INLINE 01220 banded_adaptor &plus_assign (const matrix_expression<AE> &ae) { 01221 matrix_assign<scalar_plus_assign> (*this, ae); 01222 return *this; 01223 } 01224 template<class AE> 01225 BOOST_UBLAS_INLINE 01226 banded_adaptor& operator -= (const matrix_expression<AE> &ae) { 01227 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae)); 01228 return *this; 01229 } 01230 template<class AE> 01231 BOOST_UBLAS_INLINE 01232 banded_adaptor &minus_assign (const matrix_expression<AE> &ae) { 01233 matrix_assign<scalar_minus_assign> (*this, ae); 01234 return *this; 01235 } 01236 template<class AT> 01237 BOOST_UBLAS_INLINE 01238 banded_adaptor& operator *= (const AT &at) { 01239 matrix_assign_scalar<scalar_multiplies_assign> (*this, at); 01240 return *this; 01241 } 01242 template<class AT> 01243 BOOST_UBLAS_INLINE 01244 banded_adaptor& operator /= (const AT &at) { 01245 matrix_assign_scalar<scalar_divides_assign> (*this, at); 01246 return *this; 01247 } 01248 01249 // Closure comparison 01250 BOOST_UBLAS_INLINE 01251 bool same_closure (const banded_adaptor &ba) const { 01252 return (*this).data ().same_closure (ba.data ()); 01253 } 01254 01255 // Swapping 01256 BOOST_UBLAS_INLINE 01257 void swap (banded_adaptor &m) { 01258 if (this != &m) { 01259 BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ()); 01260 BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ()); 01261 matrix_swap<scalar_swap> (*this, m); 01262 } 01263 } 01264 BOOST_UBLAS_INLINE 01265 friend void swap (banded_adaptor &m1, banded_adaptor &m2) { 01266 m1.swap (m2); 01267 } 01268 01269 // Iterator types 01270 private: 01271 // Use the matrix iterator 01272 typedef typename M::const_iterator1 const_subiterator1_type; 01273 typedef typename boost::mpl::if_<boost::is_const<M>, 01274 typename M::const_iterator1, 01275 typename M::iterator1>::type subiterator1_type; 01276 typedef typename M::const_iterator2 const_subiterator2_type; 01277 typedef typename boost::mpl::if_<boost::is_const<M>, 01278 typename M::const_iterator2, 01279 typename M::iterator2>::type subiterator2_type; 01280 01281 public: 01282 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 01283 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1; 01284 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2; 01285 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1; 01286 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2; 01287 #else 01288 class const_iterator1; 01289 class iterator1; 01290 class const_iterator2; 01291 class iterator2; 01292 #endif 01293 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 01294 typedef reverse_iterator_base1<iterator1> reverse_iterator1; 01295 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 01296 typedef reverse_iterator_base2<iterator2> reverse_iterator2; 01297 01298 // Element lookup 01299 BOOST_UBLAS_INLINE 01300 const_iterator1 find1 (int rank, size_type i, size_type j) const { 01301 if (rank == 1) { 01302 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0)); 01303 i = (std::max) (i, lower_i); 01304 size_type upper_i = (std::min) (j + 1 + lower_, size1 ()); 01305 i = (std::min) (i, upper_i); 01306 } 01307 return const_iterator1 (*this, data ().find1 (rank, i, j)); 01308 } 01309 BOOST_UBLAS_INLINE 01310 iterator1 find1 (int rank, size_type i, size_type j) { 01311 if (rank == 1) { 01312 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0)); 01313 i = (std::max) (i, lower_i); 01314 size_type upper_i = (std::min) (j + 1 + lower_, size1 ()); 01315 i = (std::min) (i, upper_i); 01316 } 01317 return iterator1 (*this, data ().find1 (rank, i, j)); 01318 } 01319 BOOST_UBLAS_INLINE 01320 const_iterator2 find2 (int rank, size_type i, size_type j) const { 01321 if (rank == 1) { 01322 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0)); 01323 j = (std::max) (j, lower_j); 01324 size_type upper_j = (std::min) (i + 1 + upper_, size2 ()); 01325 j = (std::min) (j, upper_j); 01326 } 01327 return const_iterator2 (*this, data ().find2 (rank, i, j)); 01328 } 01329 BOOST_UBLAS_INLINE 01330 iterator2 find2 (int rank, size_type i, size_type j) { 01331 if (rank == 1) { 01332 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0)); 01333 j = (std::max) (j, lower_j); 01334 size_type upper_j = (std::min) (i + 1 + upper_, size2 ()); 01335 j = (std::min) (j, upper_j); 01336 } 01337 return iterator2 (*this, data ().find2 (rank, i, j)); 01338 } 01339 01340 // Iterators simply are indices. 01341 01342 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 01343 class const_iterator1: 01344 public container_const_reference<banded_adaptor>, 01345 public random_access_iterator_base<typename iterator_restrict_traits< 01346 typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category, 01347 const_iterator1, value_type> { 01348 public: 01349 typedef typename const_subiterator1_type::value_type value_type; 01350 typedef typename const_subiterator1_type::difference_type difference_type; 01351 typedef typename const_subiterator1_type::reference reference; 01352 typedef typename const_subiterator1_type::pointer pointer; 01353 01354 typedef const_iterator2 dual_iterator_type; 01355 typedef const_reverse_iterator2 dual_reverse_iterator_type; 01356 01357 // Construction and destruction 01358 BOOST_UBLAS_INLINE 01359 const_iterator1 (): 01360 container_const_reference<self_type> (), it1_ () {} 01361 BOOST_UBLAS_INLINE 01362 const_iterator1 (const self_type &m, const const_subiterator1_type &it1): 01363 container_const_reference<self_type> (m), it1_ (it1) {} 01364 BOOST_UBLAS_INLINE 01365 const_iterator1 (const iterator1 &it): 01366 container_const_reference<self_type> (it ()), it1_ (it.it1_) {} 01367 01368 // Arithmetic 01369 BOOST_UBLAS_INLINE 01370 const_iterator1 &operator ++ () { 01371 ++ it1_; 01372 return *this; 01373 } 01374 BOOST_UBLAS_INLINE 01375 const_iterator1 &operator -- () { 01376 -- it1_; 01377 return *this; 01378 } 01379 BOOST_UBLAS_INLINE 01380 const_iterator1 &operator += (difference_type n) { 01381 it1_ += n; 01382 return *this; 01383 } 01384 BOOST_UBLAS_INLINE 01385 const_iterator1 &operator -= (difference_type n) { 01386 it1_ -= n; 01387 return *this; 01388 } 01389 BOOST_UBLAS_INLINE 01390 difference_type operator - (const const_iterator1 &it) const { 01391 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01392 return it1_ - it.it1_; 01393 } 01394 01395 // Dereference 01396 BOOST_UBLAS_INLINE 01397 const_reference operator * () const { 01398 size_type i = index1 (); 01399 size_type j = index2 (); 01400 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ()); 01401 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ()); 01402 #ifdef BOOST_UBLAS_OWN_BANDED 01403 size_type k = (std::max) (i, j); 01404 size_type l = (*this) ().lower () + j - i; 01405 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) && 01406 l < (*this) ().lower () + 1 + (*this) ().upper ()) 01407 return *it1_; 01408 #else 01409 size_type k = j; 01410 size_type l = (*this) ().upper () + i - j; 01411 if (k < (*this) ().size2 () && 01412 l < (*this) ().lower () + 1 + (*this) ().upper ()) 01413 return *it1_; 01414 #endif 01415 return (*this) () (i, j); 01416 } 01417 BOOST_UBLAS_INLINE 01418 const_reference operator [] (difference_type n) const { 01419 return *(*this + n); 01420 } 01421 01422 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 01423 BOOST_UBLAS_INLINE 01424 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01425 typename self_type:: 01426 #endif 01427 const_iterator2 begin () const { 01428 return (*this) ().find2 (1, index1 (), 0); 01429 } 01430 BOOST_UBLAS_INLINE 01431 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01432 typename self_type:: 01433 #endif 01434 const_iterator2 end () const { 01435 return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); 01436 } 01437 BOOST_UBLAS_INLINE 01438 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01439 typename self_type:: 01440 #endif 01441 const_reverse_iterator2 rbegin () const { 01442 return const_reverse_iterator2 (end ()); 01443 } 01444 BOOST_UBLAS_INLINE 01445 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01446 typename self_type:: 01447 #endif 01448 const_reverse_iterator2 rend () const { 01449 return const_reverse_iterator2 (begin ()); 01450 } 01451 #endif 01452 01453 // Indices 01454 BOOST_UBLAS_INLINE 01455 size_type index1 () const { 01456 return it1_.index1 (); 01457 } 01458 BOOST_UBLAS_INLINE 01459 size_type index2 () const { 01460 return it1_.index2 (); 01461 } 01462 01463 // Assignment 01464 BOOST_UBLAS_INLINE 01465 const_iterator1 &operator = (const const_iterator1 &it) { 01466 container_const_reference<self_type>::assign (&it ()); 01467 it1_ = it.it1_; 01468 return *this; 01469 } 01470 01471 // Comparison 01472 BOOST_UBLAS_INLINE 01473 bool operator == (const const_iterator1 &it) const { 01474 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01475 return it1_ == it.it1_; 01476 } 01477 BOOST_UBLAS_INLINE 01478 bool operator < (const const_iterator1 &it) const { 01479 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01480 return it1_ < it.it1_; 01481 } 01482 01483 private: 01484 const_subiterator1_type it1_; 01485 }; 01486 #endif 01487 01488 BOOST_UBLAS_INLINE 01489 const_iterator1 begin1 () const { 01490 return find1 (0, 0, 0); 01491 } 01492 BOOST_UBLAS_INLINE 01493 const_iterator1 end1 () const { 01494 return find1 (0, size1 (), 0); 01495 } 01496 01497 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 01498 class iterator1: 01499 public container_reference<banded_adaptor>, 01500 public random_access_iterator_base<typename iterator_restrict_traits< 01501 typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category, 01502 iterator1, value_type> { 01503 public: 01504 typedef typename subiterator1_type::value_type value_type; 01505 typedef typename subiterator1_type::difference_type difference_type; 01506 typedef typename subiterator1_type::reference reference; 01507 typedef typename subiterator1_type::pointer pointer; 01508 01509 typedef iterator2 dual_iterator_type; 01510 typedef reverse_iterator2 dual_reverse_iterator_type; 01511 01512 // Construction and destruction 01513 BOOST_UBLAS_INLINE 01514 iterator1 (): 01515 container_reference<self_type> (), it1_ () {} 01516 BOOST_UBLAS_INLINE 01517 iterator1 (self_type &m, const subiterator1_type &it1): 01518 container_reference<self_type> (m), it1_ (it1) {} 01519 01520 // Arithmetic 01521 BOOST_UBLAS_INLINE 01522 iterator1 &operator ++ () { 01523 ++ it1_; 01524 return *this; 01525 } 01526 BOOST_UBLAS_INLINE 01527 iterator1 &operator -- () { 01528 -- it1_; 01529 return *this; 01530 } 01531 BOOST_UBLAS_INLINE 01532 iterator1 &operator += (difference_type n) { 01533 it1_ += n; 01534 return *this; 01535 } 01536 BOOST_UBLAS_INLINE 01537 iterator1 &operator -= (difference_type n) { 01538 it1_ -= n; 01539 return *this; 01540 } 01541 BOOST_UBLAS_INLINE 01542 difference_type operator - (const iterator1 &it) const { 01543 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01544 return it1_ - it.it1_; 01545 } 01546 01547 // Dereference 01548 BOOST_UBLAS_INLINE 01549 reference operator * () const { 01550 size_type i = index1 (); 01551 size_type j = index2 (); 01552 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ()); 01553 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ()); 01554 #ifdef BOOST_UBLAS_OWN_BANDED 01555 size_type k = (std::max) (i, j); 01556 size_type l = (*this) ().lower () + j - i; 01557 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) && 01558 l < (*this) ().lower () + 1 + (*this) ().upper ()) 01559 return *it1_; 01560 #else 01561 size_type k = j; 01562 size_type l = (*this) ().upper () + i - j; 01563 if (k < (*this) ().size2 () && 01564 l < (*this) ().lower () + 1 + (*this) ().upper ()) 01565 return *it1_; 01566 #endif 01567 return (*this) () (i, j); 01568 } 01569 BOOST_UBLAS_INLINE 01570 reference operator [] (difference_type n) const { 01571 return *(*this + n); 01572 } 01573 01574 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 01575 BOOST_UBLAS_INLINE 01576 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01577 typename self_type:: 01578 #endif 01579 iterator2 begin () const { 01580 return (*this) ().find2 (1, index1 (), 0); 01581 } 01582 BOOST_UBLAS_INLINE 01583 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01584 typename self_type:: 01585 #endif 01586 iterator2 end () const { 01587 return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); 01588 } 01589 BOOST_UBLAS_INLINE 01590 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01591 typename self_type:: 01592 #endif 01593 reverse_iterator2 rbegin () const { 01594 return reverse_iterator2 (end ()); 01595 } 01596 BOOST_UBLAS_INLINE 01597 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01598 typename self_type:: 01599 #endif 01600 reverse_iterator2 rend () const { 01601 return reverse_iterator2 (begin ()); 01602 } 01603 #endif 01604 01605 // Indices 01606 BOOST_UBLAS_INLINE 01607 size_type index1 () const { 01608 return it1_.index1 (); 01609 } 01610 BOOST_UBLAS_INLINE 01611 size_type index2 () const { 01612 return it1_.index2 (); 01613 } 01614 01615 // Assignment 01616 BOOST_UBLAS_INLINE 01617 iterator1 &operator = (const iterator1 &it) { 01618 container_reference<self_type>::assign (&it ()); 01619 it1_ = it.it1_; 01620 return *this; 01621 } 01622 01623 // Comparison 01624 BOOST_UBLAS_INLINE 01625 bool operator == (const iterator1 &it) const { 01626 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01627 return it1_ == it.it1_; 01628 } 01629 BOOST_UBLAS_INLINE 01630 bool operator < (const iterator1 &it) const { 01631 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01632 return it1_ < it.it1_; 01633 } 01634 01635 private: 01636 subiterator1_type it1_; 01637 01638 friend class const_iterator1; 01639 }; 01640 #endif 01641 01642 BOOST_UBLAS_INLINE 01643 iterator1 begin1 () { 01644 return find1 (0, 0, 0); 01645 } 01646 BOOST_UBLAS_INLINE 01647 iterator1 end1 () { 01648 return find1 (0, size1 (), 0); 01649 } 01650 01651 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 01652 class const_iterator2: 01653 public container_const_reference<banded_adaptor>, 01654 public random_access_iterator_base<packed_random_access_iterator_tag, 01655 const_iterator2, value_type> { 01656 public: 01657 typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category, 01658 packed_random_access_iterator_tag>::iterator_category iterator_category; 01659 typedef typename const_subiterator2_type::value_type value_type; 01660 typedef typename const_subiterator2_type::difference_type difference_type; 01661 typedef typename const_subiterator2_type::reference reference; 01662 typedef typename const_subiterator2_type::pointer pointer; 01663 01664 typedef const_iterator1 dual_iterator_type; 01665 typedef const_reverse_iterator1 dual_reverse_iterator_type; 01666 01667 // Construction and destruction 01668 BOOST_UBLAS_INLINE 01669 const_iterator2 (): 01670 container_const_reference<self_type> (), it2_ () {} 01671 BOOST_UBLAS_INLINE 01672 const_iterator2 (const self_type &m, const const_subiterator2_type &it2): 01673 container_const_reference<self_type> (m), it2_ (it2) {} 01674 BOOST_UBLAS_INLINE 01675 const_iterator2 (const iterator2 &it): 01676 container_const_reference<self_type> (it ()), it2_ (it.it2_) {} 01677 01678 // Arithmetic 01679 BOOST_UBLAS_INLINE 01680 const_iterator2 &operator ++ () { 01681 ++ it2_; 01682 return *this; 01683 } 01684 BOOST_UBLAS_INLINE 01685 const_iterator2 &operator -- () { 01686 -- it2_; 01687 return *this; 01688 } 01689 BOOST_UBLAS_INLINE 01690 const_iterator2 &operator += (difference_type n) { 01691 it2_ += n; 01692 return *this; 01693 } 01694 BOOST_UBLAS_INLINE 01695 const_iterator2 &operator -= (difference_type n) { 01696 it2_ -= n; 01697 return *this; 01698 } 01699 BOOST_UBLAS_INLINE 01700 difference_type operator - (const const_iterator2 &it) const { 01701 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01702 return it2_ - it.it2_; 01703 } 01704 01705 // Dereference 01706 BOOST_UBLAS_INLINE 01707 const_reference operator * () const { 01708 size_type i = index1 (); 01709 size_type j = index2 (); 01710 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ()); 01711 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ()); 01712 #ifdef BOOST_UBLAS_OWN_BANDED 01713 size_type k = (std::max) (i, j); 01714 size_type l = (*this) ().lower () + j - i; 01715 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) && 01716 l < (*this) ().lower () + 1 + (*this) ().upper ()) 01717 return *it2_; 01718 #else 01719 size_type k = j; 01720 size_type l = (*this) ().upper () + i - j; 01721 if (k < (*this) ().size2 () && 01722 l < (*this) ().lower () + 1 + (*this) ().upper ()) 01723 return *it2_; 01724 #endif 01725 return (*this) () (i, j); 01726 } 01727 BOOST_UBLAS_INLINE 01728 const_reference operator [] (difference_type n) const { 01729 return *(*this + n); 01730 } 01731 01732 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 01733 BOOST_UBLAS_INLINE 01734 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01735 typename self_type:: 01736 #endif 01737 const_iterator1 begin () const { 01738 return (*this) ().find1 (1, 0, index2 ()); 01739 } 01740 BOOST_UBLAS_INLINE 01741 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01742 typename self_type:: 01743 #endif 01744 const_iterator1 end () const { 01745 return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); 01746 } 01747 BOOST_UBLAS_INLINE 01748 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01749 typename self_type:: 01750 #endif 01751 const_reverse_iterator1 rbegin () const { 01752 return const_reverse_iterator1 (end ()); 01753 } 01754 BOOST_UBLAS_INLINE 01755 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01756 typename self_type:: 01757 #endif 01758 const_reverse_iterator1 rend () const { 01759 return const_reverse_iterator1 (begin ()); 01760 } 01761 #endif 01762 01763 // Indices 01764 BOOST_UBLAS_INLINE 01765 size_type index1 () const { 01766 return it2_.index1 (); 01767 } 01768 BOOST_UBLAS_INLINE 01769 size_type index2 () const { 01770 return it2_.index2 (); 01771 } 01772 01773 // Assignment 01774 BOOST_UBLAS_INLINE 01775 const_iterator2 &operator = (const const_iterator2 &it) { 01776 container_const_reference<self_type>::assign (&it ()); 01777 it2_ = it.it2_; 01778 return *this; 01779 } 01780 01781 // Comparison 01782 BOOST_UBLAS_INLINE 01783 bool operator == (const const_iterator2 &it) const { 01784 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01785 return it2_ == it.it2_; 01786 } 01787 BOOST_UBLAS_INLINE 01788 bool operator < (const const_iterator2 &it) const { 01789 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01790 return it2_ < it.it2_; 01791 } 01792 01793 private: 01794 const_subiterator2_type it2_; 01795 }; 01796 #endif 01797 01798 BOOST_UBLAS_INLINE 01799 const_iterator2 begin2 () const { 01800 return find2 (0, 0, 0); 01801 } 01802 BOOST_UBLAS_INLINE 01803 const_iterator2 end2 () const { 01804 return find2 (0, 0, size2 ()); 01805 } 01806 01807 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 01808 class iterator2: 01809 public container_reference<banded_adaptor>, 01810 public random_access_iterator_base<typename iterator_restrict_traits< 01811 typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category, 01812 iterator2, value_type> { 01813 public: 01814 typedef typename subiterator2_type::value_type value_type; 01815 typedef typename subiterator2_type::difference_type difference_type; 01816 typedef typename subiterator2_type::reference reference; 01817 typedef typename subiterator2_type::pointer pointer; 01818 01819 typedef iterator1 dual_iterator_type; 01820 typedef reverse_iterator1 dual_reverse_iterator_type; 01821 01822 // Construction and destruction 01823 BOOST_UBLAS_INLINE 01824 iterator2 (): 01825 container_reference<self_type> (), it2_ () {} 01826 BOOST_UBLAS_INLINE 01827 iterator2 (self_type &m, const subiterator2_type &it2): 01828 container_reference<self_type> (m), it2_ (it2) {} 01829 01830 // Arithmetic 01831 BOOST_UBLAS_INLINE 01832 iterator2 &operator ++ () { 01833 ++ it2_; 01834 return *this; 01835 } 01836 BOOST_UBLAS_INLINE 01837 iterator2 &operator -- () { 01838 -- it2_; 01839 return *this; 01840 } 01841 BOOST_UBLAS_INLINE 01842 iterator2 &operator += (difference_type n) { 01843 it2_ += n; 01844 return *this; 01845 } 01846 BOOST_UBLAS_INLINE 01847 iterator2 &operator -= (difference_type n) { 01848 it2_ -= n; 01849 return *this; 01850 } 01851 BOOST_UBLAS_INLINE 01852 difference_type operator - (const iterator2 &it) const { 01853 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01854 return it2_ - it.it2_; 01855 } 01856 01857 // Dereference 01858 BOOST_UBLAS_INLINE 01859 reference operator * () const { 01860 size_type i = index1 (); 01861 size_type j = index2 (); 01862 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ()); 01863 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ()); 01864 #ifdef BOOST_UBLAS_OWN_BANDED 01865 size_type k = (std::max) (i, j); 01866 size_type l = (*this) ().lower () + j - i; 01867 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) && 01868 l < (*this) ().lower () + 1 + (*this) ().upper ()) 01869 return *it2_; 01870 #else 01871 size_type k = j; 01872 size_type l = (*this) ().upper () + i - j; 01873 if (k < (*this) ().size2 () && 01874 l < (*this) ().lower () + 1 + (*this) ().upper ()) 01875 return *it2_; 01876 #endif 01877 return (*this) () (i, j); 01878 } 01879 BOOST_UBLAS_INLINE 01880 reference operator [] (difference_type n) const { 01881 return *(*this + n); 01882 } 01883 01884 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 01885 BOOST_UBLAS_INLINE 01886 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01887 typename self_type:: 01888 #endif 01889 iterator1 begin () const { 01890 return (*this) ().find1 (1, 0, index2 ()); 01891 } 01892 BOOST_UBLAS_INLINE 01893 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01894 typename self_type:: 01895 #endif 01896 iterator1 end () const { 01897 return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); 01898 } 01899 BOOST_UBLAS_INLINE 01900 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01901 typename self_type:: 01902 #endif 01903 reverse_iterator1 rbegin () const { 01904 return reverse_iterator1 (end ()); 01905 } 01906 BOOST_UBLAS_INLINE 01907 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01908 typename self_type:: 01909 #endif 01910 reverse_iterator1 rend () const { 01911 return reverse_iterator1 (begin ()); 01912 } 01913 #endif 01914 01915 // Indices 01916 BOOST_UBLAS_INLINE 01917 size_type index1 () const { 01918 return it2_.index1 (); 01919 } 01920 BOOST_UBLAS_INLINE 01921 size_type index2 () const { 01922 return it2_.index2 (); 01923 } 01924 01925 // Assignment 01926 BOOST_UBLAS_INLINE 01927 iterator2 &operator = (const iterator2 &it) { 01928 container_reference<self_type>::assign (&it ()); 01929 it2_ = it.it2_; 01930 return *this; 01931 } 01932 01933 // Comparison 01934 BOOST_UBLAS_INLINE 01935 bool operator == (const iterator2 &it) const { 01936 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01937 return it2_ == it.it2_; 01938 } 01939 BOOST_UBLAS_INLINE 01940 bool operator < (const iterator2 &it) const { 01941 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01942 return it2_ < it.it2_; 01943 } 01944 01945 private: 01946 subiterator2_type it2_; 01947 01948 friend class const_iterator2; 01949 }; 01950 #endif 01951 01952 BOOST_UBLAS_INLINE 01953 iterator2 begin2 () { 01954 return find2 (0, 0, 0); 01955 } 01956 BOOST_UBLAS_INLINE 01957 iterator2 end2 () { 01958 return find2 (0, 0, size2 ()); 01959 } 01960 01961 // Reverse iterators 01962 01963 BOOST_UBLAS_INLINE 01964 const_reverse_iterator1 rbegin1 () const { 01965 return const_reverse_iterator1 (end1 ()); 01966 } 01967 BOOST_UBLAS_INLINE 01968 const_reverse_iterator1 rend1 () const { 01969 return const_reverse_iterator1 (begin1 ()); 01970 } 01971 01972 BOOST_UBLAS_INLINE 01973 reverse_iterator1 rbegin1 () { 01974 return reverse_iterator1 (end1 ()); 01975 } 01976 BOOST_UBLAS_INLINE 01977 reverse_iterator1 rend1 () { 01978 return reverse_iterator1 (begin1 ()); 01979 } 01980 01981 BOOST_UBLAS_INLINE 01982 const_reverse_iterator2 rbegin2 () const { 01983 return const_reverse_iterator2 (end2 ()); 01984 } 01985 BOOST_UBLAS_INLINE 01986 const_reverse_iterator2 rend2 () const { 01987 return const_reverse_iterator2 (begin2 ()); 01988 } 01989 01990 BOOST_UBLAS_INLINE 01991 reverse_iterator2 rbegin2 () { 01992 return reverse_iterator2 (end2 ()); 01993 } 01994 BOOST_UBLAS_INLINE 01995 reverse_iterator2 rend2 () { 01996 return reverse_iterator2 (begin2 ()); 01997 } 01998 01999 private: 02000 matrix_closure_type data_; 02001 size_type lower_; 02002 size_type upper_; 02003 typedef const value_type const_value_type; 02004 static const_value_type zero_; 02005 }; 02006 02007 // Specialization for temporary_traits 02008 template <class M> 02009 struct vector_temporary_traits< banded_adaptor<M> > 02010 : vector_temporary_traits< M > {} ; 02011 template <class M> 02012 struct vector_temporary_traits< const banded_adaptor<M> > 02013 : vector_temporary_traits< M > {} ; 02014 02015 template <class M> 02016 struct matrix_temporary_traits< banded_adaptor<M> > 02017 : matrix_temporary_traits< M > {} ; 02018 template <class M> 02019 struct matrix_temporary_traits< const banded_adaptor<M> > 02020 : matrix_temporary_traits< M > {} ; 02021 02022 02023 template<class M> 02024 typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type/*zero*/(); 02025 02038 template<class M> 02039 class diagonal_adaptor: 02040 public banded_adaptor<M> { 02041 public: 02042 typedef M matrix_type; 02043 typedef banded_adaptor<M> adaptor_type; 02044 02045 // Construction and destruction 02046 BOOST_UBLAS_INLINE 02047 diagonal_adaptor (): 02048 adaptor_type () {} 02049 BOOST_UBLAS_INLINE 02050 diagonal_adaptor (matrix_type &data): 02051 adaptor_type (data) {} 02052 BOOST_UBLAS_INLINE 02053 ~diagonal_adaptor () {} 02054 02055 // Assignment 02056 BOOST_UBLAS_INLINE 02057 diagonal_adaptor &operator = (const diagonal_adaptor &m) { 02058 adaptor_type::operator = (m); 02059 return *this; 02060 } 02061 template<class AE> 02062 BOOST_UBLAS_INLINE 02063 diagonal_adaptor &operator = (const matrix_expression<AE> &ae) { 02064 adaptor_type::operator = (ae); 02065 return *this; 02066 } 02067 }; 02068 02069 }}} 02070 02071 #endif