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