00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _BOOST_UBLAS_MATRIX_
00014 #define _BOOST_UBLAS_MATRIX_
00015
00016 #include <boost/numeric/ublas/vector.hpp>
00017 #include <boost/numeric/ublas/matrix_expression.hpp>
00018 #include <boost/numeric/ublas/detail/matrix_assign.hpp>
00019 #include <boost/serialization/collection_size_type.hpp>
00020 #include <boost/serialization/array.hpp>
00021 #include <boost/serialization/nvp.hpp>
00022
00023
00024
00025 namespace boost { namespace numeric {
00026
00040 namespace ublas {
00041
00042 namespace detail {
00043 using namespace boost::numeric::ublas;
00044
00045
00046 template <class L, class M>
00047 BOOST_UBLAS_INLINE
00048 void matrix_resize_preserve (M& m, M& temporary) {
00049 typedef L layout_type;
00050 typedef typename M::size_type size_type;
00051 const size_type msize1 (m.size1 ());
00052 const size_type msize2 (m.size2 ());
00053 const size_type size1 (temporary.size1 ());
00054 const size_type size2 (temporary.size2 ());
00055
00056 const size_type size1_min = (std::min) (size1, msize1);
00057 const size_type size2_min = (std::min) (size2, msize2);
00058
00059 const size_type major_size = layout_type::size_M (size1_min, size2_min);
00060 const size_type minor_size = layout_type::size_m (size1_min, size2_min);
00061
00062 for (size_type major = 0; major != major_size; ++major) {
00063 for (size_type minor = 0; minor != minor_size; ++minor) {
00064
00065 const size_type i1 = layout_type::index_M(major, minor);
00066 const size_type i2 = layout_type::index_m(major, minor);
00067 temporary.data () [layout_type::element (i1, size1, i2, size2)] =
00068 m.data() [layout_type::element (i1, msize1, i2, msize2)];
00069 }
00070 }
00071 m.assign_temporary (temporary);
00072 }
00073 }
00074
00089 template<class T, class L, class A>
00090 class matrix:
00091 public matrix_container<matrix<T, L, A> > {
00092
00093 typedef T *pointer;
00094 typedef L layout_type;
00095 typedef matrix<T, L, A> self_type;
00096 public:
00097 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00098 using matrix_container<self_type>::operator ();
00099 #endif
00100 typedef typename A::size_type size_type;
00101 typedef typename A::difference_type difference_type;
00102 typedef T value_type;
00103 typedef const T &const_reference;
00104 typedef T &reference;
00105 typedef A array_type;
00106 typedef const matrix_reference<const self_type> const_closure_type;
00107 typedef matrix_reference<self_type> closure_type;
00108 typedef vector<T, A> vector_temporary_type;
00109 typedef self_type matrix_temporary_type;
00110 typedef dense_tag storage_category;
00111
00112
00113
00114 typedef typename L::orientation_category orientation_category;
00115
00116
00117 BOOST_UBLAS_INLINE
00118 matrix ():
00119 matrix_container<self_type> (),
00120 size1_ (0), size2_ (0), data_ () {}
00121 BOOST_UBLAS_INLINE
00122 matrix (size_type size1, size_type size2):
00123 matrix_container<self_type> (),
00124 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) {
00125 }
00126 matrix (size_type size1, size_type size2, const value_type &init):
00127 matrix_container<self_type> (),
00128 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2), init) {
00129 }
00130 BOOST_UBLAS_INLINE
00131 matrix (size_type size1, size_type size2, const array_type &data):
00132 matrix_container<self_type> (),
00133 size1_ (size1), size2_ (size2), data_ (data) {}
00134 BOOST_UBLAS_INLINE
00135 matrix (const matrix &m):
00136 matrix_container<self_type> (),
00137 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
00138 template<class AE>
00139 BOOST_UBLAS_INLINE
00140 matrix (const matrix_expression<AE> &ae):
00141 matrix_container<self_type> (),
00142 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) {
00143 matrix_assign<scalar_assign> (*this, ae);
00144 }
00145
00146
00147 BOOST_UBLAS_INLINE
00148 size_type size1 () const {
00149 return size1_;
00150 }
00151 BOOST_UBLAS_INLINE
00152 size_type size2 () const {
00153 return size2_;
00154 }
00155
00156
00157 BOOST_UBLAS_INLINE
00158 const array_type &data () const {
00159 return data_;
00160 }
00161 BOOST_UBLAS_INLINE
00162 array_type &data () {
00163 return data_;
00164 }
00165
00166
00167 BOOST_UBLAS_INLINE
00168 void resize (size_type size1, size_type size2, bool preserve = true) {
00169 if (preserve) {
00170 self_type temporary (size1, size2);
00171 detail::matrix_resize_preserve<layout_type> (*this, temporary);
00172 }
00173 else {
00174 data ().resize (layout_type::storage_size (size1, size2));
00175 size1_ = size1;
00176 size2_ = size2;
00177 }
00178 }
00179
00180
00181 BOOST_UBLAS_INLINE
00182 const_reference operator () (size_type i, size_type j) const {
00183 return data () [layout_type::element (i, size1_, j, size2_)];
00184 }
00185 BOOST_UBLAS_INLINE
00186 reference at_element (size_type i, size_type j) {
00187 return data () [layout_type::element (i, size1_, j, size2_)];
00188 }
00189 BOOST_UBLAS_INLINE
00190 reference operator () (size_type i, size_type j) {
00191 return at_element (i, j);
00192 }
00193
00194
00195 BOOST_UBLAS_INLINE
00196 reference insert_element (size_type i, size_type j, const_reference t) {
00197 return (at_element (i, j) = t);
00198 }
00199 void erase_element (size_type i, size_type j) {
00200 at_element (i, j) = value_type();
00201 }
00202
00203
00204 BOOST_UBLAS_INLINE
00205 void clear () {
00206 std::fill (data ().begin (), data ().end (), value_type());
00207 }
00208
00209
00210 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
00211
00213 BOOST_UBLAS_INLINE
00214 matrix &operator = (matrix m) {
00215 assign_temporary(m);
00216 return *this;
00217 }
00218 #else
00219 BOOST_UBLAS_INLINE
00220 matrix &operator = (const matrix &m) {
00221 size1_ = m.size1_;
00222 size2_ = m.size2_;
00223 data () = m.data ();
00224 return *this;
00225 }
00226 #endif
00227 template<class C>
00228 BOOST_UBLAS_INLINE
00229 matrix &operator = (const matrix_container<C> &m) {
00230 resize (m ().size1 (), m ().size2 (), false);
00231 assign (m);
00232 return *this;
00233 }
00234 BOOST_UBLAS_INLINE
00235 matrix &assign_temporary (matrix &m) {
00236 swap (m);
00237 return *this;
00238 }
00239 template<class AE>
00240 BOOST_UBLAS_INLINE
00241 matrix &operator = (const matrix_expression<AE> &ae) {
00242 self_type temporary (ae);
00243 return assign_temporary (temporary);
00244 }
00245 template<class AE>
00246 BOOST_UBLAS_INLINE
00247 matrix &assign (const matrix_expression<AE> &ae) {
00248 matrix_assign<scalar_assign> (*this, ae);
00249 return *this;
00250 }
00251 template<class AE>
00252 BOOST_UBLAS_INLINE
00253 matrix& operator += (const matrix_expression<AE> &ae) {
00254 self_type temporary (*this + ae);
00255 return assign_temporary (temporary);
00256 }
00257 template<class C>
00258 BOOST_UBLAS_INLINE
00259 matrix &operator += (const matrix_container<C> &m) {
00260 plus_assign (m);
00261 return *this;
00262 }
00263 template<class AE>
00264 BOOST_UBLAS_INLINE
00265 matrix &plus_assign (const matrix_expression<AE> &ae) {
00266 matrix_assign<scalar_plus_assign> (*this, ae);
00267 return *this;
00268 }
00269 template<class AE>
00270 BOOST_UBLAS_INLINE
00271 matrix& operator -= (const matrix_expression<AE> &ae) {
00272 self_type temporary (*this - ae);
00273 return assign_temporary (temporary);
00274 }
00275 template<class C>
00276 BOOST_UBLAS_INLINE
00277 matrix &operator -= (const matrix_container<C> &m) {
00278 minus_assign (m);
00279 return *this;
00280 }
00281 template<class AE>
00282 BOOST_UBLAS_INLINE
00283 matrix &minus_assign (const matrix_expression<AE> &ae) {
00284 matrix_assign<scalar_minus_assign> (*this, ae);
00285 return *this;
00286 }
00287 template<class AT>
00288 BOOST_UBLAS_INLINE
00289 matrix& operator *= (const AT &at) {
00290 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
00291 return *this;
00292 }
00293 template<class AT>
00294 BOOST_UBLAS_INLINE
00295 matrix& operator /= (const AT &at) {
00296 matrix_assign_scalar<scalar_divides_assign> (*this, at);
00297 return *this;
00298 }
00299
00300
00301 BOOST_UBLAS_INLINE
00302 void swap (matrix &m) {
00303 if (this != &m) {
00304 std::swap (size1_, m.size1_);
00305 std::swap (size2_, m.size2_);
00306 data ().swap (m.data ());
00307 }
00308 }
00309 BOOST_UBLAS_INLINE
00310 friend void swap (matrix &m1, matrix &m2) {
00311 m1.swap (m2);
00312 }
00313
00314
00315 private:
00316
00317 typedef typename A::const_iterator const_subiterator_type;
00318 typedef typename A::iterator subiterator_type;
00319
00320 public:
00321 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00322 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
00323 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
00324 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
00325 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
00326 #else
00327 class const_iterator1;
00328 class iterator1;
00329 class const_iterator2;
00330 class iterator2;
00331 #endif
00332 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
00333 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
00334 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
00335 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
00336
00337
00338 BOOST_UBLAS_INLINE
00339 const_iterator1 find1 (int , size_type i, size_type j) const {
00340 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00341 return const_iterator1 (*this, i, j);
00342 #else
00343 return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
00344 #endif
00345 }
00346 BOOST_UBLAS_INLINE
00347 iterator1 find1 (int , size_type i, size_type j) {
00348 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00349 return iterator1 (*this, i, j);
00350 #else
00351 return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
00352 #endif
00353 }
00354 BOOST_UBLAS_INLINE
00355 const_iterator2 find2 (int , size_type i, size_type j) const {
00356 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00357 return const_iterator2 (*this, i, j);
00358 #else
00359 return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
00360 #endif
00361 }
00362 BOOST_UBLAS_INLINE
00363 iterator2 find2 (int , size_type i, size_type j) {
00364 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00365 return iterator2 (*this, i, j);
00366 #else
00367 return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
00368 #endif
00369 }
00370
00371
00372 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00373 class const_iterator1:
00374 public container_const_reference<matrix>,
00375 public random_access_iterator_base<dense_random_access_iterator_tag,
00376 const_iterator1, value_type> {
00377 public:
00378 typedef typename matrix::value_type value_type;
00379 typedef typename matrix::difference_type difference_type;
00380 typedef typename matrix::const_reference reference;
00381 typedef const typename matrix::pointer pointer;
00382
00383 typedef const_iterator2 dual_iterator_type;
00384 typedef const_reverse_iterator2 dual_reverse_iterator_type;
00385
00386
00387 BOOST_UBLAS_INLINE
00388 const_iterator1 ():
00389 container_const_reference<self_type> (), it_ () {}
00390 BOOST_UBLAS_INLINE
00391 const_iterator1 (const self_type &m, const const_subiterator_type &it):
00392 container_const_reference<self_type> (m), it_ (it) {}
00393 BOOST_UBLAS_INLINE
00394 const_iterator1 (const iterator1 &it):
00395 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00396
00397
00398 BOOST_UBLAS_INLINE
00399 const_iterator1 &operator ++ () {
00400 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
00401 return *this;
00402 }
00403 BOOST_UBLAS_INLINE
00404 const_iterator1 &operator -- () {
00405 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
00406 return *this;
00407 }
00408 BOOST_UBLAS_INLINE
00409 const_iterator1 &operator += (difference_type n) {
00410 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
00411 return *this;
00412 }
00413 BOOST_UBLAS_INLINE
00414 const_iterator1 &operator -= (difference_type n) {
00415 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
00416 return *this;
00417 }
00418 BOOST_UBLAS_INLINE
00419 difference_type operator - (const const_iterator1 &it) const {
00420 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00421 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
00422 }
00423
00424
00425 BOOST_UBLAS_INLINE
00426 const_reference operator * () const {
00427 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00428 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00429 return *it_;
00430 }
00431 BOOST_UBLAS_INLINE
00432 const_reference operator [] (difference_type n) const {
00433 return *(*this + n);
00434 }
00435
00436 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00437 BOOST_UBLAS_INLINE
00438 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00439 typename self_type::
00440 #endif
00441 const_iterator2 begin () const {
00442 const self_type &m = (*this) ();
00443 return m.find2 (1, index1 (), 0);
00444 }
00445 BOOST_UBLAS_INLINE
00446 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00447 typename self_type::
00448 #endif
00449 const_iterator2 end () const {
00450 const self_type &m = (*this) ();
00451 return m.find2 (1, index1 (), m.size2 ());
00452 }
00453 BOOST_UBLAS_INLINE
00454 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00455 typename self_type::
00456 #endif
00457 const_reverse_iterator2 rbegin () const {
00458 return const_reverse_iterator2 (end ());
00459 }
00460 BOOST_UBLAS_INLINE
00461 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00462 typename self_type::
00463 #endif
00464 const_reverse_iterator2 rend () const {
00465 return const_reverse_iterator2 (begin ());
00466 }
00467 #endif
00468
00469
00470 BOOST_UBLAS_INLINE
00471 size_type index1 () const {
00472 const self_type &m = (*this) ();
00473 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
00474 }
00475 BOOST_UBLAS_INLINE
00476 size_type index2 () const {
00477 const self_type &m = (*this) ();
00478 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
00479 }
00480
00481
00482 BOOST_UBLAS_INLINE
00483 const_iterator1 &operator = (const const_iterator1 &it) {
00484 container_const_reference<self_type>::assign (&it ());
00485 it_ = it.it_;
00486 return *this;
00487 }
00488
00489
00490 BOOST_UBLAS_INLINE
00491 bool operator == (const const_iterator1 &it) const {
00492 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00493 return it_ == it.it_;
00494 }
00495 BOOST_UBLAS_INLINE
00496 bool operator < (const const_iterator1 &it) const {
00497 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00498 return it_ < it.it_;
00499 }
00500
00501 private:
00502 const_subiterator_type it_;
00503
00504 friend class iterator1;
00505 };
00506 #endif
00507
00508 BOOST_UBLAS_INLINE
00509 const_iterator1 begin1 () const {
00510 return find1 (0, 0, 0);
00511 }
00512 BOOST_UBLAS_INLINE
00513 const_iterator1 end1 () const {
00514 return find1 (0, size1_, 0);
00515 }
00516
00517 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00518 class iterator1:
00519 public container_reference<matrix>,
00520 public random_access_iterator_base<dense_random_access_iterator_tag,
00521 iterator1, value_type> {
00522 public:
00523 typedef typename matrix::value_type value_type;
00524 typedef typename matrix::difference_type difference_type;
00525 typedef typename matrix::reference reference;
00526 typedef typename matrix::pointer pointer;
00527
00528 typedef iterator2 dual_iterator_type;
00529 typedef reverse_iterator2 dual_reverse_iterator_type;
00530
00531
00532 BOOST_UBLAS_INLINE
00533 iterator1 ():
00534 container_reference<self_type> (), it_ () {}
00535 BOOST_UBLAS_INLINE
00536 iterator1 (self_type &m, const subiterator_type &it):
00537 container_reference<self_type> (m), it_ (it) {}
00538
00539
00540 BOOST_UBLAS_INLINE
00541 iterator1 &operator ++ () {
00542 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
00543 return *this;
00544 }
00545 BOOST_UBLAS_INLINE
00546 iterator1 &operator -- () {
00547 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
00548 return *this;
00549 }
00550 BOOST_UBLAS_INLINE
00551 iterator1 &operator += (difference_type n) {
00552 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
00553 return *this;
00554 }
00555 BOOST_UBLAS_INLINE
00556 iterator1 &operator -= (difference_type n) {
00557 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
00558 return *this;
00559 }
00560 BOOST_UBLAS_INLINE
00561 difference_type operator - (const iterator1 &it) const {
00562 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00563 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
00564 }
00565
00566
00567 BOOST_UBLAS_INLINE
00568 reference operator * () const {
00569 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00570 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00571 return *it_;
00572 }
00573 BOOST_UBLAS_INLINE
00574 reference operator [] (difference_type n) const {
00575 return *(*this + n);
00576 }
00577
00578 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00579 BOOST_UBLAS_INLINE
00580 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00581 typename self_type::
00582 #endif
00583 iterator2 begin () const {
00584 self_type &m = (*this) ();
00585 return m.find2 (1, index1 (), 0);
00586 }
00587 BOOST_UBLAS_INLINE
00588 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00589 typename self_type::
00590 #endif
00591 iterator2 end () const {
00592 self_type &m = (*this) ();
00593 return m.find2 (1, index1 (), m.size2 ());
00594 }
00595 BOOST_UBLAS_INLINE
00596 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00597 typename self_type::
00598 #endif
00599 reverse_iterator2 rbegin () const {
00600 return reverse_iterator2 (end ());
00601 }
00602 BOOST_UBLAS_INLINE
00603 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00604 typename self_type::
00605 #endif
00606 reverse_iterator2 rend () const {
00607 return reverse_iterator2 (begin ());
00608 }
00609 #endif
00610
00611
00612 BOOST_UBLAS_INLINE
00613 size_type index1 () const {
00614 self_type &m = (*this) ();
00615 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
00616 }
00617 BOOST_UBLAS_INLINE
00618 size_type index2 () const {
00619 self_type &m = (*this) ();
00620 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
00621 }
00622
00623
00624 BOOST_UBLAS_INLINE
00625 iterator1 &operator = (const iterator1 &it) {
00626 container_reference<self_type>::assign (&it ());
00627 it_ = it.it_;
00628 return *this;
00629 }
00630
00631
00632 BOOST_UBLAS_INLINE
00633 bool operator == (const iterator1 &it) const {
00634 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00635 return it_ == it.it_;
00636 }
00637 BOOST_UBLAS_INLINE
00638 bool operator < (const iterator1 &it) const {
00639 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00640 return it_ < it.it_;
00641 }
00642
00643 private:
00644 subiterator_type it_;
00645
00646 friend class const_iterator1;
00647 };
00648 #endif
00649
00650 BOOST_UBLAS_INLINE
00651 iterator1 begin1 () {
00652 return find1 (0, 0, 0);
00653 }
00654 BOOST_UBLAS_INLINE
00655 iterator1 end1 () {
00656 return find1 (0, size1_, 0);
00657 }
00658
00659 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00660 class const_iterator2:
00661 public container_const_reference<matrix>,
00662 public random_access_iterator_base<dense_random_access_iterator_tag,
00663 const_iterator2, value_type> {
00664 public:
00665 typedef typename matrix::value_type value_type;
00666 typedef typename matrix::difference_type difference_type;
00667 typedef typename matrix::const_reference reference;
00668 typedef const typename matrix::pointer pointer;
00669
00670 typedef const_iterator1 dual_iterator_type;
00671 typedef const_reverse_iterator1 dual_reverse_iterator_type;
00672
00673
00674 BOOST_UBLAS_INLINE
00675 const_iterator2 ():
00676 container_const_reference<self_type> (), it_ () {}
00677 BOOST_UBLAS_INLINE
00678 const_iterator2 (const self_type &m, const const_subiterator_type &it):
00679 container_const_reference<self_type> (m), it_ (it) {}
00680 BOOST_UBLAS_INLINE
00681 const_iterator2 (const iterator2 &it):
00682 container_const_reference<self_type> (it ()), it_ (it.it_) {}
00683
00684
00685 BOOST_UBLAS_INLINE
00686 const_iterator2 &operator ++ () {
00687 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
00688 return *this;
00689 }
00690 BOOST_UBLAS_INLINE
00691 const_iterator2 &operator -- () {
00692 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
00693 return *this;
00694 }
00695 BOOST_UBLAS_INLINE
00696 const_iterator2 &operator += (difference_type n) {
00697 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
00698 return *this;
00699 }
00700 BOOST_UBLAS_INLINE
00701 const_iterator2 &operator -= (difference_type n) {
00702 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
00703 return *this;
00704 }
00705 BOOST_UBLAS_INLINE
00706 difference_type operator - (const const_iterator2 &it) const {
00707 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00708 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
00709 }
00710
00711
00712 BOOST_UBLAS_INLINE
00713 const_reference operator * () const {
00714 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00715 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00716 return *it_;
00717 }
00718 BOOST_UBLAS_INLINE
00719 const_reference operator [] (difference_type n) const {
00720 return *(*this + n);
00721 }
00722
00723 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00724 BOOST_UBLAS_INLINE
00725 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00726 typename self_type::
00727 #endif
00728 const_iterator1 begin () const {
00729 const self_type &m = (*this) ();
00730 return m.find1 (1, 0, index2 ());
00731 }
00732 BOOST_UBLAS_INLINE
00733 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00734 typename self_type::
00735 #endif
00736 const_iterator1 end () const {
00737 const self_type &m = (*this) ();
00738 return m.find1 (1, m.size1 (), index2 ());
00739 }
00740 BOOST_UBLAS_INLINE
00741 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00742 typename self_type::
00743 #endif
00744 const_reverse_iterator1 rbegin () const {
00745 return const_reverse_iterator1 (end ());
00746 }
00747 BOOST_UBLAS_INLINE
00748 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00749 typename self_type::
00750 #endif
00751 const_reverse_iterator1 rend () const {
00752 return const_reverse_iterator1 (begin ());
00753 }
00754 #endif
00755
00756
00757 BOOST_UBLAS_INLINE
00758 size_type index1 () const {
00759 const self_type &m = (*this) ();
00760 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
00761 }
00762 BOOST_UBLAS_INLINE
00763 size_type index2 () const {
00764 const self_type &m = (*this) ();
00765 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
00766 }
00767
00768
00769 BOOST_UBLAS_INLINE
00770 const_iterator2 &operator = (const const_iterator2 &it) {
00771 container_const_reference<self_type>::assign (&it ());
00772 it_ = it.it_;
00773 return *this;
00774 }
00775
00776
00777 BOOST_UBLAS_INLINE
00778 bool operator == (const const_iterator2 &it) const {
00779 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00780 return it_ == it.it_;
00781 }
00782 BOOST_UBLAS_INLINE
00783 bool operator < (const const_iterator2 &it) const {
00784 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00785 return it_ < it.it_;
00786 }
00787
00788 private:
00789 const_subiterator_type it_;
00790
00791 friend class iterator2;
00792 };
00793 #endif
00794
00795 BOOST_UBLAS_INLINE
00796 const_iterator2 begin2 () const {
00797 return find2 (0, 0, 0);
00798 }
00799 BOOST_UBLAS_INLINE
00800 const_iterator2 end2 () const {
00801 return find2 (0, 0, size2_);
00802 }
00803
00804 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00805 class iterator2:
00806 public container_reference<matrix>,
00807 public random_access_iterator_base<dense_random_access_iterator_tag,
00808 iterator2, value_type> {
00809 public:
00810 typedef typename matrix::value_type value_type;
00811 typedef typename matrix::difference_type difference_type;
00812 typedef typename matrix::reference reference;
00813 typedef typename matrix::pointer pointer;
00814
00815 typedef iterator1 dual_iterator_type;
00816 typedef reverse_iterator1 dual_reverse_iterator_type;
00817
00818
00819 BOOST_UBLAS_INLINE
00820 iterator2 ():
00821 container_reference<self_type> (), it_ () {}
00822 BOOST_UBLAS_INLINE
00823 iterator2 (self_type &m, const subiterator_type &it):
00824 container_reference<self_type> (m), it_ (it) {}
00825
00826
00827 BOOST_UBLAS_INLINE
00828 iterator2 &operator ++ () {
00829 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
00830 return *this;
00831 }
00832 BOOST_UBLAS_INLINE
00833 iterator2 &operator -- () {
00834 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
00835 return *this;
00836 }
00837 BOOST_UBLAS_INLINE
00838 iterator2 &operator += (difference_type n) {
00839 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
00840 return *this;
00841 }
00842 BOOST_UBLAS_INLINE
00843 iterator2 &operator -= (difference_type n) {
00844 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
00845 return *this;
00846 }
00847 BOOST_UBLAS_INLINE
00848 difference_type operator - (const iterator2 &it) const {
00849 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00850 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
00851 }
00852
00853
00854 BOOST_UBLAS_INLINE
00855 reference operator * () const {
00856 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
00857 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
00858 return *it_;
00859 }
00860 BOOST_UBLAS_INLINE
00861 reference operator [] (difference_type n) const {
00862 return *(*this + n);
00863 }
00864
00865 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
00866 BOOST_UBLAS_INLINE
00867 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00868 typename self_type::
00869 #endif
00870 iterator1 begin () const {
00871 self_type &m = (*this) ();
00872 return m.find1 (1, 0, index2 ());
00873 }
00874 BOOST_UBLAS_INLINE
00875 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00876 typename self_type::
00877 #endif
00878 iterator1 end () const {
00879 self_type &m = (*this) ();
00880 return m.find1 (1, m.size1 (), index2 ());
00881 }
00882 BOOST_UBLAS_INLINE
00883 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00884 typename self_type::
00885 #endif
00886 reverse_iterator1 rbegin () const {
00887 return reverse_iterator1 (end ());
00888 }
00889 BOOST_UBLAS_INLINE
00890 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
00891 typename self_type::
00892 #endif
00893 reverse_iterator1 rend () const {
00894 return reverse_iterator1 (begin ());
00895 }
00896 #endif
00897
00898
00899 BOOST_UBLAS_INLINE
00900 size_type index1 () const {
00901 self_type &m = (*this) ();
00902 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
00903 }
00904 BOOST_UBLAS_INLINE
00905 size_type index2 () const {
00906 self_type &m = (*this) ();
00907 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
00908 }
00909
00910
00911 BOOST_UBLAS_INLINE
00912 iterator2 &operator = (const iterator2 &it) {
00913 container_reference<self_type>::assign (&it ());
00914 it_ = it.it_;
00915 return *this;
00916 }
00917
00918
00919 BOOST_UBLAS_INLINE
00920 bool operator == (const iterator2 &it) const {
00921 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00922 return it_ == it.it_;
00923 }
00924 BOOST_UBLAS_INLINE
00925 bool operator < (const iterator2 &it) const {
00926 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
00927 return it_ < it.it_;
00928 }
00929
00930 private:
00931 subiterator_type it_;
00932
00933 friend class const_iterator2;
00934 };
00935 #endif
00936
00937 BOOST_UBLAS_INLINE
00938 iterator2 begin2 () {
00939 return find2 (0, 0, 0);
00940 }
00941 BOOST_UBLAS_INLINE
00942 iterator2 end2 () {
00943 return find2 (0, 0, size2_);
00944 }
00945
00946
00947
00948 BOOST_UBLAS_INLINE
00949 const_reverse_iterator1 rbegin1 () const {
00950 return const_reverse_iterator1 (end1 ());
00951 }
00952 BOOST_UBLAS_INLINE
00953 const_reverse_iterator1 rend1 () const {
00954 return const_reverse_iterator1 (begin1 ());
00955 }
00956
00957 BOOST_UBLAS_INLINE
00958 reverse_iterator1 rbegin1 () {
00959 return reverse_iterator1 (end1 ());
00960 }
00961 BOOST_UBLAS_INLINE
00962 reverse_iterator1 rend1 () {
00963 return reverse_iterator1 (begin1 ());
00964 }
00965
00966 BOOST_UBLAS_INLINE
00967 const_reverse_iterator2 rbegin2 () const {
00968 return const_reverse_iterator2 (end2 ());
00969 }
00970 BOOST_UBLAS_INLINE
00971 const_reverse_iterator2 rend2 () const {
00972 return const_reverse_iterator2 (begin2 ());
00973 }
00974
00975 BOOST_UBLAS_INLINE
00976 reverse_iterator2 rbegin2 () {
00977 return reverse_iterator2 (end2 ());
00978 }
00979 BOOST_UBLAS_INLINE
00980 reverse_iterator2 rend2 () {
00981 return reverse_iterator2 (begin2 ());
00982 }
00983
00984
00985 template<class Archive>
00986 void serialize(Archive & ar, const unsigned int ){
00987
00988
00989
00990 serialization::collection_size_type s1 (size1_);
00991 serialization::collection_size_type s2 (size2_);
00992
00993
00994 ar & serialization::make_nvp("size1",s1)
00995 & serialization::make_nvp("size2",s2);
00996
00997
00998 if (Archive::is_loading::value) {
00999 size1_ = s1;
01000 size2_ = s2;
01001 }
01002 ar & serialization::make_nvp("data",data_);
01003 }
01004
01005 private:
01006 size_type size1_;
01007 size_type size2_;
01008 array_type data_;
01009 };
01010
01027 template<class T, std::size_t M, std::size_t N, class L>
01028 class bounded_matrix:
01029 public matrix<T, L, bounded_array<T, M * N> > {
01030
01031 typedef matrix<T, L, bounded_array<T, M * N> > matrix_type;
01032 public:
01033 typedef typename matrix_type::size_type size_type;
01034 static const size_type max_size1 = M;
01035 static const size_type max_size2 = N;
01036
01037
01038 BOOST_UBLAS_INLINE
01039 bounded_matrix ():
01040 matrix_type (M, N) {}
01041 BOOST_UBLAS_INLINE
01042 bounded_matrix (size_type size1, size_type size2):
01043 matrix_type (size1, size2) {}
01044 BOOST_UBLAS_INLINE
01045 bounded_matrix (const bounded_matrix &m):
01046 matrix_type (m) {}
01047 template<class A2>
01048 BOOST_UBLAS_INLINE
01049 bounded_matrix (const matrix<T, L, A2> &m):
01050 matrix_type (m) {}
01051 template<class AE>
01052 BOOST_UBLAS_INLINE
01053 bounded_matrix (const matrix_expression<AE> &ae):
01054 matrix_type (ae) {}
01055 BOOST_UBLAS_INLINE
01056 ~bounded_matrix () {}
01057
01058
01059 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
01060
01062 BOOST_UBLAS_INLINE
01063 bounded_matrix &operator = (bounded_matrix m) {
01064 matrix_type::operator = (m);
01065 return *this;
01066 }
01067 #else
01068 BOOST_UBLAS_INLINE
01069 bounded_matrix &operator = (const bounded_matrix &m) {
01070 matrix_type::operator = (m);
01071 return *this;
01072 }
01073 #endif
01074 template<class L2, class A2>
01075 BOOST_UBLAS_INLINE
01076 bounded_matrix &operator = (const matrix<T, L2, A2> &m) {
01077 matrix_type::operator = (m);
01078 return *this;
01079 }
01080 template<class C>
01081 BOOST_UBLAS_INLINE
01082 bounded_matrix &operator = (const matrix_container<C> &m) {
01083 matrix_type::operator = (m);
01084 return *this;
01085 }
01086 template<class AE>
01087 BOOST_UBLAS_INLINE
01088 bounded_matrix &operator = (const matrix_expression<AE> &ae) {
01089 matrix_type::operator = (ae);
01090 return *this;
01091 }
01092 };
01093
01109 template<class T, class L, class A>
01110 class vector_of_vector:
01111 public matrix_container<vector_of_vector<T, L, A> > {
01112
01113 typedef T *pointer;
01114 typedef L layout_type;
01115 typedef vector_of_vector<T, L, A> self_type;
01116 public:
01117 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01118 using matrix_container<self_type>::operator ();
01119 #endif
01120 typedef typename A::size_type size_type;
01121 typedef typename A::difference_type difference_type;
01122 typedef T value_type;
01123 typedef const T &const_reference;
01124 typedef T &reference;
01125 typedef A array_type;
01126 typedef const matrix_reference<const self_type> const_closure_type;
01127 typedef matrix_reference<self_type> closure_type;
01128 typedef vector<T, typename A::value_type> vector_temporary_type;
01129 typedef self_type matrix_temporary_type;
01130 typedef dense_tag storage_category;
01131
01132
01133
01134 typedef typename L::orientation_category orientation_category;
01135
01136
01137 BOOST_UBLAS_INLINE
01138 vector_of_vector ():
01139 matrix_container<self_type> (),
01140 size1_ (0), size2_ (0), data_ (1) {}
01141 BOOST_UBLAS_INLINE
01142 vector_of_vector (size_type size1, size_type size2):
01143 matrix_container<self_type> (),
01144 size1_ (size1), size2_ (size2), data_ (1) {
01145 resize (size1, size2, true);
01146 }
01147 BOOST_UBLAS_INLINE
01148 vector_of_vector (const vector_of_vector &m):
01149 matrix_container<self_type> (),
01150 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
01151 template<class AE>
01152 BOOST_UBLAS_INLINE
01153 vector_of_vector (const matrix_expression<AE> &ae):
01154 matrix_container<self_type> (),
01155 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) {
01156 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
01157 data ()[k].resize (layout_type::size_m (size1_, size2_));
01158 matrix_assign<scalar_assign> (*this, ae);
01159 }
01160
01161
01162 BOOST_UBLAS_INLINE
01163 size_type size1 () const {
01164 return size1_;
01165 }
01166 BOOST_UBLAS_INLINE
01167 size_type size2 () const {
01168 return size2_;
01169 }
01170
01171
01172 BOOST_UBLAS_INLINE
01173 const array_type &data () const {
01174 return data_;
01175 }
01176 BOOST_UBLAS_INLINE
01177 array_type &data () {
01178 return data_;
01179 }
01180
01181
01182 BOOST_UBLAS_INLINE
01183 void resize (size_type size1, size_type size2, bool preserve = true) {
01184 size1_ = size1;
01185 size2_ = size2;
01186 if (preserve)
01187 data ().resize (layout_type::size_M (size1, size2) + 1, typename array_type::value_type ());
01188 else
01189 data ().resize (layout_type::size_M (size1, size2) + 1);
01190 for (size_type k = 0; k < layout_type::size_M (size1, size2); ++ k) {
01191 if (preserve)
01192 data () [k].resize (layout_type::size_m (size1, size2), value_type ());
01193 else
01194 data () [k].resize (layout_type::size_m (size1, size2));
01195 }
01196 }
01197
01198
01199 BOOST_UBLAS_INLINE
01200 const_reference operator () (size_type i, size_type j) const {
01201 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
01202 }
01203 BOOST_UBLAS_INLINE
01204 reference at_element (size_type i, size_type j) {
01205 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
01206 }
01207 BOOST_UBLAS_INLINE
01208 reference operator () (size_type i, size_type j) {
01209 return at_element (i, j);
01210 }
01211
01212
01213 BOOST_UBLAS_INLINE
01214 reference insert_element (size_type i, size_type j, const_reference t) {
01215 return (at_element (i, j) = t);
01216 }
01217 BOOST_UBLAS_INLINE
01218 void erase_element (size_type i, size_type j) {
01219 at_element (i, j) = value_type();
01220 }
01221
01222
01223 BOOST_UBLAS_INLINE
01224 void clear () {
01225 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
01226 std::fill (data () [k].begin (), data () [k].end (), value_type());
01227 }
01228
01229
01230 BOOST_UBLAS_INLINE
01231 vector_of_vector &operator = (const vector_of_vector &m) {
01232 size1_ = m.size1_;
01233 size2_ = m.size2_;
01234 data () = m.data ();
01235 return *this;
01236 }
01237 BOOST_UBLAS_INLINE
01238 vector_of_vector &assign_temporary (vector_of_vector &m) {
01239 swap (m);
01240 return *this;
01241 }
01242 template<class AE>
01243 BOOST_UBLAS_INLINE
01244 vector_of_vector &operator = (const matrix_expression<AE> &ae) {
01245 self_type temporary (ae);
01246 return assign_temporary (temporary);
01247 }
01248 template<class C>
01249 BOOST_UBLAS_INLINE
01250 vector_of_vector &operator = (const matrix_container<C> &m) {
01251 resize (m ().size1 (), m ().size2 (), false);
01252 assign (m);
01253 return *this;
01254 }
01255 template<class AE>
01256 BOOST_UBLAS_INLINE
01257 vector_of_vector &assign (const matrix_expression<AE> &ae) {
01258 matrix_assign<scalar_assign> (*this, ae);
01259 return *this;
01260 }
01261 template<class AE>
01262 BOOST_UBLAS_INLINE
01263 vector_of_vector& operator += (const matrix_expression<AE> &ae) {
01264 self_type temporary (*this + ae);
01265 return assign_temporary (temporary);
01266 }
01267 template<class C>
01268 BOOST_UBLAS_INLINE
01269 vector_of_vector &operator += (const matrix_container<C> &m) {
01270 plus_assign (m);
01271 return *this;
01272 }
01273 template<class AE>
01274 BOOST_UBLAS_INLINE
01275 vector_of_vector &plus_assign (const matrix_expression<AE> &ae) {
01276 matrix_assign<scalar_plus_assign> (*this, ae);
01277 return *this;
01278 }
01279 template<class AE>
01280 BOOST_UBLAS_INLINE
01281 vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
01282 self_type temporary (*this - ae);
01283 return assign_temporary (temporary);
01284 }
01285 template<class C>
01286 BOOST_UBLAS_INLINE
01287 vector_of_vector &operator -= (const matrix_container<C> &m) {
01288 minus_assign (m);
01289 return *this;
01290 }
01291 template<class AE>
01292 BOOST_UBLAS_INLINE
01293 vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
01294 matrix_assign<scalar_minus_assign> (*this, ae);
01295 return *this;
01296 }
01297 template<class AT>
01298 BOOST_UBLAS_INLINE
01299 vector_of_vector& operator *= (const AT &at) {
01300 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
01301 return *this;
01302 }
01303 template<class AT>
01304 BOOST_UBLAS_INLINE
01305 vector_of_vector& operator /= (const AT &at) {
01306 matrix_assign_scalar<scalar_divides_assign> (*this, at);
01307 return *this;
01308 }
01309
01310
01311 BOOST_UBLAS_INLINE
01312 void swap (vector_of_vector &m) {
01313 if (this != &m) {
01314 std::swap (size1_, m.size1_);
01315 std::swap (size2_, m.size2_);
01316 data ().swap (m.data ());
01317 }
01318 }
01319 BOOST_UBLAS_INLINE
01320 friend void swap (vector_of_vector &m1, vector_of_vector &m2) {
01321 m1.swap (m2);
01322 }
01323
01324
01325 private:
01326
01327 typedef typename A::value_type::const_iterator const_subiterator_type;
01328 typedef typename A::value_type::iterator subiterator_type;
01329 public:
01330 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01331 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
01332 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
01333 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
01334 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
01335 #else
01336 class const_iterator1;
01337 class iterator1;
01338 class const_iterator2;
01339 class iterator2;
01340 #endif
01341 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
01342 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
01343 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
01344 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
01345
01346
01347 BOOST_UBLAS_INLINE
01348 const_iterator1 find1 (int , size_type i, size_type j) const {
01349 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01350 return const_iterator1 (*this, i, j);
01351 #else
01352 return const_iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
01353 #endif
01354 }
01355 BOOST_UBLAS_INLINE
01356 iterator1 find1 (int , size_type i, size_type j) {
01357 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01358 return iterator1 (*this, i, j);
01359 #else
01360 return iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
01361 #endif
01362 }
01363 BOOST_UBLAS_INLINE
01364 const_iterator2 find2 (int , size_type i, size_type j) const {
01365 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01366 return const_iterator2 (*this, i, j);
01367 #else
01368 return const_iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
01369 #endif
01370 }
01371 BOOST_UBLAS_INLINE
01372 iterator2 find2 (int , size_type i, size_type j) {
01373 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01374 return iterator2 (*this, i, j);
01375 #else
01376 return iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
01377 #endif
01378 }
01379
01380
01381 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01382 class const_iterator1:
01383 public container_const_reference<vector_of_vector>,
01384 public random_access_iterator_base<dense_random_access_iterator_tag,
01385 const_iterator1, value_type> {
01386 public:
01387 typedef typename vector_of_vector::value_type value_type;
01388 typedef typename vector_of_vector::difference_type difference_type;
01389 typedef typename vector_of_vector::const_reference reference;
01390 typedef const typename vector_of_vector::pointer pointer;
01391
01392 typedef const_iterator2 dual_iterator_type;
01393 typedef const_reverse_iterator2 dual_reverse_iterator_type;
01394
01395
01396 BOOST_UBLAS_INLINE
01397 const_iterator1 ():
01398 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
01399 BOOST_UBLAS_INLINE
01400 const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
01401 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
01402 BOOST_UBLAS_INLINE
01403 const_iterator1 (const iterator1 &it):
01404 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
01405
01406
01407 BOOST_UBLAS_INLINE
01408 const_iterator1 &operator ++ () {
01409 ++ i_;
01410 const self_type &m = (*this) ();
01411 if (layout_type::fast_i ())
01412 ++ it_;
01413 else
01414 it_ = m.find1 (1, i_, j_).it_;
01415 return *this;
01416 }
01417 BOOST_UBLAS_INLINE
01418 const_iterator1 &operator -- () {
01419 -- i_;
01420 const self_type &m = (*this) ();
01421 if (layout_type::fast_i ())
01422 -- it_;
01423 else
01424 it_ = m.find1 (1, i_, j_).it_;
01425 return *this;
01426 }
01427 BOOST_UBLAS_INLINE
01428 const_iterator1 &operator += (difference_type n) {
01429 i_ += n;
01430 const self_type &m = (*this) ();
01431 it_ = m.find1 (1, i_, j_).it_;
01432 return *this;
01433 }
01434 BOOST_UBLAS_INLINE
01435 const_iterator1 &operator -= (difference_type n) {
01436 i_ -= n;
01437 const self_type &m = (*this) ();
01438 it_ = m.find1 (1, i_, j_).it_;
01439 return *this;
01440 }
01441 BOOST_UBLAS_INLINE
01442 difference_type operator - (const const_iterator1 &it) const {
01443 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01444 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01445 return index1 () - it.index1 ();
01446 }
01447
01448
01449 BOOST_UBLAS_INLINE
01450 const_reference operator * () const {
01451 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01452 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01453 return *it_;
01454 }
01455 BOOST_UBLAS_INLINE
01456 const_reference operator [] (difference_type n) const {
01457 return *(*this + n);
01458 }
01459
01460 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01461 BOOST_UBLAS_INLINE
01462 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01463 typename self_type::
01464 #endif
01465 const_iterator2 begin () const {
01466 const self_type &m = (*this) ();
01467 return m.find2 (1, index1 (), 0);
01468 }
01469 BOOST_UBLAS_INLINE
01470 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01471 typename self_type::
01472 #endif
01473 const_iterator2 end () const {
01474 const self_type &m = (*this) ();
01475 return m.find2 (1, index1 (), m.size2 ());
01476 }
01477 BOOST_UBLAS_INLINE
01478 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01479 typename self_type::
01480 #endif
01481 const_reverse_iterator2 rbegin () const {
01482 return const_reverse_iterator2 (end ());
01483 }
01484 BOOST_UBLAS_INLINE
01485 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01486 typename self_type::
01487 #endif
01488 const_reverse_iterator2 rend () const {
01489 return const_reverse_iterator2 (begin ());
01490 }
01491 #endif
01492
01493
01494 BOOST_UBLAS_INLINE
01495 size_type index1 () const {
01496 return i_;
01497 }
01498 BOOST_UBLAS_INLINE
01499 size_type index2 () const {
01500 return j_;
01501 }
01502
01503
01504 BOOST_UBLAS_INLINE
01505 const_iterator1 &operator = (const const_iterator1 &it) {
01506 container_const_reference<self_type>::assign (&it ());
01507 it_ = it.it_;
01508 return *this;
01509 }
01510
01511
01512 BOOST_UBLAS_INLINE
01513 bool operator == (const const_iterator1 &it) const {
01514 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01515 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01516 return it_ == it.it_;
01517 }
01518 BOOST_UBLAS_INLINE
01519 bool operator < (const const_iterator1 &it) const {
01520 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01521 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01522 return it_ < it.it_;
01523 }
01524
01525 private:
01526 size_type i_;
01527 size_type j_;
01528 const_subiterator_type it_;
01529
01530 friend class iterator1;
01531 };
01532 #endif
01533
01534 BOOST_UBLAS_INLINE
01535 const_iterator1 begin1 () const {
01536 return find1 (0, 0, 0);
01537 }
01538 BOOST_UBLAS_INLINE
01539 const_iterator1 end1 () const {
01540 return find1 (0, size1_, 0);
01541 }
01542
01543 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01544 class iterator1:
01545 public container_reference<vector_of_vector>,
01546 public random_access_iterator_base<dense_random_access_iterator_tag,
01547 iterator1, value_type> {
01548 public:
01549 typedef typename vector_of_vector::value_type value_type;
01550 typedef typename vector_of_vector::difference_type difference_type;
01551 typedef typename vector_of_vector::reference reference;
01552 typedef typename vector_of_vector::pointer pointer;
01553
01554 typedef iterator2 dual_iterator_type;
01555 typedef reverse_iterator2 dual_reverse_iterator_type;
01556
01557
01558 BOOST_UBLAS_INLINE
01559 iterator1 ():
01560 container_reference<self_type> (), i_ (), j_ (), it_ () {}
01561 BOOST_UBLAS_INLINE
01562 iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it):
01563 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
01564
01565
01566 BOOST_UBLAS_INLINE
01567 iterator1 &operator ++ () {
01568 ++ i_;
01569 self_type &m = (*this) ();
01570 if (layout_type::fast_i ())
01571 ++ it_;
01572 else
01573 it_ = m.find1 (1, i_, j_).it_;
01574 return *this;
01575 }
01576 BOOST_UBLAS_INLINE
01577 iterator1 &operator -- () {
01578 -- i_;
01579 self_type &m = (*this) ();
01580 if (layout_type::fast_i ())
01581 -- it_;
01582 else
01583 it_ = m.find1 (1, i_, j_).it_;
01584 return *this;
01585 }
01586 BOOST_UBLAS_INLINE
01587 iterator1 &operator += (difference_type n) {
01588 i_ += n;
01589 self_type &m = (*this) ();
01590 it_ = m.find1 (1, i_, j_).it_;
01591 return *this;
01592 }
01593 BOOST_UBLAS_INLINE
01594 iterator1 &operator -= (difference_type n) {
01595 i_ -= n;
01596 self_type &m = (*this) ();
01597 it_ = m.find1 (1, i_, j_).it_;
01598 return *this;
01599 }
01600 BOOST_UBLAS_INLINE
01601 difference_type operator - (const iterator1 &it) const {
01602 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01603 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01604 return index1 () - it.index1 ();
01605 }
01606
01607
01608 BOOST_UBLAS_INLINE
01609 reference operator * () const {
01610 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01611 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01612 return *it_;
01613 }
01614 BOOST_UBLAS_INLINE
01615 reference operator [] (difference_type n) const {
01616 return *(*this + n);
01617 }
01618
01619 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01620 BOOST_UBLAS_INLINE
01621 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01622 typename self_type::
01623 #endif
01624 iterator2 begin () const {
01625 self_type &m = (*this) ();
01626 return m.find2 (1, index1 (), 0);
01627 }
01628 BOOST_UBLAS_INLINE
01629 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01630 typename self_type::
01631 #endif
01632 iterator2 end () const {
01633 self_type &m = (*this) ();
01634 return m.find2 (1, index1 (), m.size2 ());
01635 }
01636 BOOST_UBLAS_INLINE
01637 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01638 typename self_type::
01639 #endif
01640 reverse_iterator2 rbegin () const {
01641 return reverse_iterator2 (end ());
01642 }
01643 BOOST_UBLAS_INLINE
01644 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01645 typename self_type::
01646 #endif
01647 reverse_iterator2 rend () const {
01648 return reverse_iterator2 (begin ());
01649 }
01650 #endif
01651
01652
01653 BOOST_UBLAS_INLINE
01654 size_type index1 () const {
01655 return i_;
01656 }
01657 BOOST_UBLAS_INLINE
01658 size_type index2 () const {
01659 return j_;
01660 }
01661
01662
01663 BOOST_UBLAS_INLINE
01664 iterator1 &operator = (const iterator1 &it) {
01665 container_reference<self_type>::assign (&it ());
01666 it_ = it.it_;
01667 return *this;
01668 }
01669
01670
01671 BOOST_UBLAS_INLINE
01672 bool operator == (const iterator1 &it) const {
01673 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01674 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01675 return it_ == it.it_;
01676 }
01677 BOOST_UBLAS_INLINE
01678 bool operator < (const iterator1 &it) const {
01679 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01680 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
01681 return it_ < it.it_;
01682 }
01683
01684 private:
01685 size_type i_;
01686 size_type j_;
01687 subiterator_type it_;
01688
01689 friend class const_iterator1;
01690 };
01691 #endif
01692
01693 BOOST_UBLAS_INLINE
01694 iterator1 begin1 () {
01695 return find1 (0, 0, 0);
01696 }
01697 BOOST_UBLAS_INLINE
01698 iterator1 end1 () {
01699 return find1 (0, size1_, 0);
01700 }
01701
01702 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01703 class const_iterator2:
01704 public container_const_reference<vector_of_vector>,
01705 public random_access_iterator_base<dense_random_access_iterator_tag,
01706 const_iterator2, value_type> {
01707 public:
01708 typedef typename vector_of_vector::value_type value_type;
01709 typedef typename vector_of_vector::difference_type difference_type;
01710 typedef typename vector_of_vector::const_reference reference;
01711 typedef const typename vector_of_vector::pointer pointer;
01712
01713 typedef const_iterator1 dual_iterator_type;
01714 typedef const_reverse_iterator1 dual_reverse_iterator_type;
01715
01716
01717 BOOST_UBLAS_INLINE
01718 const_iterator2 ():
01719 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
01720 BOOST_UBLAS_INLINE
01721 const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
01722 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
01723 BOOST_UBLAS_INLINE
01724 const_iterator2 (const iterator2 &it):
01725 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
01726
01727
01728 BOOST_UBLAS_INLINE
01729 const_iterator2 &operator ++ () {
01730 ++ j_;
01731 const self_type &m = (*this) ();
01732 if (layout_type::fast_j ())
01733 ++ it_;
01734 else
01735 it_ = m.find2 (1, i_, j_).it_;
01736 return *this;
01737 }
01738 BOOST_UBLAS_INLINE
01739 const_iterator2 &operator -- () {
01740 -- j_;
01741 const self_type &m = (*this) ();
01742 if (layout_type::fast_j ())
01743 -- it_;
01744 else
01745 it_ = m.find2 (1, i_, j_).it_;
01746 return *this;
01747 }
01748 BOOST_UBLAS_INLINE
01749 const_iterator2 &operator += (difference_type n) {
01750 j_ += n;
01751 const self_type &m = (*this) ();
01752 it_ = m.find2 (1, i_, j_).it_;
01753 return *this;
01754 }
01755 BOOST_UBLAS_INLINE
01756 const_iterator2 &operator -= (difference_type n) {
01757 j_ -= n;
01758 const self_type &m = (*this) ();
01759 it_ = m.find2 (1, i_, j_).it_;
01760 return *this;
01761 }
01762 BOOST_UBLAS_INLINE
01763 difference_type operator - (const const_iterator2 &it) const {
01764 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01765 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01766 return index2 () - it.index2 ();
01767 }
01768
01769
01770 BOOST_UBLAS_INLINE
01771 const_reference operator * () const {
01772 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01773 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01774 return *it_;
01775 }
01776 BOOST_UBLAS_INLINE
01777 const_reference operator [] (difference_type n) const {
01778 return *(*this + n);
01779 }
01780
01781 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01782 BOOST_UBLAS_INLINE
01783 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01784 typename self_type::
01785 #endif
01786 const_iterator1 begin () const {
01787 const self_type &m = (*this) ();
01788 return m.find1 (1, 0, index2 ());
01789 }
01790 BOOST_UBLAS_INLINE
01791 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01792 typename self_type::
01793 #endif
01794 const_iterator1 end () const {
01795 const self_type &m = (*this) ();
01796 return m.find1 (1, m.size1 (), index2 ());
01797 }
01798 BOOST_UBLAS_INLINE
01799 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01800 typename self_type::
01801 #endif
01802 const_reverse_iterator1 rbegin () const {
01803 return const_reverse_iterator1 (end ());
01804 }
01805 BOOST_UBLAS_INLINE
01806 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01807 typename self_type::
01808 #endif
01809 const_reverse_iterator1 rend () const {
01810 return const_reverse_iterator1 (begin ());
01811 }
01812 #endif
01813
01814
01815 BOOST_UBLAS_INLINE
01816 size_type index1 () const {
01817 return i_;
01818 }
01819 BOOST_UBLAS_INLINE
01820 size_type index2 () const {
01821 return j_;
01822 }
01823
01824
01825 BOOST_UBLAS_INLINE
01826 const_iterator2 &operator = (const const_iterator2 &it) {
01827 container_const_reference<self_type>::assign (&it ());
01828 it_ = it.it_;
01829 return *this;
01830 }
01831
01832
01833 BOOST_UBLAS_INLINE
01834 bool operator == (const const_iterator2 &it) const {
01835 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01836 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01837 return it_ == it.it_;
01838 }
01839 BOOST_UBLAS_INLINE
01840 bool operator < (const const_iterator2 &it) const {
01841 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01842 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01843 return it_ < it.it_;
01844 }
01845
01846 private:
01847 size_type i_;
01848 size_type j_;
01849 const_subiterator_type it_;
01850
01851 friend class iterator2;
01852 };
01853 #endif
01854
01855 BOOST_UBLAS_INLINE
01856 const_iterator2 begin2 () const {
01857 return find2 (0, 0, 0);
01858 }
01859 BOOST_UBLAS_INLINE
01860 const_iterator2 end2 () const {
01861 return find2 (0, 0, size2_);
01862 }
01863
01864 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01865 class iterator2:
01866 public container_reference<vector_of_vector>,
01867 public random_access_iterator_base<dense_random_access_iterator_tag,
01868 iterator2, value_type> {
01869 public:
01870 typedef typename vector_of_vector::value_type value_type;
01871 typedef typename vector_of_vector::difference_type difference_type;
01872 typedef typename vector_of_vector::reference reference;
01873 typedef typename vector_of_vector::pointer pointer;
01874
01875 typedef iterator1 dual_iterator_type;
01876 typedef reverse_iterator1 dual_reverse_iterator_type;
01877
01878
01879 BOOST_UBLAS_INLINE
01880 iterator2 ():
01881 container_reference<self_type> (), i_ (), j_ (), it_ () {}
01882 BOOST_UBLAS_INLINE
01883 iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it):
01884 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
01885
01886
01887 BOOST_UBLAS_INLINE
01888 iterator2 &operator ++ () {
01889 ++ j_;
01890 self_type &m = (*this) ();
01891 if (layout_type::fast_j ())
01892 ++ it_;
01893 else
01894 it_ = m.find2 (1, i_, j_).it_;
01895 return *this;
01896 }
01897 BOOST_UBLAS_INLINE
01898 iterator2 &operator -- () {
01899 -- j_;
01900 self_type &m = (*this) ();
01901 if (layout_type::fast_j ())
01902 -- it_;
01903 else
01904 it_ = m.find2 (1, i_, j_).it_;
01905 return *this;
01906 }
01907 BOOST_UBLAS_INLINE
01908 iterator2 &operator += (difference_type n) {
01909 j_ += n;
01910 self_type &m = (*this) ();
01911 it_ = m.find2 (1, i_, j_).it_;
01912 return *this;
01913 }
01914 BOOST_UBLAS_INLINE
01915 iterator2 &operator -= (difference_type n) {
01916 j_ -= n;
01917 self_type &m = (*this) ();
01918 it_ = m.find2 (1, i_, j_).it_;
01919 return *this;
01920 }
01921 BOOST_UBLAS_INLINE
01922 difference_type operator - (const iterator2 &it) const {
01923 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01924 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01925 return index2 () - it.index2 ();
01926 }
01927
01928
01929 BOOST_UBLAS_INLINE
01930 reference operator * () const {
01931 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
01932 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
01933 return *it_;
01934 }
01935 BOOST_UBLAS_INLINE
01936 reference operator [] (difference_type n) const {
01937 return *(*this + n);
01938 }
01939
01940 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
01941 BOOST_UBLAS_INLINE
01942 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01943 typename self_type::
01944 #endif
01945 iterator1 begin () const {
01946 self_type &m = (*this) ();
01947 return m.find1 (1, 0, index2 ());
01948 }
01949 BOOST_UBLAS_INLINE
01950 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01951 typename self_type::
01952 #endif
01953 iterator1 end () const {
01954 self_type &m = (*this) ();
01955 return m.find1 (1, m.size1 (), index2 ());
01956 }
01957 BOOST_UBLAS_INLINE
01958 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01959 typename self_type::
01960 #endif
01961 reverse_iterator1 rbegin () const {
01962 return reverse_iterator1 (end ());
01963 }
01964 BOOST_UBLAS_INLINE
01965 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
01966 typename self_type::
01967 #endif
01968 reverse_iterator1 rend () const {
01969 return reverse_iterator1 (begin ());
01970 }
01971 #endif
01972
01973
01974 BOOST_UBLAS_INLINE
01975 size_type index1 () const {
01976 return i_;
01977 }
01978 BOOST_UBLAS_INLINE
01979 size_type index2 () const {
01980 return j_;
01981 }
01982
01983
01984 BOOST_UBLAS_INLINE
01985 iterator2 &operator = (const iterator2 &it) {
01986 container_reference<self_type>::assign (&it ());
01987 it_ = it.it_;
01988 return *this;
01989 }
01990
01991
01992 BOOST_UBLAS_INLINE
01993 bool operator == (const iterator2 &it) const {
01994 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
01995 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
01996 return it_ == it.it_;
01997 }
01998 BOOST_UBLAS_INLINE
01999 bool operator < (const iterator2 &it) const {
02000 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02001 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
02002 return it_ < it.it_;
02003 }
02004
02005 private:
02006 size_type i_;
02007 size_type j_;
02008 subiterator_type it_;
02009
02010 friend class const_iterator2;
02011 };
02012 #endif
02013
02014 BOOST_UBLAS_INLINE
02015 iterator2 begin2 () {
02016 return find2 (0, 0, 0);
02017 }
02018 BOOST_UBLAS_INLINE
02019 iterator2 end2 () {
02020 return find2 (0, 0, size2_);
02021 }
02022
02023
02024
02025 BOOST_UBLAS_INLINE
02026 const_reverse_iterator1 rbegin1 () const {
02027 return const_reverse_iterator1 (end1 ());
02028 }
02029 BOOST_UBLAS_INLINE
02030 const_reverse_iterator1 rend1 () const {
02031 return const_reverse_iterator1 (begin1 ());
02032 }
02033
02034 BOOST_UBLAS_INLINE
02035 reverse_iterator1 rbegin1 () {
02036 return reverse_iterator1 (end1 ());
02037 }
02038 BOOST_UBLAS_INLINE
02039 reverse_iterator1 rend1 () {
02040 return reverse_iterator1 (begin1 ());
02041 }
02042
02043 BOOST_UBLAS_INLINE
02044 const_reverse_iterator2 rbegin2 () const {
02045 return const_reverse_iterator2 (end2 ());
02046 }
02047 BOOST_UBLAS_INLINE
02048 const_reverse_iterator2 rend2 () const {
02049 return const_reverse_iterator2 (begin2 ());
02050 }
02051
02052 BOOST_UBLAS_INLINE
02053 reverse_iterator2 rbegin2 () {
02054 return reverse_iterator2 (end2 ());
02055 }
02056 BOOST_UBLAS_INLINE
02057 reverse_iterator2 rend2 () {
02058 return reverse_iterator2 (begin2 ());
02059 }
02060
02061
02062 template<class Archive>
02063 void serialize(Archive & ar, const unsigned int ){
02064
02065
02066
02067 serialization::collection_size_type s1 (size1_);
02068 serialization::collection_size_type s2 (size2_);
02069
02070
02071 ar & serialization::make_nvp("size1",s1)
02072 & serialization::make_nvp("size2",s2);
02073
02074
02075 if (Archive::is_loading::value) {
02076 size1_ = s1;
02077 size2_ = s2;
02078 }
02079 ar & serialization::make_nvp("data",data_);
02080 }
02081
02082 private:
02083 size_type size1_;
02084 size_type size2_;
02085 array_type data_;
02086 };
02087
02088
02097 template<class T, class ALLOC>
02098 class zero_matrix:
02099 public matrix_container<zero_matrix<T, ALLOC> > {
02100
02101 typedef const T *const_pointer;
02102 typedef zero_matrix<T, ALLOC> self_type;
02103 public:
02104 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
02105 using matrix_container<self_type>::operator ();
02106 #endif
02107 typedef typename ALLOC::size_type size_type;
02108 typedef typename ALLOC::difference_type difference_type;
02109 typedef T value_type;
02110 typedef const T &const_reference;
02111 typedef T &reference;
02112 typedef const matrix_reference<const self_type> const_closure_type;
02113 typedef matrix_reference<self_type> closure_type;
02114 typedef sparse_tag storage_category;
02115 typedef unknown_orientation_tag orientation_category;
02116
02117
02118 BOOST_UBLAS_INLINE
02119 zero_matrix ():
02120 matrix_container<self_type> (),
02121 size1_ (0), size2_ (0) {}
02122 BOOST_UBLAS_INLINE
02123 zero_matrix (size_type size):
02124 matrix_container<self_type> (),
02125 size1_ (size), size2_ (size) {}
02126 BOOST_UBLAS_INLINE
02127 zero_matrix (size_type size1, size_type size2):
02128 matrix_container<self_type> (),
02129 size1_ (size1), size2_ (size2) {}
02130 BOOST_UBLAS_INLINE
02131 zero_matrix (const zero_matrix &m):
02132 matrix_container<self_type> (),
02133 size1_ (m.size1_), size2_ (m.size2_) {}
02134
02135
02136 BOOST_UBLAS_INLINE
02137 size_type size1 () const {
02138 return size1_;
02139 }
02140 BOOST_UBLAS_INLINE
02141 size_type size2 () const {
02142 return size2_;
02143 }
02144
02145
02146 BOOST_UBLAS_INLINE
02147 void resize (size_type size, bool preserve = true) {
02148 size1_ = size;
02149 size2_ = size;
02150 }
02151 BOOST_UBLAS_INLINE
02152 void resize (size_type size1, size_type size2, bool = true) {
02153 size1_ = size1;
02154 size2_ = size2;
02155 }
02156
02157
02158 BOOST_UBLAS_INLINE
02159 const_reference operator () (size_type , size_type ) const {
02160 return zero_;
02161 }
02162
02163
02164 BOOST_UBLAS_INLINE
02165 zero_matrix &operator = (const zero_matrix &m) {
02166 size1_ = m.size1_;
02167 size2_ = m.size2_;
02168 return *this;
02169 }
02170 BOOST_UBLAS_INLINE
02171 zero_matrix &assign_temporary (zero_matrix &m) {
02172 swap (m);
02173 return *this;
02174 }
02175
02176
02177 BOOST_UBLAS_INLINE
02178 void swap (zero_matrix &m) {
02179 if (this != &m) {
02180 std::swap (size1_, m.size1_);
02181 std::swap (size2_, m.size2_);
02182 }
02183 }
02184 BOOST_UBLAS_INLINE
02185 friend void swap (zero_matrix &m1, zero_matrix &m2) {
02186 m1.swap (m2);
02187 }
02188
02189
02190 public:
02191 class const_iterator1;
02192 class const_iterator2;
02193 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
02194 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
02195
02196
02197 BOOST_UBLAS_INLINE
02198 const_iterator1 find1 (int , size_type , size_type ) const {
02199 return const_iterator1 (*this);
02200 }
02201 BOOST_UBLAS_INLINE
02202 const_iterator2 find2 (int , size_type , size_type ) const {
02203 return const_iterator2 (*this);
02204 }
02205
02206 class const_iterator1:
02207 public container_const_reference<zero_matrix>,
02208 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
02209 const_iterator1, value_type> {
02210 public:
02211 typedef typename zero_matrix::value_type value_type;
02212 typedef typename zero_matrix::difference_type difference_type;
02213 typedef typename zero_matrix::const_reference reference;
02214 typedef typename zero_matrix::const_pointer pointer;
02215
02216 typedef const_iterator2 dual_iterator_type;
02217 typedef const_reverse_iterator2 dual_reverse_iterator_type;
02218
02219
02220 BOOST_UBLAS_INLINE
02221 const_iterator1 ():
02222 container_const_reference<self_type> () {}
02223 BOOST_UBLAS_INLINE
02224 const_iterator1 (const self_type &m):
02225 container_const_reference<self_type> (m) {}
02226
02227
02228 BOOST_UBLAS_INLINE
02229 const_iterator1 &operator ++ () {
02230 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02231 return *this;
02232 }
02233 BOOST_UBLAS_INLINE
02234 const_iterator1 &operator -- () {
02235 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02236 return *this;
02237 }
02238
02239
02240 BOOST_UBLAS_INLINE
02241 const_reference operator * () const {
02242 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02243 return zero_;
02244 }
02245
02246 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02247 BOOST_UBLAS_INLINE
02248 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02249 typename self_type::
02250 #endif
02251 const_iterator2 begin () const {
02252 return const_iterator2 ((*this) ());
02253 }
02254 BOOST_UBLAS_INLINE
02255 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02256 typename self_type::
02257 #endif
02258 const_iterator2 end () const {
02259 return const_iterator2 ((*this) ());
02260 }
02261 BOOST_UBLAS_INLINE
02262 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02263 typename self_type::
02264 #endif
02265 const_reverse_iterator2 rbegin () const {
02266 return const_reverse_iterator2 (end ());
02267 }
02268 BOOST_UBLAS_INLINE
02269 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02270 typename self_type::
02271 #endif
02272 const_reverse_iterator2 rend () const {
02273 return const_reverse_iterator2 (begin ());
02274 }
02275 #endif
02276
02277
02278 BOOST_UBLAS_INLINE
02279 size_type index1 () const {
02280 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02281 return 0;
02282 }
02283 BOOST_UBLAS_INLINE
02284 size_type index2 () const {
02285 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02286 return 0;
02287 }
02288
02289
02290 BOOST_UBLAS_INLINE
02291 const_iterator1 &operator = (const const_iterator1 &it) {
02292 container_const_reference<self_type>::assign (&it ());
02293 return *this;
02294 }
02295
02296
02297 BOOST_UBLAS_INLINE
02298 bool operator == (const const_iterator1 &it) const {
02299 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02300 detail::ignore_unused_variable_warning(it);
02301 return true;
02302 }
02303 };
02304
02305 typedef const_iterator1 iterator1;
02306
02307 BOOST_UBLAS_INLINE
02308 const_iterator1 begin1 () const {
02309 return const_iterator1 (*this);
02310 }
02311 BOOST_UBLAS_INLINE
02312 const_iterator1 end1 () const {
02313 return const_iterator1 (*this);
02314 }
02315
02316 class const_iterator2:
02317 public container_const_reference<zero_matrix>,
02318 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
02319 const_iterator2, value_type> {
02320 public:
02321 typedef typename zero_matrix::value_type value_type;
02322 typedef typename zero_matrix::difference_type difference_type;
02323 typedef typename zero_matrix::const_reference reference;
02324 typedef typename zero_matrix::const_pointer pointer;
02325
02326 typedef const_iterator1 dual_iterator_type;
02327 typedef const_reverse_iterator1 dual_reverse_iterator_type;
02328
02329
02330 BOOST_UBLAS_INLINE
02331 const_iterator2 ():
02332 container_const_reference<self_type> () {}
02333 BOOST_UBLAS_INLINE
02334 const_iterator2 (const self_type &m):
02335 container_const_reference<self_type> (m) {}
02336
02337
02338 BOOST_UBLAS_INLINE
02339 const_iterator2 &operator ++ () {
02340 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02341 return *this;
02342 }
02343 BOOST_UBLAS_INLINE
02344 const_iterator2 &operator -- () {
02345 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02346 return *this;
02347 }
02348
02349
02350 BOOST_UBLAS_INLINE
02351 const_reference operator * () const {
02352 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02353 return zero_;
02354 }
02355
02356 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02357 BOOST_UBLAS_INLINE
02358 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02359 typename self_type::
02360 #endif
02361 const_iterator1 begin () const {
02362 return const_iterator1 ((*this) ());
02363 }
02364 BOOST_UBLAS_INLINE
02365 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02366 typename self_type::
02367 #endif
02368 const_iterator1 end () const {
02369 return const_iterator1 ((*this) ());
02370 }
02371 BOOST_UBLAS_INLINE
02372 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02373 typename self_type::
02374 #endif
02375 const_reverse_iterator1 rbegin () const {
02376 return const_reverse_iterator1 (end ());
02377 }
02378 BOOST_UBLAS_INLINE
02379 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02380 typename self_type::
02381 #endif
02382 const_reverse_iterator1 rend () const {
02383 return const_reverse_iterator1 (begin ());
02384 }
02385 #endif
02386
02387
02388 BOOST_UBLAS_INLINE
02389 size_type index1 () const {
02390 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02391 return 0;
02392 }
02393 BOOST_UBLAS_INLINE
02394 size_type index2 () const {
02395 BOOST_UBLAS_CHECK_FALSE (bad_index ());
02396 return 0;
02397 }
02398
02399
02400 BOOST_UBLAS_INLINE
02401 const_iterator2 &operator = (const const_iterator2 &it) {
02402 container_const_reference<self_type>::assign (&it ());
02403 return *this;
02404 }
02405
02406
02407 BOOST_UBLAS_INLINE
02408 bool operator == (const const_iterator2 &it) const {
02409 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02410 detail::ignore_unused_variable_warning(it);
02411 return true;
02412 }
02413 };
02414
02415 typedef const_iterator2 iterator2;
02416
02417 BOOST_UBLAS_INLINE
02418 const_iterator2 begin2 () const {
02419 return find2 (0, 0, 0);
02420 }
02421 BOOST_UBLAS_INLINE
02422 const_iterator2 end2 () const {
02423 return find2 (0, 0, size2_);
02424 }
02425
02426
02427
02428 BOOST_UBLAS_INLINE
02429 const_reverse_iterator1 rbegin1 () const {
02430 return const_reverse_iterator1 (end1 ());
02431 }
02432 BOOST_UBLAS_INLINE
02433 const_reverse_iterator1 rend1 () const {
02434 return const_reverse_iterator1 (begin1 ());
02435 }
02436
02437 BOOST_UBLAS_INLINE
02438 const_reverse_iterator2 rbegin2 () const {
02439 return const_reverse_iterator2 (end2 ());
02440 }
02441 BOOST_UBLAS_INLINE
02442 const_reverse_iterator2 rend2 () const {
02443 return const_reverse_iterator2 (begin2 ());
02444 }
02445
02446
02447 template<class Archive>
02448 void serialize(Archive & ar, const unsigned int ){
02449
02450
02451
02452 serialization::collection_size_type s1 (size1_);
02453 serialization::collection_size_type s2 (size2_);
02454
02455
02456 ar & serialization::make_nvp("size1",s1)
02457 & serialization::make_nvp("size2",s2);
02458
02459
02460 if (Archive::is_loading::value) {
02461 size1_ = s1;
02462 size2_ = s2;
02463 }
02464 }
02465
02466 private:
02467 size_type size1_;
02468 size_type size2_;
02469 static const value_type zero_;
02470 };
02471
02472 template<class T, class ALLOC>
02473 const typename zero_matrix<T, ALLOC>::value_type zero_matrix<T, ALLOC>::zero_ = T();
02474
02484 template<class T, class ALLOC>
02485 class identity_matrix:
02486 public matrix_container<identity_matrix<T, ALLOC> > {
02487
02488 typedef const T *const_pointer;
02489 typedef identity_matrix<T, ALLOC> self_type;
02490 public:
02491 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
02492 using matrix_container<self_type>::operator ();
02493 #endif
02494 typedef typename ALLOC::size_type size_type;
02495 typedef typename ALLOC::difference_type difference_type;
02496 typedef T value_type;
02497 typedef const T &const_reference;
02498 typedef T &reference;
02499 typedef const matrix_reference<const self_type> const_closure_type;
02500 typedef matrix_reference<self_type> closure_type;
02501 typedef sparse_tag storage_category;
02502 typedef unknown_orientation_tag orientation_category;
02503
02504
02505 BOOST_UBLAS_INLINE
02506 identity_matrix ():
02507 matrix_container<self_type> (),
02508 size1_ (0), size2_ (0), size_common_ (0) {}
02509 BOOST_UBLAS_INLINE
02510 identity_matrix (size_type size):
02511 matrix_container<self_type> (),
02512 size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {}
02513 BOOST_UBLAS_INLINE
02514 identity_matrix (size_type size1, size_type size2):
02515 matrix_container<self_type> (),
02516 size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {}
02517 BOOST_UBLAS_INLINE
02518 identity_matrix (const identity_matrix &m):
02519 matrix_container<self_type> (),
02520 size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {}
02521
02522
02523 BOOST_UBLAS_INLINE
02524 size_type size1 () const {
02525 return size1_;
02526 }
02527 BOOST_UBLAS_INLINE
02528 size_type size2 () const {
02529 return size2_;
02530 }
02531
02532
02533 BOOST_UBLAS_INLINE
02534 void resize (size_type size, bool preserve = true) {
02535 size1_ = size;
02536 size2_ = size;
02537 size_common_ = ((std::min)(size1_, size2_));
02538 }
02539 BOOST_UBLAS_INLINE
02540 void resize (size_type size1, size_type size2, bool = true) {
02541 size1_ = size1;
02542 size2_ = size2;
02543 size_common_ = ((std::min)(size1_, size2_));
02544 }
02545
02546
02547 BOOST_UBLAS_INLINE
02548 const_reference operator () (size_type i, size_type j) const {
02549 if (i == j)
02550 return one_;
02551 else
02552 return zero_;
02553 }
02554
02555
02556 BOOST_UBLAS_INLINE
02557 identity_matrix &operator = (const identity_matrix &m) {
02558 size1_ = m.size1_;
02559 size2_ = m.size2_;
02560 size_common_ = m.size_common_;
02561 return *this;
02562 }
02563 BOOST_UBLAS_INLINE
02564 identity_matrix &assign_temporary (identity_matrix &m) {
02565 swap (m);
02566 return *this;
02567 }
02568
02569
02570 BOOST_UBLAS_INLINE
02571 void swap (identity_matrix &m) {
02572 if (this != &m) {
02573 std::swap (size1_, m.size1_);
02574 std::swap (size2_, m.size2_);
02575 std::swap (size_common_, m.size_common_);
02576 }
02577 }
02578 BOOST_UBLAS_INLINE
02579 friend void swap (identity_matrix &m1, identity_matrix &m2) {
02580 m1.swap (m2);
02581 }
02582
02583
02584 private:
02585
02586 typedef size_type const_subiterator_type;
02587
02588 public:
02589 class const_iterator1;
02590 class const_iterator2;
02591 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
02592 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
02593
02594
02595 BOOST_UBLAS_INLINE
02596 const_iterator1 find1 (int rank, size_type i, size_type j) const {
02597 if (rank == 1) {
02598 i = (std::max) (i, j);
02599 i = (std::min) (i, j + 1);
02600 }
02601 return const_iterator1 (*this, i);
02602 }
02603 BOOST_UBLAS_INLINE
02604 const_iterator2 find2 (int rank, size_type i, size_type j) const {
02605 if (rank == 1) {
02606 j = (std::max) (j, i);
02607 j = (std::min) (j, i + 1);
02608 }
02609 return const_iterator2 (*this, j);
02610 }
02611
02612
02613 class const_iterator1:
02614 public container_const_reference<identity_matrix>,
02615 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
02616 const_iterator1, value_type> {
02617 public:
02618 typedef typename identity_matrix::value_type value_type;
02619 typedef typename identity_matrix::difference_type difference_type;
02620 typedef typename identity_matrix::const_reference reference;
02621 typedef typename identity_matrix::const_pointer pointer;
02622
02623 typedef const_iterator2 dual_iterator_type;
02624 typedef const_reverse_iterator2 dual_reverse_iterator_type;
02625
02626
02627 BOOST_UBLAS_INLINE
02628 const_iterator1 ():
02629 container_const_reference<self_type> (), it_ () {}
02630 BOOST_UBLAS_INLINE
02631 const_iterator1 (const self_type &m, const const_subiterator_type &it):
02632 container_const_reference<self_type> (m), it_ (it) {}
02633
02634
02635 BOOST_UBLAS_INLINE
02636 const_iterator1 &operator ++ () {
02637 BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ());
02638 ++it_;
02639 return *this;
02640 }
02641 BOOST_UBLAS_INLINE
02642 const_iterator1 &operator -- () {
02643 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
02644 --it_;
02645 return *this;
02646 }
02647
02648
02649 BOOST_UBLAS_INLINE
02650 const_reference operator * () const {
02651 return one_;
02652 }
02653
02654 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02655 BOOST_UBLAS_INLINE
02656 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02657 typename self_type::
02658 #endif
02659 const_iterator2 begin () const {
02660 return const_iterator2 ((*this) (), it_);
02661 }
02662 BOOST_UBLAS_INLINE
02663 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02664 typename self_type::
02665 #endif
02666 const_iterator2 end () const {
02667 return const_iterator2 ((*this) (), it_ + 1);
02668 }
02669 BOOST_UBLAS_INLINE
02670 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02671 typename self_type::
02672 #endif
02673 const_reverse_iterator2 rbegin () const {
02674 return const_reverse_iterator2 (end ());
02675 }
02676 BOOST_UBLAS_INLINE
02677 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02678 typename self_type::
02679 #endif
02680 const_reverse_iterator2 rend () const {
02681 return const_reverse_iterator2 (begin ());
02682 }
02683 #endif
02684
02685
02686 BOOST_UBLAS_INLINE
02687 size_type index1 () const {
02688 return it_;
02689 }
02690 BOOST_UBLAS_INLINE
02691 size_type index2 () const {
02692 return it_;
02693 }
02694
02695
02696 BOOST_UBLAS_INLINE
02697 const_iterator1 &operator = (const const_iterator1 &it) {
02698 container_const_reference<self_type>::assign (&it ());
02699 it_ = it.it_;
02700 return *this;
02701 }
02702
02703
02704 BOOST_UBLAS_INLINE
02705 bool operator == (const const_iterator1 &it) const {
02706 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02707 return it_ == it.it_;
02708 }
02709
02710 private:
02711 const_subiterator_type it_;
02712 };
02713
02714 typedef const_iterator1 iterator1;
02715
02716 BOOST_UBLAS_INLINE
02717 const_iterator1 begin1 () const {
02718 return const_iterator1 (*this, 0);
02719 }
02720 BOOST_UBLAS_INLINE
02721 const_iterator1 end1 () const {
02722 return const_iterator1 (*this, size_common_);
02723 }
02724
02725 class const_iterator2:
02726 public container_const_reference<identity_matrix>,
02727 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
02728 const_iterator2, value_type> {
02729 public:
02730 typedef typename identity_matrix::value_type value_type;
02731 typedef typename identity_matrix::difference_type difference_type;
02732 typedef typename identity_matrix::const_reference reference;
02733 typedef typename identity_matrix::const_pointer pointer;
02734
02735 typedef const_iterator1 dual_iterator_type;
02736 typedef const_reverse_iterator1 dual_reverse_iterator_type;
02737
02738
02739 BOOST_UBLAS_INLINE
02740 const_iterator2 ():
02741 container_const_reference<self_type> (), it_ () {}
02742 BOOST_UBLAS_INLINE
02743 const_iterator2 (const self_type &m, const const_subiterator_type &it):
02744 container_const_reference<self_type> (m), it_ (it) {}
02745
02746
02747 BOOST_UBLAS_INLINE
02748 const_iterator2 &operator ++ () {
02749 BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ());
02750 ++it_;
02751 return *this;
02752 }
02753 BOOST_UBLAS_INLINE
02754 const_iterator2 &operator -- () {
02755 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
02756 --it_;
02757 return *this;
02758 }
02759
02760
02761 BOOST_UBLAS_INLINE
02762 const_reference operator * () const {
02763 return one_;
02764 }
02765
02766 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
02767 BOOST_UBLAS_INLINE
02768 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02769 typename self_type::
02770 #endif
02771 const_iterator1 begin () const {
02772 return const_iterator1 ((*this) (), it_);
02773 }
02774 BOOST_UBLAS_INLINE
02775 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02776 typename self_type::
02777 #endif
02778 const_iterator1 end () const {
02779 return const_iterator1 ((*this) (), it_ + 1);
02780 }
02781 BOOST_UBLAS_INLINE
02782 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02783 typename self_type::
02784 #endif
02785 const_reverse_iterator1 rbegin () const {
02786 return const_reverse_iterator1 (end ());
02787 }
02788 BOOST_UBLAS_INLINE
02789 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
02790 typename self_type::
02791 #endif
02792 const_reverse_iterator1 rend () const {
02793 return const_reverse_iterator1 (begin ());
02794 }
02795 #endif
02796
02797
02798 BOOST_UBLAS_INLINE
02799 size_type index1 () const {
02800 return it_;
02801 }
02802 BOOST_UBLAS_INLINE
02803 size_type index2 () const {
02804 return it_;
02805 }
02806
02807
02808 BOOST_UBLAS_INLINE
02809 const_iterator2 &operator = (const const_iterator2 &it) {
02810 container_const_reference<self_type>::assign (&it ());
02811 it_ = it.it_;
02812 return *this;
02813 }
02814
02815
02816 BOOST_UBLAS_INLINE
02817 bool operator == (const const_iterator2 &it) const {
02818 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
02819 return it_ == it.it_;
02820 }
02821
02822 private:
02823 const_subiterator_type it_;
02824 };
02825
02826 typedef const_iterator2 iterator2;
02827
02828 BOOST_UBLAS_INLINE
02829 const_iterator2 begin2 () const {
02830 return const_iterator2 (*this, 0);
02831 }
02832 BOOST_UBLAS_INLINE
02833 const_iterator2 end2 () const {
02834 return const_iterator2 (*this, size_common_);
02835 }
02836
02837
02838
02839 BOOST_UBLAS_INLINE
02840 const_reverse_iterator1 rbegin1 () const {
02841 return const_reverse_iterator1 (end1 ());
02842 }
02843 BOOST_UBLAS_INLINE
02844 const_reverse_iterator1 rend1 () const {
02845 return const_reverse_iterator1 (begin1 ());
02846 }
02847
02848 BOOST_UBLAS_INLINE
02849 const_reverse_iterator2 rbegin2 () const {
02850 return const_reverse_iterator2 (end2 ());
02851 }
02852 BOOST_UBLAS_INLINE
02853 const_reverse_iterator2 rend2 () const {
02854 return const_reverse_iterator2 (begin2 ());
02855 }
02856
02857
02858 template<class Archive>
02859 void serialize(Archive & ar, const unsigned int ){
02860
02861
02862
02863 serialization::collection_size_type s1 (size1_);
02864 serialization::collection_size_type s2 (size2_);
02865
02866
02867 ar & serialization::make_nvp("size1",s1)
02868 & serialization::make_nvp("size2",s2);
02869
02870
02871 if (Archive::is_loading::value) {
02872 size1_ = s1;
02873 size2_ = s2;
02874 size_common_ = ((std::min)(size1_, size2_));
02875 }
02876 }
02877
02878 private:
02879 size_type size1_;
02880 size_type size2_;
02881 size_type size_common_;
02882 static const value_type zero_;
02883 static const value_type one_;
02884 };
02885
02886 template<class T, class ALLOC>
02887 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::zero_ = T();
02888 template<class T, class ALLOC>
02889 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::one_ (1);
02890
02891
02900 template<class T, class ALLOC>
02901 class scalar_matrix:
02902 public matrix_container<scalar_matrix<T, ALLOC> > {
02903
02904 typedef const T *const_pointer;
02905 typedef scalar_matrix<T, ALLOC> self_type;
02906 public:
02907 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
02908 using matrix_container<self_type>::operator ();
02909 #endif
02910 typedef std::size_t size_type;
02911 typedef std::ptrdiff_t difference_type;
02912 typedef T value_type;
02913 typedef const T &const_reference;
02914 typedef T &reference;
02915 typedef const matrix_reference<const self_type> const_closure_type;
02916 typedef matrix_reference<self_type> closure_type;
02917 typedef dense_tag storage_category;
02918 typedef unknown_orientation_tag orientation_category;
02919
02920
02921 BOOST_UBLAS_INLINE
02922 scalar_matrix ():
02923 matrix_container<self_type> (),
02924 size1_ (0), size2_ (0), value_ () {}
02925 BOOST_UBLAS_INLINE
02926 scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)):
02927 matrix_container<self_type> (),
02928 size1_ (size1), size2_ (size2), value_ (value) {}
02929 BOOST_UBLAS_INLINE
02930 scalar_matrix (const scalar_matrix &m):
02931 matrix_container<self_type> (),
02932 size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {}
02933
02934
02935 BOOST_UBLAS_INLINE
02936 size_type size1 () const {
02937 return size1_;
02938 }
02939 BOOST_UBLAS_INLINE
02940 size_type size2 () const {
02941 return size2_;
02942 }
02943
02944
02945 BOOST_UBLAS_INLINE
02946 void resize (size_type size1, size_type size2, bool = true) {
02947 size1_ = size1;
02948 size2_ = size2;
02949 }
02950
02951
02952 BOOST_UBLAS_INLINE
02953 const_reference operator () (size_type , size_type ) const {
02954 return value_;
02955 }
02956
02957
02958 BOOST_UBLAS_INLINE
02959 scalar_matrix &operator = (const scalar_matrix &m) {
02960 size1_ = m.size1_;
02961 size2_ = m.size2_;
02962 value_ = m.value_;
02963 return *this;
02964 }
02965 BOOST_UBLAS_INLINE
02966 scalar_matrix &assign_temporary (scalar_matrix &m) {
02967 swap (m);
02968 return *this;
02969 }
02970
02971
02972 BOOST_UBLAS_INLINE
02973 void swap (scalar_matrix &m) {
02974 if (this != &m) {
02975 std::swap (size1_, m.size1_);
02976 std::swap (size2_, m.size2_);
02977 std::swap (value_, m.value_);
02978 }
02979 }
02980 BOOST_UBLAS_INLINE
02981 friend void swap (scalar_matrix &m1, scalar_matrix &m2) {
02982 m1.swap (m2);
02983 }
02984
02985
02986 private:
02987
02988 typedef size_type const_subiterator_type;
02989
02990 public:
02991 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
02992 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
02993 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
02994 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
02995 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
02996 #else
02997 class const_iterator1;
02998 class const_iterator2;
02999 #endif
03000 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
03001 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
03002
03003
03004 BOOST_UBLAS_INLINE
03005 const_iterator1 find1 (int , size_type i, size_type j) const {
03006 return const_iterator1 (*this, i, j);
03007 }
03008 BOOST_UBLAS_INLINE
03009 const_iterator2 find2 (int , size_type i, size_type j) const {
03010 return const_iterator2 (*this, i, j);
03011 }
03012
03013
03014 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03015 class const_iterator1:
03016 public container_const_reference<scalar_matrix>,
03017 public random_access_iterator_base<dense_random_access_iterator_tag,
03018 const_iterator1, value_type> {
03019 public:
03020 typedef typename scalar_matrix::value_type value_type;
03021 typedef typename scalar_matrix::difference_type difference_type;
03022 typedef typename scalar_matrix::const_reference reference;
03023 typedef typename scalar_matrix::const_pointer pointer;
03024
03025 typedef const_iterator2 dual_iterator_type;
03026 typedef const_reverse_iterator2 dual_reverse_iterator_type;
03027
03028
03029 BOOST_UBLAS_INLINE
03030 const_iterator1 ():
03031 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
03032 BOOST_UBLAS_INLINE
03033 const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
03034 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
03035
03036
03037 BOOST_UBLAS_INLINE
03038 const_iterator1 &operator ++ () {
03039 ++ it1_;
03040 return *this;
03041 }
03042 BOOST_UBLAS_INLINE
03043 const_iterator1 &operator -- () {
03044 -- it1_;
03045 return *this;
03046 }
03047 BOOST_UBLAS_INLINE
03048 const_iterator1 &operator += (difference_type n) {
03049 it1_ += n;
03050 return *this;
03051 }
03052 BOOST_UBLAS_INLINE
03053 const_iterator1 &operator -= (difference_type n) {
03054 it1_ -= n;
03055 return *this;
03056 }
03057 BOOST_UBLAS_INLINE
03058 difference_type operator - (const const_iterator1 &it) const {
03059 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03060 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
03061 return it1_ - it.it1_;
03062 }
03063
03064
03065 BOOST_UBLAS_INLINE
03066 const_reference operator * () const {
03067 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03068 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03069 return (*this) () (index1 (), index2 ());
03070 }
03071 BOOST_UBLAS_INLINE
03072 const_reference operator [] (difference_type n) const {
03073 return *(*this + n);
03074 }
03075
03076 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03077 BOOST_UBLAS_INLINE
03078 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03079 typename self_type::
03080 #endif
03081 const_iterator2 begin () const {
03082 const scalar_matrix &m = (*this) ();
03083 return m.find2 (1, index1 (), 0);
03084 }
03085 BOOST_UBLAS_INLINE
03086 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03087 typename self_type::
03088 #endif
03089 const_iterator2 end () const {
03090 const scalar_matrix &m = (*this) ();
03091 return m.find2 (1, index1 (), m.size2 ());
03092 }
03093 BOOST_UBLAS_INLINE
03094 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03095 typename self_type::
03096 #endif
03097 const_reverse_iterator2 rbegin () const {
03098 return const_reverse_iterator2 (end ());
03099 }
03100 BOOST_UBLAS_INLINE
03101 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03102 typename self_type::
03103 #endif
03104 const_reverse_iterator2 rend () const {
03105 return const_reverse_iterator2 (begin ());
03106 }
03107 #endif
03108
03109
03110 BOOST_UBLAS_INLINE
03111 size_type index1 () const {
03112 return it1_;
03113 }
03114 BOOST_UBLAS_INLINE
03115 size_type index2 () const {
03116 return it2_;
03117 }
03118
03119
03120 BOOST_UBLAS_INLINE
03121 const_iterator1 &operator = (const const_iterator1 &it) {
03122 container_const_reference<scalar_matrix>::assign (&it ());
03123 it1_ = it.it1_;
03124 it2_ = it.it2_;
03125 return *this;
03126 }
03127
03128
03129 BOOST_UBLAS_INLINE
03130 bool operator == (const const_iterator1 &it) const {
03131 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03132 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
03133 return it1_ == it.it1_;
03134 }
03135 BOOST_UBLAS_INLINE
03136 bool operator < (const const_iterator1 &it) const {
03137 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03138 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
03139 return it1_ < it.it1_;
03140 }
03141
03142 private:
03143 const_subiterator_type it1_;
03144 const_subiterator_type it2_;
03145 };
03146
03147 typedef const_iterator1 iterator1;
03148 #endif
03149
03150 BOOST_UBLAS_INLINE
03151 const_iterator1 begin1 () const {
03152 return find1 (0, 0, 0);
03153 }
03154 BOOST_UBLAS_INLINE
03155 const_iterator1 end1 () const {
03156 return find1 (0, size1_, 0);
03157 }
03158
03159 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03160 class const_iterator2:
03161 public container_const_reference<scalar_matrix>,
03162 public random_access_iterator_base<dense_random_access_iterator_tag,
03163 const_iterator2, value_type> {
03164 public:
03165 typedef typename scalar_matrix::value_type value_type;
03166 typedef typename scalar_matrix::difference_type difference_type;
03167 typedef typename scalar_matrix::const_reference reference;
03168 typedef typename scalar_matrix::const_pointer pointer;
03169
03170 typedef const_iterator1 dual_iterator_type;
03171 typedef const_reverse_iterator1 dual_reverse_iterator_type;
03172
03173
03174 BOOST_UBLAS_INLINE
03175 const_iterator2 ():
03176 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
03177 BOOST_UBLAS_INLINE
03178 const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
03179 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
03180
03181
03182 BOOST_UBLAS_INLINE
03183 const_iterator2 &operator ++ () {
03184 ++ it2_;
03185 return *this;
03186 }
03187 BOOST_UBLAS_INLINE
03188 const_iterator2 &operator -- () {
03189 -- it2_;
03190 return *this;
03191 }
03192 BOOST_UBLAS_INLINE
03193 const_iterator2 &operator += (difference_type n) {
03194 it2_ += n;
03195 return *this;
03196 }
03197 BOOST_UBLAS_INLINE
03198 const_iterator2 &operator -= (difference_type n) {
03199 it2_ -= n;
03200 return *this;
03201 }
03202 BOOST_UBLAS_INLINE
03203 difference_type operator - (const const_iterator2 &it) const {
03204 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03205 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
03206 return it2_ - it.it2_;
03207 }
03208
03209
03210 BOOST_UBLAS_INLINE
03211 const_reference operator * () const {
03212 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03213 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03214 return (*this) () (index1 (), index2 ());
03215 }
03216 BOOST_UBLAS_INLINE
03217 const_reference operator [] (difference_type n) const {
03218 return *(*this + n);
03219 }
03220
03221 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03222 BOOST_UBLAS_INLINE
03223 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03224 typename self_type::
03225 #endif
03226 const_iterator1 begin () const {
03227 const scalar_matrix &m = (*this) ();
03228 return m.find1 (1, 0, index2 ());
03229 }
03230 BOOST_UBLAS_INLINE
03231 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03232 typename self_type::
03233 #endif
03234 const_iterator1 end () const {
03235 const scalar_matrix &m = (*this) ();
03236 return m.find1 (1, m.size1 (), index2 ());
03237 }
03238 BOOST_UBLAS_INLINE
03239 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03240 typename self_type::
03241 #endif
03242 const_reverse_iterator1 rbegin () const {
03243 return const_reverse_iterator1 (end ());
03244 }
03245 BOOST_UBLAS_INLINE
03246 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03247 typename self_type::
03248 #endif
03249 const_reverse_iterator1 rend () const {
03250 return const_reverse_iterator1 (begin ());
03251 }
03252 #endif
03253
03254
03255 BOOST_UBLAS_INLINE
03256 size_type index1 () const {
03257 return it1_;
03258 }
03259 BOOST_UBLAS_INLINE
03260 size_type index2 () const {
03261 return it2_;
03262 }
03263
03264
03265 BOOST_UBLAS_INLINE
03266 const_iterator2 &operator = (const const_iterator2 &it) {
03267 container_const_reference<scalar_matrix>::assign (&it ());
03268 it1_ = it.it1_;
03269 it2_ = it.it2_;
03270 return *this;
03271 }
03272
03273
03274 BOOST_UBLAS_INLINE
03275 bool operator == (const const_iterator2 &it) const {
03276 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03277 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
03278 return it2_ == it.it2_;
03279 }
03280 BOOST_UBLAS_INLINE
03281 bool operator < (const const_iterator2 &it) const {
03282 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03283 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
03284 return it2_ < it.it2_;
03285 }
03286
03287 private:
03288 const_subiterator_type it1_;
03289 const_subiterator_type it2_;
03290 };
03291
03292 typedef const_iterator2 iterator2;
03293 #endif
03294
03295 BOOST_UBLAS_INLINE
03296 const_iterator2 begin2 () const {
03297 return find2 (0, 0, 0);
03298 }
03299 BOOST_UBLAS_INLINE
03300 const_iterator2 end2 () const {
03301 return find2 (0, 0, size2_);
03302 }
03303
03304
03305
03306 BOOST_UBLAS_INLINE
03307 const_reverse_iterator1 rbegin1 () const {
03308 return const_reverse_iterator1 (end1 ());
03309 }
03310 BOOST_UBLAS_INLINE
03311 const_reverse_iterator1 rend1 () const {
03312 return const_reverse_iterator1 (begin1 ());
03313 }
03314
03315 BOOST_UBLAS_INLINE
03316 const_reverse_iterator2 rbegin2 () const {
03317 return const_reverse_iterator2 (end2 ());
03318 }
03319 BOOST_UBLAS_INLINE
03320 const_reverse_iterator2 rend2 () const {
03321 return const_reverse_iterator2 (begin2 ());
03322 }
03323
03324
03325 template<class Archive>
03326 void serialize(Archive & ar, const unsigned int ){
03327
03328
03329
03330 serialization::collection_size_type s1 (size1_);
03331 serialization::collection_size_type s2 (size2_);
03332
03333
03334 ar & serialization::make_nvp("size1",s1)
03335 & serialization::make_nvp("size2",s2);
03336
03337
03338 if (Archive::is_loading::value) {
03339 size1_ = s1;
03340 size2_ = s2;
03341 }
03342
03343 ar & serialization::make_nvp("value", value_);
03344 }
03345
03346 private:
03347 size_type size1_;
03348 size_type size2_;
03349 value_type value_;
03350 };
03351
03352
03370 template<class T, std::size_t N, std::size_t M>
03371 class c_matrix:
03372 public matrix_container<c_matrix<T, N, M> > {
03373
03374 typedef c_matrix<T, N, M> self_type;
03375 public:
03376 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
03377 using matrix_container<self_type>::operator ();
03378 #endif
03379 typedef std::size_t size_type;
03380 typedef std::ptrdiff_t difference_type;
03381 typedef T value_type;
03382 typedef const T &const_reference;
03383 typedef T &reference;
03384 typedef const T *const_pointer;
03385 typedef T *pointer;
03386 typedef const matrix_reference<const self_type> const_closure_type;
03387 typedef matrix_reference<self_type> closure_type;
03388 typedef c_vector<T, N * M> vector_temporary_type;
03389 typedef self_type matrix_temporary_type;
03390 typedef dense_tag storage_category;
03391
03392
03393
03394 typedef row_major_tag orientation_category;
03395
03396
03397 BOOST_UBLAS_INLINE
03398 c_matrix ():
03399 size1_ (N), size2_ (M) {
03400 }
03401 BOOST_UBLAS_INLINE
03402 c_matrix (size_type size1, size_type size2):
03403 size1_ (size1), size2_ (size2) {
03404 if (size1_ > N || size2_ > M)
03405 bad_size ().raise ();
03406 }
03407 BOOST_UBLAS_INLINE
03408 c_matrix (const c_matrix &m):
03409 size1_ (m.size1_), size2_ (m.size2_) {
03410 if (size1_ > N || size2_ > M)
03411 bad_size ().raise ();
03412 assign(m);
03413 }
03414 template<class AE>
03415 BOOST_UBLAS_INLINE
03416 c_matrix (const matrix_expression<AE> &ae):
03417 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) {
03418 if (size1_ > N || size2_ > M)
03419 bad_size ().raise ();
03420 matrix_assign<scalar_assign> (*this, ae);
03421 }
03422
03423
03424 BOOST_UBLAS_INLINE
03425 size_type size1 () const {
03426 return size1_;
03427 }
03428 BOOST_UBLAS_INLINE
03429 size_type size2 () const {
03430 return size2_;
03431 }
03432 BOOST_UBLAS_INLINE
03433 const_pointer data () const {
03434 return reinterpret_cast<const_pointer> (data_);
03435 }
03436 BOOST_UBLAS_INLINE
03437 pointer data () {
03438 return reinterpret_cast<pointer> (data_);
03439 }
03440
03441
03442 BOOST_UBLAS_INLINE
03443 void resize (size_type size1, size_type size2, bool preserve = true) {
03444 if (size1 > N || size2 > M)
03445 bad_size ().raise ();
03446 if (preserve) {
03447 self_type temporary (size1, size2);
03448
03449 const size_type size1_min = (std::min) (size1, size1_);
03450 const size_type size2_min = (std::min) (size2, size2_);
03451 for (size_type i = 0; i != size1_min; ++i) {
03452 for (size_type j = 0; j != size2_min; ++j) {
03453 temporary.data_[i][j] = data_[i][j];
03454 }
03455 }
03456 assign_temporary (temporary);
03457 }
03458 else {
03459 size1_ = size1;
03460 size2_ = size2;
03461 }
03462 }
03463
03464
03465 BOOST_UBLAS_INLINE
03466 const_reference operator () (size_type i, size_type j) const {
03467 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
03468 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
03469 return data_ [i] [j];
03470 }
03471 BOOST_UBLAS_INLINE
03472 reference at_element (size_type i, size_type j) {
03473 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
03474 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
03475 return data_ [i] [j];
03476 }
03477 BOOST_UBLAS_INLINE
03478 reference operator () (size_type i, size_type j) {
03479 return at_element (i, j);
03480 }
03481
03482
03483 BOOST_UBLAS_INLINE
03484 reference insert_element (size_type i, size_type j, const_reference t) {
03485 return (at_element (i, j) = t);
03486 }
03487
03488
03489 BOOST_UBLAS_INLINE
03490 void clear () {
03491 for (size_type i = 0; i < size1_; ++ i)
03492 std::fill (data_ [i], data_ [i] + size2_, value_type());
03493 }
03494
03495
03496 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
03497
03499 BOOST_UBLAS_INLINE
03500 c_matrix &operator = (c_matrix m) {
03501 assign_temporary(m);
03502 return *this;
03503 }
03504 #else
03505 BOOST_UBLAS_INLINE
03506 c_matrix &operator = (const c_matrix &m) {
03507 size1_ = m.size1_;
03508 size2_ = m.size2_;
03509 for (size_type i = 0; i < m.size1_; ++ i)
03510 std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]);
03511 return *this;
03512 }
03513 #endif
03514 template<class C>
03515 BOOST_UBLAS_INLINE
03516 c_matrix &operator = (const matrix_container<C> &m) {
03517 resize (m ().size1 (), m ().size2 (), false);
03518 assign (m);
03519 return *this;
03520 }
03521 BOOST_UBLAS_INLINE
03522 c_matrix &assign_temporary (c_matrix &m) {
03523 swap (m);
03524 return *this;
03525 }
03526 template<class AE>
03527 BOOST_UBLAS_INLINE
03528 c_matrix &operator = (const matrix_expression<AE> &ae) {
03529 self_type temporary (ae);
03530 return assign_temporary (temporary);
03531 }
03532 template<class AE>
03533 BOOST_UBLAS_INLINE
03534 c_matrix &assign (const matrix_expression<AE> &ae) {
03535 matrix_assign<scalar_assign> (*this, ae);
03536 return *this;
03537 }
03538 template<class AE>
03539 BOOST_UBLAS_INLINE
03540 c_matrix& operator += (const matrix_expression<AE> &ae) {
03541 self_type temporary (*this + ae);
03542 return assign_temporary (temporary);
03543 }
03544 template<class C>
03545 BOOST_UBLAS_INLINE
03546 c_matrix &operator += (const matrix_container<C> &m) {
03547 plus_assign (m);
03548 return *this;
03549 }
03550 template<class AE>
03551 BOOST_UBLAS_INLINE
03552 c_matrix &plus_assign (const matrix_expression<AE> &ae) {
03553 matrix_assign<scalar_plus_assign> (*this, ae);
03554 return *this;
03555 }
03556 template<class AE>
03557 BOOST_UBLAS_INLINE
03558 c_matrix& operator -= (const matrix_expression<AE> &ae) {
03559 self_type temporary (*this - ae);
03560 return assign_temporary (temporary);
03561 }
03562 template<class C>
03563 BOOST_UBLAS_INLINE
03564 c_matrix &operator -= (const matrix_container<C> &m) {
03565 minus_assign (m);
03566 return *this;
03567 }
03568 template<class AE>
03569 BOOST_UBLAS_INLINE
03570 c_matrix &minus_assign (const matrix_expression<AE> &ae) {
03571 matrix_assign<scalar_minus_assign> (*this, ae);
03572 return *this;
03573 }
03574 template<class AT>
03575 BOOST_UBLAS_INLINE
03576 c_matrix& operator *= (const AT &at) {
03577 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
03578 return *this;
03579 }
03580 template<class AT>
03581 BOOST_UBLAS_INLINE
03582 c_matrix& operator /= (const AT &at) {
03583 matrix_assign_scalar<scalar_divides_assign> (*this, at);
03584 return *this;
03585 }
03586
03587
03588 BOOST_UBLAS_INLINE
03589 void swap (c_matrix &m) {
03590 if (this != &m) {
03591 BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ());
03592 BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ());
03593 std::swap (size1_, m.size1_);
03594 std::swap (size2_, m.size2_);
03595 for (size_type i = 0; i < size1_; ++ i)
03596 std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]);
03597 }
03598 }
03599 BOOST_UBLAS_INLINE
03600 friend void swap (c_matrix &m1, c_matrix &m2) {
03601 m1.swap (m2);
03602 }
03603
03604
03605 private:
03606
03607 typedef const_pointer const_subiterator_type;
03608 typedef pointer subiterator_type;
03609
03610 public:
03611 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03612 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
03613 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
03614 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
03615 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
03616 #else
03617 class const_iterator1;
03618 class iterator1;
03619 class const_iterator2;
03620 class iterator2;
03621 #endif
03622 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
03623 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
03624 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
03625 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
03626
03627
03628 BOOST_UBLAS_INLINE
03629 const_iterator1 find1 (int rank, size_type i, size_type j) const {
03630 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03631 return const_iterator1 (*this, i, j);
03632 #else
03633 return const_iterator1 (*this, &data_ [i] [j]);
03634 #endif
03635 }
03636 BOOST_UBLAS_INLINE
03637 iterator1 find1 (int rank, size_type i, size_type j) {
03638 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03639 return iterator1 (*this, i, j);
03640 #else
03641 return iterator1 (*this, &data_ [i] [j]);
03642 #endif
03643 }
03644 BOOST_UBLAS_INLINE
03645 const_iterator2 find2 (int rank, size_type i, size_type j) const {
03646 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03647 return const_iterator2 (*this, i, j);
03648 #else
03649 return const_iterator2 (*this, &data_ [i] [j]);
03650 #endif
03651 }
03652 BOOST_UBLAS_INLINE
03653 iterator2 find2 (int rank, size_type i, size_type j) {
03654 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
03655 return iterator2 (*this, i, j);
03656 #else
03657 return iterator2 (*this, &data_ [i] [j]);
03658 #endif
03659 }
03660
03661
03662 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03663 class const_iterator1:
03664 public container_const_reference<c_matrix>,
03665 public random_access_iterator_base<dense_random_access_iterator_tag,
03666 const_iterator1, value_type> {
03667 public:
03668 typedef typename c_matrix::difference_type difference_type;
03669 typedef typename c_matrix::value_type value_type;
03670 typedef typename c_matrix::const_reference reference;
03671 typedef typename c_matrix::const_pointer pointer;
03672
03673 typedef const_iterator2 dual_iterator_type;
03674 typedef const_reverse_iterator2 dual_reverse_iterator_type;
03675
03676
03677 BOOST_UBLAS_INLINE
03678 const_iterator1 ():
03679 container_const_reference<self_type> (), it_ () {}
03680 BOOST_UBLAS_INLINE
03681 const_iterator1 (const self_type &m, const const_subiterator_type &it):
03682 container_const_reference<self_type> (m), it_ (it) {}
03683 BOOST_UBLAS_INLINE
03684 const_iterator1 (const iterator1 &it):
03685 container_const_reference<self_type> (it ()), it_ (it.it_) {}
03686
03687
03688 BOOST_UBLAS_INLINE
03689 const_iterator1 &operator ++ () {
03690 it_ += M;
03691 return *this;
03692 }
03693 BOOST_UBLAS_INLINE
03694 const_iterator1 &operator -- () {
03695 it_ -= M;
03696 return *this;
03697 }
03698 BOOST_UBLAS_INLINE
03699 const_iterator1 &operator += (difference_type n) {
03700 it_ += n * M;
03701 return *this;
03702 }
03703 BOOST_UBLAS_INLINE
03704 const_iterator1 &operator -= (difference_type n) {
03705 it_ -= n * M;
03706 return *this;
03707 }
03708 BOOST_UBLAS_INLINE
03709 difference_type operator - (const const_iterator1 &it) const {
03710 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03711 return (it_ - it.it_) / M;
03712 }
03713
03714
03715 BOOST_UBLAS_INLINE
03716 const_reference operator * () const {
03717 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03718 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03719 return *it_;
03720 }
03721 BOOST_UBLAS_INLINE
03722 const_reference operator [] (difference_type n) const {
03723 return *(*this + n);
03724 }
03725
03726 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03727 BOOST_UBLAS_INLINE
03728 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03729 typename self_type::
03730 #endif
03731 const_iterator2 begin () const {
03732 const self_type &m = (*this) ();
03733 return m.find2 (1, index1 (), 0);
03734 }
03735 BOOST_UBLAS_INLINE
03736 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03737 typename self_type::
03738 #endif
03739 const_iterator2 end () const {
03740 const self_type &m = (*this) ();
03741 return m.find2 (1, index1 (), m.size2 ());
03742 }
03743 BOOST_UBLAS_INLINE
03744 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03745 typename self_type::
03746 #endif
03747 const_reverse_iterator2 rbegin () const {
03748 return const_reverse_iterator2 (end ());
03749 }
03750 BOOST_UBLAS_INLINE
03751 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03752 typename self_type::
03753 #endif
03754 const_reverse_iterator2 rend () const {
03755 return const_reverse_iterator2 (begin ());
03756 }
03757 #endif
03758
03759
03760 BOOST_UBLAS_INLINE
03761 size_type index1 () const {
03762 const self_type &m = (*this) ();
03763 return (it_ - m.begin1 ().it_) / M;
03764 }
03765 BOOST_UBLAS_INLINE
03766 size_type index2 () const {
03767 const self_type &m = (*this) ();
03768 return (it_ - m.begin1 ().it_) % M;
03769 }
03770
03771
03772 BOOST_UBLAS_INLINE
03773 const_iterator1 &operator = (const const_iterator1 &it) {
03774 container_const_reference<self_type>::assign (&it ());
03775 it_ = it.it_;
03776 return *this;
03777 }
03778
03779
03780 BOOST_UBLAS_INLINE
03781 bool operator == (const const_iterator1 &it) const {
03782 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03783 return it_ == it.it_;
03784 }
03785 BOOST_UBLAS_INLINE
03786 bool operator < (const const_iterator1 &it) const {
03787 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03788 return it_ < it.it_;
03789 }
03790
03791 private:
03792 const_subiterator_type it_;
03793
03794 friend class iterator1;
03795 };
03796 #endif
03797
03798 BOOST_UBLAS_INLINE
03799 const_iterator1 begin1 () const {
03800 return find1 (0, 0, 0);
03801 }
03802 BOOST_UBLAS_INLINE
03803 const_iterator1 end1 () const {
03804 return find1 (0, size1_, 0);
03805 }
03806
03807 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03808 class iterator1:
03809 public container_reference<c_matrix>,
03810 public random_access_iterator_base<dense_random_access_iterator_tag,
03811 iterator1, value_type> {
03812 public:
03813
03814 typedef typename c_matrix::difference_type difference_type;
03815 typedef typename c_matrix::value_type value_type;
03816 typedef typename c_matrix::reference reference;
03817 typedef typename c_matrix::pointer pointer;
03818
03819 typedef iterator2 dual_iterator_type;
03820 typedef reverse_iterator2 dual_reverse_iterator_type;
03821
03822
03823 BOOST_UBLAS_INLINE
03824 iterator1 ():
03825 container_reference<self_type> (), it_ () {}
03826 BOOST_UBLAS_INLINE
03827 iterator1 (self_type &m, const subiterator_type &it):
03828 container_reference<self_type> (m), it_ (it) {}
03829
03830
03831 BOOST_UBLAS_INLINE
03832 iterator1 &operator ++ () {
03833 it_ += M;
03834 return *this;
03835 }
03836 BOOST_UBLAS_INLINE
03837 iterator1 &operator -- () {
03838 it_ -= M;
03839 return *this;
03840 }
03841 BOOST_UBLAS_INLINE
03842 iterator1 &operator += (difference_type n) {
03843 it_ += n * M;
03844 return *this;
03845 }
03846 BOOST_UBLAS_INLINE
03847 iterator1 &operator -= (difference_type n) {
03848 it_ -= n * M;
03849 return *this;
03850 }
03851 BOOST_UBLAS_INLINE
03852 difference_type operator - (const iterator1 &it) const {
03853 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03854 return (it_ - it.it_) / M;
03855 }
03856
03857
03858 BOOST_UBLAS_INLINE
03859 reference operator * () const {
03860 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
03861 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
03862 return *it_;
03863 }
03864 BOOST_UBLAS_INLINE
03865 reference operator [] (difference_type n) const {
03866 return *(*this + n);
03867 }
03868
03869 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
03870 BOOST_UBLAS_INLINE
03871 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03872 typename self_type::
03873 #endif
03874 iterator2 begin () const {
03875 self_type &m = (*this) ();
03876 return m.find2 (1, index1 (), 0);
03877 }
03878 BOOST_UBLAS_INLINE
03879 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03880 typename self_type::
03881 #endif
03882 iterator2 end () const {
03883 self_type &m = (*this) ();
03884 return m.find2 (1, index1 (), m.size2 ());
03885 }
03886 BOOST_UBLAS_INLINE
03887 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03888 typename self_type::
03889 #endif
03890 reverse_iterator2 rbegin () const {
03891 return reverse_iterator2 (end ());
03892 }
03893 BOOST_UBLAS_INLINE
03894 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
03895 typename self_type::
03896 #endif
03897 reverse_iterator2 rend () const {
03898 return reverse_iterator2 (begin ());
03899 }
03900 #endif
03901
03902
03903 BOOST_UBLAS_INLINE
03904 size_type index1 () const {
03905 const self_type &m = (*this) ();
03906 return (it_ - m.begin1 ().it_) / M;
03907 }
03908 BOOST_UBLAS_INLINE
03909 size_type index2 () const {
03910 const self_type &m = (*this) ();
03911 return (it_ - m.begin1 ().it_) % M;
03912 }
03913
03914
03915 BOOST_UBLAS_INLINE
03916 iterator1 &operator = (const iterator1 &it) {
03917 container_reference<self_type>::assign (&it ());
03918 it_ = it.it_;
03919 return *this;
03920 }
03921
03922
03923 BOOST_UBLAS_INLINE
03924 bool operator == (const iterator1 &it) const {
03925 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03926 return it_ == it.it_;
03927 }
03928 BOOST_UBLAS_INLINE
03929 bool operator < (const iterator1 &it) const {
03930 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03931 return it_ < it.it_;
03932 }
03933
03934 private:
03935 subiterator_type it_;
03936
03937 friend class const_iterator1;
03938 };
03939 #endif
03940
03941 BOOST_UBLAS_INLINE
03942 iterator1 begin1 () {
03943 return find1 (0, 0, 0);
03944 }
03945 BOOST_UBLAS_INLINE
03946 iterator1 end1 () {
03947 return find1 (0, size1_, 0);
03948 }
03949
03950 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
03951 class const_iterator2:
03952 public container_const_reference<c_matrix>,
03953 public random_access_iterator_base<dense_random_access_iterator_tag,
03954 const_iterator2, value_type> {
03955 public:
03956 typedef typename c_matrix::difference_type difference_type;
03957 typedef typename c_matrix::value_type value_type;
03958 typedef typename c_matrix::const_reference reference;
03959 typedef typename c_matrix::const_reference pointer;
03960
03961 typedef const_iterator1 dual_iterator_type;
03962 typedef const_reverse_iterator1 dual_reverse_iterator_type;
03963
03964
03965 BOOST_UBLAS_INLINE
03966 const_iterator2 ():
03967 container_const_reference<self_type> (), it_ () {}
03968 BOOST_UBLAS_INLINE
03969 const_iterator2 (const self_type &m, const const_subiterator_type &it):
03970 container_const_reference<self_type> (m), it_ (it) {}
03971 BOOST_UBLAS_INLINE
03972 const_iterator2 (const iterator2 &it):
03973 container_const_reference<self_type> (it ()), it_ (it.it_) {}
03974
03975
03976 BOOST_UBLAS_INLINE
03977 const_iterator2 &operator ++ () {
03978 ++ it_;
03979 return *this;
03980 }
03981 BOOST_UBLAS_INLINE
03982 const_iterator2 &operator -- () {
03983 -- it_;
03984 return *this;
03985 }
03986 BOOST_UBLAS_INLINE
03987 const_iterator2 &operator += (difference_type n) {
03988 it_ += n;
03989 return *this;
03990 }
03991 BOOST_UBLAS_INLINE
03992 const_iterator2 &operator -= (difference_type n) {
03993 it_ -= n;
03994 return *this;
03995 }
03996 BOOST_UBLAS_INLINE
03997 difference_type operator - (const const_iterator2 &it) const {
03998 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
03999 return it_ - it.it_;
04000 }
04001
04002
04003 BOOST_UBLAS_INLINE
04004 const_reference operator * () const {
04005 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
04006 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
04007 return *it_;
04008 }
04009 BOOST_UBLAS_INLINE
04010 const_reference operator [] (difference_type n) const {
04011 return *(*this + n);
04012 }
04013
04014 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
04015 BOOST_UBLAS_INLINE
04016 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
04017 typename self_type::
04018 #endif
04019 const_iterator1 begin () const {
04020 const self_type &m = (*this) ();
04021 return m.find1 (1, 0, index2 ());
04022 }
04023 BOOST_UBLAS_INLINE
04024 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
04025 typename self_type::
04026 #endif
04027 const_iterator1 end () const {
04028 const self_type &m = (*this) ();
04029 return m.find1 (1, m.size1 (), index2 ());
04030 }
04031 BOOST_UBLAS_INLINE
04032 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
04033 typename self_type::
04034 #endif
04035 const_reverse_iterator1 rbegin () const {
04036 return const_reverse_iterator1 (end ());
04037 }
04038 BOOST_UBLAS_INLINE
04039 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
04040 typename self_type::
04041 #endif
04042 const_reverse_iterator1 rend () const {
04043 return const_reverse_iterator1 (begin ());
04044 }
04045 #endif
04046
04047
04048 BOOST_UBLAS_INLINE
04049 size_type index1 () const {
04050 const self_type &m = (*this) ();
04051 return (it_ - m.begin2 ().it_) / M;
04052 }
04053 BOOST_UBLAS_INLINE
04054 size_type index2 () const {
04055 const self_type &m = (*this) ();
04056 return (it_ - m.begin2 ().it_) % M;
04057 }
04058
04059
04060 BOOST_UBLAS_INLINE
04061 const_iterator2 &operator = (const const_iterator2 &it) {
04062 container_const_reference<self_type>::assign (&it ());
04063 it_ = it.it_;
04064 return *this;
04065 }
04066
04067
04068 BOOST_UBLAS_INLINE
04069 bool operator == (const const_iterator2 &it) const {
04070 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
04071 return it_ == it.it_;
04072 }
04073 BOOST_UBLAS_INLINE
04074 bool operator < (const const_iterator2 &it) const {
04075 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
04076 return it_ < it.it_;
04077 }
04078
04079 private:
04080 const_subiterator_type it_;
04081
04082 friend class iterator2;
04083 };
04084 #endif
04085
04086 BOOST_UBLAS_INLINE
04087 const_iterator2 begin2 () const {
04088 return find2 (0, 0, 0);
04089 }
04090 BOOST_UBLAS_INLINE
04091 const_iterator2 end2 () const {
04092 return find2 (0, 0, size2_);
04093 }
04094
04095 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
04096 class iterator2:
04097 public container_reference<c_matrix>,
04098 public random_access_iterator_base<dense_random_access_iterator_tag,
04099 iterator2, value_type> {
04100 public:
04101 typedef typename c_matrix::difference_type difference_type;
04102 typedef typename c_matrix::value_type value_type;
04103 typedef typename c_matrix::reference reference;
04104 typedef typename c_matrix::pointer pointer;
04105
04106 typedef iterator1 dual_iterator_type;
04107 typedef reverse_iterator1 dual_reverse_iterator_type;
04108
04109
04110 BOOST_UBLAS_INLINE
04111 iterator2 ():
04112 container_reference<self_type> (), it_ () {}
04113 BOOST_UBLAS_INLINE
04114 iterator2 (self_type &m, const subiterator_type &it):
04115 container_reference<self_type> (m), it_ (it) {}
04116
04117
04118 BOOST_UBLAS_INLINE
04119 iterator2 &operator ++ () {
04120 ++ it_;
04121 return *this;
04122 }
04123 BOOST_UBLAS_INLINE
04124 iterator2 &operator -- () {
04125 -- it_;
04126 return *this;
04127 }
04128 BOOST_UBLAS_INLINE
04129 iterator2 &operator += (difference_type n) {
04130 it_ += n;
04131 return *this;
04132 }
04133 BOOST_UBLAS_INLINE
04134 iterator2 &operator -= (difference_type n) {
04135 it_ -= n;
04136 return *this;
04137 }
04138 BOOST_UBLAS_INLINE
04139 difference_type operator - (const iterator2 &it) const {
04140 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
04141 return it_ - it.it_;
04142 }
04143
04144
04145 BOOST_UBLAS_INLINE
04146 reference operator * () const {
04147 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
04148 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
04149 return *it_;
04150 }
04151 BOOST_UBLAS_INLINE
04152 reference operator [] (difference_type n) const {
04153 return *(*this + n);
04154 }
04155
04156 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
04157 BOOST_UBLAS_INLINE
04158 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
04159 typename self_type::
04160 #endif
04161 iterator1 begin () const {
04162 self_type &m = (*this) ();
04163 return m.find1 (1, 0, index2 ());
04164 }
04165 BOOST_UBLAS_INLINE
04166 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
04167 typename self_type::
04168 #endif
04169 iterator1 end () const {
04170 self_type &m = (*this) ();
04171 return m.find1 (1, m.size1 (), index2 ());
04172 }
04173 BOOST_UBLAS_INLINE
04174 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
04175 typename self_type::
04176 #endif
04177 reverse_iterator1 rbegin () const {
04178 return reverse_iterator1 (end ());
04179 }
04180 BOOST_UBLAS_INLINE
04181 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
04182 typename self_type::
04183 #endif
04184 reverse_iterator1 rend () const {
04185 return reverse_iterator1 (begin ());
04186 }
04187 #endif
04188
04189
04190 BOOST_UBLAS_INLINE
04191 size_type index1 () const {
04192 const self_type &m = (*this) ();
04193 return (it_ - m.begin2 ().it_) / M;
04194 }
04195 BOOST_UBLAS_INLINE
04196 size_type index2 () const {
04197 const self_type &m = (*this) ();
04198 return (it_ - m.begin2 ().it_) % M;
04199 }
04200
04201
04202 BOOST_UBLAS_INLINE
04203 iterator2 &operator = (const iterator2 &it) {
04204 container_reference<self_type>::assign (&it ());
04205 it_ = it.it_;
04206 return *this;
04207 }
04208
04209
04210 BOOST_UBLAS_INLINE
04211 bool operator == (const iterator2 &it) const {
04212 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
04213 return it_ == it.it_;
04214 }
04215 BOOST_UBLAS_INLINE
04216 bool operator < (const iterator2 &it) const {
04217 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
04218 return it_ < it.it_;
04219 }
04220
04221 private:
04222 subiterator_type it_;
04223
04224 friend class const_iterator2;
04225 };
04226 #endif
04227
04228 BOOST_UBLAS_INLINE
04229 iterator2 begin2 () {
04230 return find2 (0, 0, 0);
04231 }
04232 BOOST_UBLAS_INLINE
04233 iterator2 end2 () {
04234 return find2 (0, 0, size2_);
04235 }
04236
04237
04238
04239 BOOST_UBLAS_INLINE
04240 const_reverse_iterator1 rbegin1 () const {
04241 return const_reverse_iterator1 (end1 ());
04242 }
04243 BOOST_UBLAS_INLINE
04244 const_reverse_iterator1 rend1 () const {
04245 return const_reverse_iterator1 (begin1 ());
04246 }
04247
04248 BOOST_UBLAS_INLINE
04249 reverse_iterator1 rbegin1 () {
04250 return reverse_iterator1 (end1 ());
04251 }
04252 BOOST_UBLAS_INLINE
04253 reverse_iterator1 rend1 () {
04254 return reverse_iterator1 (begin1 ());
04255 }
04256
04257 BOOST_UBLAS_INLINE
04258 const_reverse_iterator2 rbegin2 () const {
04259 return const_reverse_iterator2 (end2 ());
04260 }
04261 BOOST_UBLAS_INLINE
04262 const_reverse_iterator2 rend2 () const {
04263 return const_reverse_iterator2 (begin2 ());
04264 }
04265
04266 BOOST_UBLAS_INLINE
04267 reverse_iterator2 rbegin2 () {
04268 return reverse_iterator2 (end2 ());
04269 }
04270 BOOST_UBLAS_INLINE
04271 reverse_iterator2 rend2 () {
04272 return reverse_iterator2 (begin2 ());
04273 }
04274
04275
04276 template<class Archive>
04277 void serialize(Archive & ar, const unsigned int ){
04278
04279
04280
04281 serialization::collection_size_type s1 (size1_);
04282 serialization::collection_size_type s2 (size2_);
04283
04284
04285 ar & serialization::make_nvp("size1",s1)
04286 & serialization::make_nvp("size2",s2);
04287
04288
04289 if (Archive::is_loading::value) {
04290 size1_ = s1;
04291 size2_ = s2;
04292 }
04293
04294 ar & serialization::make_array(data_, N);
04295 }
04296
04297 private:
04298 size_type size1_;
04299 size_type size2_;
04300 value_type data_ [N] [M];
04301 };
04302
04303 }}}
04304
04305 #endif