annotate DEPENDENCIES/generic/include/boost/numeric/ublas/matrix.hpp @ 72:004555bedba1

Merge
author Chris Cannam
date Wed, 29 Oct 2014 17:39:34 +0000
parents 2665513ce2d3
children c530137014c0
rev   line source
Chris@16 1 //
Chris@16 2 // Copyright (c) 2000-2010
Chris@16 3 // Joerg Walter, Mathias Koch, Gunter Winkler, David Bellot
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // The authors gratefully acknowledge the support of
Chris@16 10 // GeNeSys mbH & Co. KG in producing this work.
Chris@16 11 //
Chris@16 12
Chris@16 13 #ifndef _BOOST_UBLAS_MATRIX_
Chris@16 14 #define _BOOST_UBLAS_MATRIX_
Chris@16 15
Chris@16 16 #include <boost/numeric/ublas/vector.hpp>
Chris@16 17 #include <boost/numeric/ublas/matrix_expression.hpp>
Chris@16 18 #include <boost/numeric/ublas/detail/matrix_assign.hpp>
Chris@16 19 #include <boost/serialization/collection_size_type.hpp>
Chris@16 20 #include <boost/serialization/array.hpp>
Chris@16 21 #include <boost/serialization/nvp.hpp>
Chris@16 22
Chris@16 23 // Iterators based on ideas of Jeremy Siek
Chris@16 24
Chris@16 25 namespace boost { namespace numeric {
Chris@16 26
Chris@16 27 /** \brief main namespace of uBLAS.
Chris@16 28 *
Chris@16 29 * Use this namespace for all operations with uBLAS. It can also be abbreviated with
Chris@16 30 * \code namespace ublas = boost::numeric::ublas; \endcode
Chris@16 31 *
Chris@16 32 * A common practice is to bring this namespace into the current scope with
Chris@16 33 * \code using namespace boost::numeric::ublas; \endcode.
Chris@16 34 *
Chris@16 35 * However, be warned that using the ublas namespace and the std::vector at the same time can lead to the compiler to confusion.
Chris@16 36 * The solution is simply to prefix each ublas vector like \c boost::numeric::ublas::vector<T>. If you think it's too long to
Chris@16 37 * write, you can define a new namespace like \c namespace ublas = boost::numeric::ublas and then just declare your vectors
Chris@16 38 * with \c ublas::vector<T>. STL vectors will be declared as vector<T>. No need to prefix with \c std::
Chris@16 39 */
Chris@16 40 namespace ublas {
Chris@16 41
Chris@16 42 namespace detail {
Chris@16 43 using namespace boost::numeric::ublas;
Chris@16 44
Chris@16 45 // Matrix resizing algorithm
Chris@16 46 template <class L, class M>
Chris@16 47 BOOST_UBLAS_INLINE
Chris@16 48 void matrix_resize_preserve (M& m, M& temporary) {
Chris@16 49 typedef L layout_type;
Chris@16 50 typedef typename M::size_type size_type;
Chris@16 51 const size_type msize1 (m.size1 ()); // original size
Chris@16 52 const size_type msize2 (m.size2 ());
Chris@16 53 const size_type size1 (temporary.size1 ()); // new size is specified by temporary
Chris@16 54 const size_type size2 (temporary.size2 ());
Chris@16 55 // Common elements to preserve
Chris@16 56 const size_type size1_min = (std::min) (size1, msize1);
Chris@16 57 const size_type size2_min = (std::min) (size2, msize2);
Chris@16 58 // Order for major and minor sizes
Chris@16 59 const size_type major_size = layout_type::size_M (size1_min, size2_min);
Chris@16 60 const size_type minor_size = layout_type::size_m (size1_min, size2_min);
Chris@16 61 // Indexing copy over major
Chris@16 62 for (size_type major = 0; major != major_size; ++major) {
Chris@16 63 for (size_type minor = 0; minor != minor_size; ++minor) {
Chris@16 64 // find indexes - use invertability of element_ functions
Chris@16 65 const size_type i1 = layout_type::index_M(major, minor);
Chris@16 66 const size_type i2 = layout_type::index_m(major, minor);
Chris@16 67 temporary.data () [layout_type::element (i1, size1, i2, size2)] =
Chris@16 68 m.data() [layout_type::element (i1, msize1, i2, msize2)];
Chris@16 69 }
Chris@16 70 }
Chris@16 71 m.assign_temporary (temporary);
Chris@16 72 }
Chris@16 73 }
Chris@16 74
Chris@16 75 /** \brief A dense matrix of values of type \c T.
Chris@16 76 *
Chris@16 77 * For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$ m_{i,j} \f$ is mapped to
Chris@16 78 * the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$ (i + j.m) \f$-th element of
Chris@16 79 * the container for column major orientation. In a dense matrix all elements are represented in memory in a
Chris@16 80 * contiguous chunk of memory by definition.
Chris@16 81 *
Chris@16 82 * Orientation and storage can also be specified, otherwise a \c row_major and \c unbounded_array are used. It is \b not
Chris@16 83 * required by the storage to initialize elements of the matrix.
Chris@16 84 *
Chris@16 85 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 86 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
Chris@16 87 * \tparam A the type of Storage array. Default is \c unbounded_array
Chris@16 88 */
Chris@16 89 template<class T, class L, class A>
Chris@16 90 class matrix:
Chris@16 91 public matrix_container<matrix<T, L, A> > {
Chris@16 92
Chris@16 93 typedef T *pointer;
Chris@16 94 typedef L layout_type;
Chris@16 95 typedef matrix<T, L, A> self_type;
Chris@16 96 public:
Chris@16 97 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 98 using matrix_container<self_type>::operator ();
Chris@16 99 #endif
Chris@16 100 typedef typename A::size_type size_type;
Chris@16 101 typedef typename A::difference_type difference_type;
Chris@16 102 typedef T value_type;
Chris@16 103 typedef const T &const_reference;
Chris@16 104 typedef T &reference;
Chris@16 105 typedef A array_type;
Chris@16 106 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 107 typedef matrix_reference<self_type> closure_type;
Chris@16 108 typedef vector<T, A> vector_temporary_type;
Chris@16 109 typedef self_type matrix_temporary_type;
Chris@16 110 typedef dense_tag storage_category;
Chris@16 111 // This could be better for performance,
Chris@16 112 // typedef typename unknown_orientation_tag orientation_category;
Chris@16 113 // but others depend on the orientation information...
Chris@16 114 typedef typename L::orientation_category orientation_category;
Chris@16 115
Chris@16 116 // Construction and destruction
Chris@16 117
Chris@16 118 /// Default dense matrix constructor. Make a dense matrix of size (0,0)
Chris@16 119 BOOST_UBLAS_INLINE
Chris@16 120 matrix ():
Chris@16 121 matrix_container<self_type> (),
Chris@16 122 size1_ (0), size2_ (0), data_ () {}
Chris@16 123
Chris@16 124 /** Dense matrix constructor with defined size
Chris@16 125 * \param size1 number of rows
Chris@16 126 * \param size2 number of columns
Chris@16 127 */
Chris@16 128 BOOST_UBLAS_INLINE
Chris@16 129 matrix (size_type size1, size_type size2):
Chris@16 130 matrix_container<self_type> (),
Chris@16 131 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) {
Chris@16 132 }
Chris@16 133
Chris@16 134 /** Dense matrix constructor with defined size a initial value for all the matrix elements
Chris@16 135 * \param size1 number of rows
Chris@16 136 * \param size2 number of columns
Chris@16 137 * \param init initial value assigned to all elements
Chris@16 138 */
Chris@16 139 matrix (size_type size1, size_type size2, const value_type &init):
Chris@16 140 matrix_container<self_type> (),
Chris@16 141 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2), init) {
Chris@16 142 }
Chris@16 143
Chris@16 144 /** Dense matrix constructor with defined size and an initial data array
Chris@16 145 * \param size1 number of rows
Chris@16 146 * \param size2 number of columns
Chris@16 147 * \param data array to copy into the matrix. Must have the same dimension as the matrix
Chris@16 148 */
Chris@16 149 BOOST_UBLAS_INLINE
Chris@16 150 matrix (size_type size1, size_type size2, const array_type &data):
Chris@16 151 matrix_container<self_type> (),
Chris@16 152 size1_ (size1), size2_ (size2), data_ (data) {}
Chris@16 153
Chris@16 154 /** Copy-constructor of a dense matrix
Chris@16 155 * \param m is a dense matrix
Chris@16 156 */
Chris@16 157 BOOST_UBLAS_INLINE
Chris@16 158 matrix (const matrix &m):
Chris@16 159 matrix_container<self_type> (),
Chris@16 160 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
Chris@16 161
Chris@16 162 /** Copy-constructor of a dense matrix from a matrix expression
Chris@16 163 * \param ae is a matrix expression
Chris@16 164 */
Chris@16 165 template<class AE>
Chris@16 166 BOOST_UBLAS_INLINE
Chris@16 167 matrix (const matrix_expression<AE> &ae):
Chris@16 168 matrix_container<self_type> (),
Chris@16 169 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) {
Chris@16 170 matrix_assign<scalar_assign> (*this, ae);
Chris@16 171 }
Chris@16 172
Chris@16 173 // Accessors
Chris@16 174 /** Return the number of rows of the matrix
Chris@16 175 * You can also use the free size<>() function in operation/size.hpp as size<1>(m) where m is a matrix
Chris@16 176 */
Chris@16 177 BOOST_UBLAS_INLINE
Chris@16 178 size_type size1 () const {
Chris@16 179 return size1_;
Chris@16 180 }
Chris@16 181
Chris@16 182 /** Return the number of colums of the matrix
Chris@16 183 * You can also use the free size<>() function in operation/size.hpp as size<2>(m) where m is a matrix
Chris@16 184 */
Chris@16 185 BOOST_UBLAS_INLINE
Chris@16 186 size_type size2 () const {
Chris@16 187 return size2_;
Chris@16 188 }
Chris@16 189
Chris@16 190 // Storage accessors
Chris@16 191 /** Return a constant reference to the internal storage of a dense matrix, i.e. the raw data
Chris@16 192 * It's type depends on the type used by the matrix to store its data
Chris@16 193 */
Chris@16 194 BOOST_UBLAS_INLINE
Chris@16 195 const array_type &data () const {
Chris@16 196 return data_;
Chris@16 197 }
Chris@16 198 /** Return a reference to the internal storage of a dense matrix, i.e. the raw data
Chris@16 199 * It's type depends on the type used by the matrix to store its data
Chris@16 200 */
Chris@16 201 BOOST_UBLAS_INLINE
Chris@16 202 array_type &data () {
Chris@16 203 return data_;
Chris@16 204 }
Chris@16 205
Chris@16 206 // Resizing
Chris@16 207 /** Resize a matrix to new dimensions
Chris@16 208 * If data are preserved, then if the size if bigger at least on one dimension, extra values are filled with zeros.
Chris@16 209 * If data are not preserved, then nothing has to be assumed regarding the content of the matrix after resizing.
Chris@16 210 * \param size1 the new number of rows
Chris@16 211 * \param size2 the new number of colums
Chris@16 212 * \param preserve a boolean to say if one wants the data to be preserved during the resizing. Default is true.
Chris@16 213 */
Chris@16 214 BOOST_UBLAS_INLINE
Chris@16 215 void resize (size_type size1, size_type size2, bool preserve = true) {
Chris@16 216 if (preserve) {
Chris@16 217 self_type temporary (size1, size2);
Chris@16 218 detail::matrix_resize_preserve<layout_type> (*this, temporary);
Chris@16 219 }
Chris@16 220 else {
Chris@16 221 data ().resize (layout_type::storage_size (size1, size2));
Chris@16 222 size1_ = size1;
Chris@16 223 size2_ = size2;
Chris@16 224 }
Chris@16 225 }
Chris@16 226
Chris@16 227 // Element access
Chris@16 228
Chris@16 229 /** Access a matrix element. Here we return a const reference
Chris@16 230 * \param i the first coordinate of the element. By default it's the row
Chris@16 231 * \param j the second coordinate of the element. By default it's the column
Chris@16 232 * \return a const reference to the element
Chris@16 233 */
Chris@16 234 BOOST_UBLAS_INLINE
Chris@16 235 const_reference operator () (size_type i, size_type j) const {
Chris@16 236 return data () [layout_type::element (i, size1_, j, size2_)];
Chris@16 237 }
Chris@16 238
Chris@16 239 /** Access a matrix element. Here we return a reference
Chris@16 240 * \param i the first coordinate of the element. By default it's the row
Chris@16 241 * \param j the second coordinate of the element. By default it's the column
Chris@16 242 * \return a reference to the element
Chris@16 243 */
Chris@16 244 BOOST_UBLAS_INLINE
Chris@16 245 reference at_element (size_type i, size_type j) {
Chris@16 246 return data () [layout_type::element (i, size1_, j, size2_)];
Chris@16 247 }
Chris@16 248
Chris@16 249 /** Access a matrix element. Here we return a reference
Chris@16 250 * \param i the first coordinate of the element. By default it's the row
Chris@16 251 * \param j the second coordinate of the element. By default it's the column
Chris@16 252 * \return a reference to the element
Chris@16 253 */
Chris@16 254 BOOST_UBLAS_INLINE
Chris@16 255 reference operator () (size_type i, size_type j) {
Chris@16 256 return at_element (i, j);
Chris@16 257 }
Chris@16 258
Chris@16 259 // Element assignment
Chris@16 260
Chris@16 261 /** Change the value of a matrix element. Return back a reference to it
Chris@16 262 * \param i the first coordinate of the element. By default it's the row
Chris@16 263 * \param j the second coordinate of the element. By default it's the column
Chris@16 264 * \param t the new value of the element
Chris@16 265 * \return a reference to the newly changed element
Chris@16 266 */
Chris@16 267 BOOST_UBLAS_INLINE
Chris@16 268 reference insert_element (size_type i, size_type j, const_reference t) {
Chris@16 269 return (at_element (i, j) = t);
Chris@16 270 }
Chris@16 271
Chris@16 272 /** Erase the element
Chris@16 273 * For most types (int, double, etc...) it means setting 0 (zero) the element at zero in fact.
Chris@16 274 * For user-defined types, it could be another value if you decided it. Your type in that case must
Chris@16 275 * contain a default null value.
Chris@16 276 * \param i the first coordinate of the element. By default it's the row
Chris@16 277 * \param j the second coordinate of the element. By default it's the column
Chris@16 278 */
Chris@16 279 void erase_element (size_type i, size_type j) {
Chris@16 280 at_element (i, j) = value_type/*zero*/();
Chris@16 281 }
Chris@16 282
Chris@16 283 // Zeroing
Chris@16 284 /** Erase all elements in the matrix
Chris@16 285 * For most types (int, double, etc...) it means writing 0 (zero) everywhere.
Chris@16 286 * For user-defined types, it could be another value if you decided it. Your type in that case must
Chris@16 287 * contain a default null value.
Chris@16 288 */
Chris@16 289 BOOST_UBLAS_INLINE
Chris@16 290 void clear () {
Chris@16 291 std::fill (data ().begin (), data ().end (), value_type/*zero*/());
Chris@16 292 }
Chris@16 293
Chris@16 294 // Assignment
Chris@16 295 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
Chris@16 296
Chris@16 297 /*! @note "pass by value" the key idea to enable move semantics */
Chris@16 298 BOOST_UBLAS_INLINE
Chris@16 299 matrix &operator = (matrix m) {
Chris@16 300 assign_temporary(m);
Chris@16 301 return *this;
Chris@16 302 }
Chris@16 303 #else
Chris@16 304 BOOST_UBLAS_INLINE
Chris@16 305 matrix &operator = (const matrix &m) {
Chris@16 306 size1_ = m.size1_;
Chris@16 307 size2_ = m.size2_;
Chris@16 308 data () = m.data ();
Chris@16 309 return *this;
Chris@16 310 }
Chris@16 311 #endif
Chris@16 312 template<class C> // Container assignment without temporary
Chris@16 313 BOOST_UBLAS_INLINE
Chris@16 314 matrix &operator = (const matrix_container<C> &m) {
Chris@16 315 resize (m ().size1 (), m ().size2 (), false);
Chris@16 316 assign (m);
Chris@16 317 return *this;
Chris@16 318 }
Chris@16 319 BOOST_UBLAS_INLINE
Chris@16 320 matrix &assign_temporary (matrix &m) {
Chris@16 321 swap (m);
Chris@16 322 return *this;
Chris@16 323 }
Chris@16 324 template<class AE>
Chris@16 325 BOOST_UBLAS_INLINE
Chris@16 326 matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 327 self_type temporary (ae);
Chris@16 328 return assign_temporary (temporary);
Chris@16 329 }
Chris@16 330 template<class AE>
Chris@16 331 BOOST_UBLAS_INLINE
Chris@16 332 matrix &assign (const matrix_expression<AE> &ae) {
Chris@16 333 matrix_assign<scalar_assign> (*this, ae);
Chris@16 334 return *this;
Chris@16 335 }
Chris@16 336 template<class AE>
Chris@16 337 BOOST_UBLAS_INLINE
Chris@16 338 matrix& operator += (const matrix_expression<AE> &ae) {
Chris@16 339 self_type temporary (*this + ae);
Chris@16 340 return assign_temporary (temporary);
Chris@16 341 }
Chris@16 342 template<class C> // Container assignment without temporary
Chris@16 343 BOOST_UBLAS_INLINE
Chris@16 344 matrix &operator += (const matrix_container<C> &m) {
Chris@16 345 plus_assign (m);
Chris@16 346 return *this;
Chris@16 347 }
Chris@16 348 template<class AE>
Chris@16 349 BOOST_UBLAS_INLINE
Chris@16 350 matrix &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 351 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 352 return *this;
Chris@16 353 }
Chris@16 354 template<class AE>
Chris@16 355 BOOST_UBLAS_INLINE
Chris@16 356 matrix& operator -= (const matrix_expression<AE> &ae) {
Chris@16 357 self_type temporary (*this - ae);
Chris@16 358 return assign_temporary (temporary);
Chris@16 359 }
Chris@16 360 template<class C> // Container assignment without temporary
Chris@16 361 BOOST_UBLAS_INLINE
Chris@16 362 matrix &operator -= (const matrix_container<C> &m) {
Chris@16 363 minus_assign (m);
Chris@16 364 return *this;
Chris@16 365 }
Chris@16 366 template<class AE>
Chris@16 367 BOOST_UBLAS_INLINE
Chris@16 368 matrix &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 369 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 370 return *this;
Chris@16 371 }
Chris@16 372 template<class AT>
Chris@16 373 BOOST_UBLAS_INLINE
Chris@16 374 matrix& operator *= (const AT &at) {
Chris@16 375 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 376 return *this;
Chris@16 377 }
Chris@16 378 template<class AT>
Chris@16 379 BOOST_UBLAS_INLINE
Chris@16 380 matrix& operator /= (const AT &at) {
Chris@16 381 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 382 return *this;
Chris@16 383 }
Chris@16 384
Chris@16 385 // Swapping
Chris@16 386 BOOST_UBLAS_INLINE
Chris@16 387 void swap (matrix &m) {
Chris@16 388 if (this != &m) {
Chris@16 389 std::swap (size1_, m.size1_);
Chris@16 390 std::swap (size2_, m.size2_);
Chris@16 391 data ().swap (m.data ());
Chris@16 392 }
Chris@16 393 }
Chris@16 394 BOOST_UBLAS_INLINE
Chris@16 395 friend void swap (matrix &m1, matrix &m2) {
Chris@16 396 m1.swap (m2);
Chris@16 397 }
Chris@16 398
Chris@16 399 // Iterator types
Chris@16 400 private:
Chris@16 401 // Use the storage array iterator
Chris@16 402 typedef typename A::const_iterator const_subiterator_type;
Chris@16 403 typedef typename A::iterator subiterator_type;
Chris@16 404
Chris@16 405 public:
Chris@16 406 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 407 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@16 408 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@16 409 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 410 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 411 #else
Chris@16 412 class const_iterator1;
Chris@16 413 class iterator1;
Chris@16 414 class const_iterator2;
Chris@16 415 class iterator2;
Chris@16 416 #endif
Chris@16 417 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 418 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 419 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 420 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 421
Chris@16 422 // Element lookup
Chris@16 423 BOOST_UBLAS_INLINE
Chris@16 424 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
Chris@16 425 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 426 return const_iterator1 (*this, i, j);
Chris@16 427 #else
Chris@16 428 return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
Chris@16 429 #endif
Chris@16 430 }
Chris@16 431 BOOST_UBLAS_INLINE
Chris@16 432 iterator1 find1 (int /* rank */, size_type i, size_type j) {
Chris@16 433 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 434 return iterator1 (*this, i, j);
Chris@16 435 #else
Chris@16 436 return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
Chris@16 437 #endif
Chris@16 438 }
Chris@16 439 BOOST_UBLAS_INLINE
Chris@16 440 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
Chris@16 441 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 442 return const_iterator2 (*this, i, j);
Chris@16 443 #else
Chris@16 444 return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
Chris@16 445 #endif
Chris@16 446 }
Chris@16 447 BOOST_UBLAS_INLINE
Chris@16 448 iterator2 find2 (int /* rank */, size_type i, size_type j) {
Chris@16 449 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 450 return iterator2 (*this, i, j);
Chris@16 451 #else
Chris@16 452 return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
Chris@16 453 #endif
Chris@16 454 }
Chris@16 455
Chris@16 456
Chris@16 457 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 458 class const_iterator1:
Chris@16 459 public container_const_reference<matrix>,
Chris@16 460 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 461 const_iterator1, value_type> {
Chris@16 462 public:
Chris@16 463 typedef typename matrix::value_type value_type;
Chris@16 464 typedef typename matrix::difference_type difference_type;
Chris@16 465 typedef typename matrix::const_reference reference;
Chris@16 466 typedef const typename matrix::pointer pointer;
Chris@16 467
Chris@16 468 typedef const_iterator2 dual_iterator_type;
Chris@16 469 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 470
Chris@16 471 // Construction and destruction
Chris@16 472 BOOST_UBLAS_INLINE
Chris@16 473 const_iterator1 ():
Chris@16 474 container_const_reference<self_type> (), it_ () {}
Chris@16 475 BOOST_UBLAS_INLINE
Chris@16 476 const_iterator1 (const self_type &m, const const_subiterator_type &it):
Chris@16 477 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 478 BOOST_UBLAS_INLINE
Chris@16 479 const_iterator1 (const iterator1 &it):
Chris@16 480 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 481
Chris@16 482 // Arithmetic
Chris@16 483 BOOST_UBLAS_INLINE
Chris@16 484 const_iterator1 &operator ++ () {
Chris@16 485 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 486 return *this;
Chris@16 487 }
Chris@16 488 BOOST_UBLAS_INLINE
Chris@16 489 const_iterator1 &operator -- () {
Chris@16 490 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 491 return *this;
Chris@16 492 }
Chris@16 493 BOOST_UBLAS_INLINE
Chris@16 494 const_iterator1 &operator += (difference_type n) {
Chris@16 495 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 496 return *this;
Chris@16 497 }
Chris@16 498 BOOST_UBLAS_INLINE
Chris@16 499 const_iterator1 &operator -= (difference_type n) {
Chris@16 500 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 501 return *this;
Chris@16 502 }
Chris@16 503 BOOST_UBLAS_INLINE
Chris@16 504 difference_type operator - (const const_iterator1 &it) const {
Chris@16 505 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 506 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 507 }
Chris@16 508
Chris@16 509 // Dereference
Chris@16 510 BOOST_UBLAS_INLINE
Chris@16 511 const_reference operator * () const {
Chris@16 512 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 513 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 514 return *it_;
Chris@16 515 }
Chris@16 516 BOOST_UBLAS_INLINE
Chris@16 517 const_reference operator [] (difference_type n) const {
Chris@16 518 return *(*this + n);
Chris@16 519 }
Chris@16 520
Chris@16 521 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 522 BOOST_UBLAS_INLINE
Chris@16 523 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 524 typename self_type::
Chris@16 525 #endif
Chris@16 526 const_iterator2 begin () const {
Chris@16 527 const self_type &m = (*this) ();
Chris@16 528 return m.find2 (1, index1 (), 0);
Chris@16 529 }
Chris@16 530 BOOST_UBLAS_INLINE
Chris@16 531 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 532 typename self_type::
Chris@16 533 #endif
Chris@16 534 const_iterator2 end () const {
Chris@16 535 const self_type &m = (*this) ();
Chris@16 536 return m.find2 (1, index1 (), m.size2 ());
Chris@16 537 }
Chris@16 538 BOOST_UBLAS_INLINE
Chris@16 539 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 540 typename self_type::
Chris@16 541 #endif
Chris@16 542 const_reverse_iterator2 rbegin () const {
Chris@16 543 return const_reverse_iterator2 (end ());
Chris@16 544 }
Chris@16 545 BOOST_UBLAS_INLINE
Chris@16 546 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 547 typename self_type::
Chris@16 548 #endif
Chris@16 549 const_reverse_iterator2 rend () const {
Chris@16 550 return const_reverse_iterator2 (begin ());
Chris@16 551 }
Chris@16 552 #endif
Chris@16 553
Chris@16 554 // Indices
Chris@16 555 BOOST_UBLAS_INLINE
Chris@16 556 size_type index1 () const {
Chris@16 557 const self_type &m = (*this) ();
Chris@16 558 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@16 559 }
Chris@16 560 BOOST_UBLAS_INLINE
Chris@16 561 size_type index2 () const {
Chris@16 562 const self_type &m = (*this) ();
Chris@16 563 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@16 564 }
Chris@16 565
Chris@16 566 // Assignment
Chris@16 567 BOOST_UBLAS_INLINE
Chris@16 568 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 569 container_const_reference<self_type>::assign (&it ());
Chris@16 570 it_ = it.it_;
Chris@16 571 return *this;
Chris@16 572 }
Chris@16 573
Chris@16 574 // Comparison
Chris@16 575 BOOST_UBLAS_INLINE
Chris@16 576 bool operator == (const const_iterator1 &it) const {
Chris@16 577 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 578 return it_ == it.it_;
Chris@16 579 }
Chris@16 580 BOOST_UBLAS_INLINE
Chris@16 581 bool operator < (const const_iterator1 &it) const {
Chris@16 582 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 583 return it_ < it.it_;
Chris@16 584 }
Chris@16 585
Chris@16 586 private:
Chris@16 587 const_subiterator_type it_;
Chris@16 588
Chris@16 589 friend class iterator1;
Chris@16 590 };
Chris@16 591 #endif
Chris@16 592
Chris@16 593 BOOST_UBLAS_INLINE
Chris@16 594 const_iterator1 begin1 () const {
Chris@16 595 return find1 (0, 0, 0);
Chris@16 596 }
Chris@16 597 BOOST_UBLAS_INLINE
Chris@16 598 const_iterator1 end1 () const {
Chris@16 599 return find1 (0, size1_, 0);
Chris@16 600 }
Chris@16 601
Chris@16 602 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 603 class iterator1:
Chris@16 604 public container_reference<matrix>,
Chris@16 605 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 606 iterator1, value_type> {
Chris@16 607 public:
Chris@16 608 typedef typename matrix::value_type value_type;
Chris@16 609 typedef typename matrix::difference_type difference_type;
Chris@16 610 typedef typename matrix::reference reference;
Chris@16 611 typedef typename matrix::pointer pointer;
Chris@16 612
Chris@16 613 typedef iterator2 dual_iterator_type;
Chris@16 614 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 615
Chris@16 616 // Construction and destruction
Chris@16 617 BOOST_UBLAS_INLINE
Chris@16 618 iterator1 ():
Chris@16 619 container_reference<self_type> (), it_ () {}
Chris@16 620 BOOST_UBLAS_INLINE
Chris@16 621 iterator1 (self_type &m, const subiterator_type &it):
Chris@16 622 container_reference<self_type> (m), it_ (it) {}
Chris@16 623
Chris@16 624 // Arithmetic
Chris@16 625 BOOST_UBLAS_INLINE
Chris@16 626 iterator1 &operator ++ () {
Chris@16 627 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 628 return *this;
Chris@16 629 }
Chris@16 630 BOOST_UBLAS_INLINE
Chris@16 631 iterator1 &operator -- () {
Chris@16 632 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 633 return *this;
Chris@16 634 }
Chris@16 635 BOOST_UBLAS_INLINE
Chris@16 636 iterator1 &operator += (difference_type n) {
Chris@16 637 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 638 return *this;
Chris@16 639 }
Chris@16 640 BOOST_UBLAS_INLINE
Chris@16 641 iterator1 &operator -= (difference_type n) {
Chris@16 642 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 643 return *this;
Chris@16 644 }
Chris@16 645 BOOST_UBLAS_INLINE
Chris@16 646 difference_type operator - (const iterator1 &it) const {
Chris@16 647 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 648 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 649 }
Chris@16 650
Chris@16 651 // Dereference
Chris@16 652 BOOST_UBLAS_INLINE
Chris@16 653 reference operator * () const {
Chris@16 654 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 655 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 656 return *it_;
Chris@16 657 }
Chris@16 658 BOOST_UBLAS_INLINE
Chris@16 659 reference operator [] (difference_type n) const {
Chris@16 660 return *(*this + n);
Chris@16 661 }
Chris@16 662
Chris@16 663 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 664 BOOST_UBLAS_INLINE
Chris@16 665 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 666 typename self_type::
Chris@16 667 #endif
Chris@16 668 iterator2 begin () const {
Chris@16 669 self_type &m = (*this) ();
Chris@16 670 return m.find2 (1, index1 (), 0);
Chris@16 671 }
Chris@16 672 BOOST_UBLAS_INLINE
Chris@16 673 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 674 typename self_type::
Chris@16 675 #endif
Chris@16 676 iterator2 end () const {
Chris@16 677 self_type &m = (*this) ();
Chris@16 678 return m.find2 (1, index1 (), m.size2 ());
Chris@16 679 }
Chris@16 680 BOOST_UBLAS_INLINE
Chris@16 681 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 682 typename self_type::
Chris@16 683 #endif
Chris@16 684 reverse_iterator2 rbegin () const {
Chris@16 685 return reverse_iterator2 (end ());
Chris@16 686 }
Chris@16 687 BOOST_UBLAS_INLINE
Chris@16 688 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 689 typename self_type::
Chris@16 690 #endif
Chris@16 691 reverse_iterator2 rend () const {
Chris@16 692 return reverse_iterator2 (begin ());
Chris@16 693 }
Chris@16 694 #endif
Chris@16 695
Chris@16 696 // Indices
Chris@16 697 BOOST_UBLAS_INLINE
Chris@16 698 size_type index1 () const {
Chris@16 699 self_type &m = (*this) ();
Chris@16 700 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@16 701 }
Chris@16 702 BOOST_UBLAS_INLINE
Chris@16 703 size_type index2 () const {
Chris@16 704 self_type &m = (*this) ();
Chris@16 705 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@16 706 }
Chris@16 707
Chris@16 708 // Assignment
Chris@16 709 BOOST_UBLAS_INLINE
Chris@16 710 iterator1 &operator = (const iterator1 &it) {
Chris@16 711 container_reference<self_type>::assign (&it ());
Chris@16 712 it_ = it.it_;
Chris@16 713 return *this;
Chris@16 714 }
Chris@16 715
Chris@16 716 // Comparison
Chris@16 717 BOOST_UBLAS_INLINE
Chris@16 718 bool operator == (const iterator1 &it) const {
Chris@16 719 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 720 return it_ == it.it_;
Chris@16 721 }
Chris@16 722 BOOST_UBLAS_INLINE
Chris@16 723 bool operator < (const iterator1 &it) const {
Chris@16 724 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 725 return it_ < it.it_;
Chris@16 726 }
Chris@16 727
Chris@16 728 private:
Chris@16 729 subiterator_type it_;
Chris@16 730
Chris@16 731 friend class const_iterator1;
Chris@16 732 };
Chris@16 733 #endif
Chris@16 734
Chris@16 735 BOOST_UBLAS_INLINE
Chris@16 736 iterator1 begin1 () {
Chris@16 737 return find1 (0, 0, 0);
Chris@16 738 }
Chris@16 739 BOOST_UBLAS_INLINE
Chris@16 740 iterator1 end1 () {
Chris@16 741 return find1 (0, size1_, 0);
Chris@16 742 }
Chris@16 743
Chris@16 744 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 745 class const_iterator2:
Chris@16 746 public container_const_reference<matrix>,
Chris@16 747 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 748 const_iterator2, value_type> {
Chris@16 749 public:
Chris@16 750 typedef typename matrix::value_type value_type;
Chris@16 751 typedef typename matrix::difference_type difference_type;
Chris@16 752 typedef typename matrix::const_reference reference;
Chris@16 753 typedef const typename matrix::pointer pointer;
Chris@16 754
Chris@16 755 typedef const_iterator1 dual_iterator_type;
Chris@16 756 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 757
Chris@16 758 // Construction and destruction
Chris@16 759 BOOST_UBLAS_INLINE
Chris@16 760 const_iterator2 ():
Chris@16 761 container_const_reference<self_type> (), it_ () {}
Chris@16 762 BOOST_UBLAS_INLINE
Chris@16 763 const_iterator2 (const self_type &m, const const_subiterator_type &it):
Chris@16 764 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 765 BOOST_UBLAS_INLINE
Chris@16 766 const_iterator2 (const iterator2 &it):
Chris@16 767 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 768
Chris@16 769 // Arithmetic
Chris@16 770 BOOST_UBLAS_INLINE
Chris@16 771 const_iterator2 &operator ++ () {
Chris@16 772 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 773 return *this;
Chris@16 774 }
Chris@16 775 BOOST_UBLAS_INLINE
Chris@16 776 const_iterator2 &operator -- () {
Chris@16 777 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 778 return *this;
Chris@16 779 }
Chris@16 780 BOOST_UBLAS_INLINE
Chris@16 781 const_iterator2 &operator += (difference_type n) {
Chris@16 782 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 783 return *this;
Chris@16 784 }
Chris@16 785 BOOST_UBLAS_INLINE
Chris@16 786 const_iterator2 &operator -= (difference_type n) {
Chris@16 787 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 788 return *this;
Chris@16 789 }
Chris@16 790 BOOST_UBLAS_INLINE
Chris@16 791 difference_type operator - (const const_iterator2 &it) const {
Chris@16 792 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 793 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 794 }
Chris@16 795
Chris@16 796 // Dereference
Chris@16 797 BOOST_UBLAS_INLINE
Chris@16 798 const_reference operator * () const {
Chris@16 799 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 800 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 801 return *it_;
Chris@16 802 }
Chris@16 803 BOOST_UBLAS_INLINE
Chris@16 804 const_reference operator [] (difference_type n) const {
Chris@16 805 return *(*this + n);
Chris@16 806 }
Chris@16 807
Chris@16 808 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 809 BOOST_UBLAS_INLINE
Chris@16 810 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 811 typename self_type::
Chris@16 812 #endif
Chris@16 813 const_iterator1 begin () const {
Chris@16 814 const self_type &m = (*this) ();
Chris@16 815 return m.find1 (1, 0, index2 ());
Chris@16 816 }
Chris@16 817 BOOST_UBLAS_INLINE
Chris@16 818 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 819 typename self_type::
Chris@16 820 #endif
Chris@16 821 const_iterator1 end () const {
Chris@16 822 const self_type &m = (*this) ();
Chris@16 823 return m.find1 (1, m.size1 (), index2 ());
Chris@16 824 }
Chris@16 825 BOOST_UBLAS_INLINE
Chris@16 826 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 827 typename self_type::
Chris@16 828 #endif
Chris@16 829 const_reverse_iterator1 rbegin () const {
Chris@16 830 return const_reverse_iterator1 (end ());
Chris@16 831 }
Chris@16 832 BOOST_UBLAS_INLINE
Chris@16 833 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 834 typename self_type::
Chris@16 835 #endif
Chris@16 836 const_reverse_iterator1 rend () const {
Chris@16 837 return const_reverse_iterator1 (begin ());
Chris@16 838 }
Chris@16 839 #endif
Chris@16 840
Chris@16 841 // Indices
Chris@16 842 BOOST_UBLAS_INLINE
Chris@16 843 size_type index1 () const {
Chris@16 844 const self_type &m = (*this) ();
Chris@16 845 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@16 846 }
Chris@16 847 BOOST_UBLAS_INLINE
Chris@16 848 size_type index2 () const {
Chris@16 849 const self_type &m = (*this) ();
Chris@16 850 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@16 851 }
Chris@16 852
Chris@16 853 // Assignment
Chris@16 854 BOOST_UBLAS_INLINE
Chris@16 855 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 856 container_const_reference<self_type>::assign (&it ());
Chris@16 857 it_ = it.it_;
Chris@16 858 return *this;
Chris@16 859 }
Chris@16 860
Chris@16 861 // Comparison
Chris@16 862 BOOST_UBLAS_INLINE
Chris@16 863 bool operator == (const const_iterator2 &it) const {
Chris@16 864 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 865 return it_ == it.it_;
Chris@16 866 }
Chris@16 867 BOOST_UBLAS_INLINE
Chris@16 868 bool operator < (const const_iterator2 &it) const {
Chris@16 869 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 870 return it_ < it.it_;
Chris@16 871 }
Chris@16 872
Chris@16 873 private:
Chris@16 874 const_subiterator_type it_;
Chris@16 875
Chris@16 876 friend class iterator2;
Chris@16 877 };
Chris@16 878 #endif
Chris@16 879
Chris@16 880 BOOST_UBLAS_INLINE
Chris@16 881 const_iterator2 begin2 () const {
Chris@16 882 return find2 (0, 0, 0);
Chris@16 883 }
Chris@16 884 BOOST_UBLAS_INLINE
Chris@16 885 const_iterator2 end2 () const {
Chris@16 886 return find2 (0, 0, size2_);
Chris@16 887 }
Chris@16 888
Chris@16 889 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 890 class iterator2:
Chris@16 891 public container_reference<matrix>,
Chris@16 892 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 893 iterator2, value_type> {
Chris@16 894 public:
Chris@16 895 typedef typename matrix::value_type value_type;
Chris@16 896 typedef typename matrix::difference_type difference_type;
Chris@16 897 typedef typename matrix::reference reference;
Chris@16 898 typedef typename matrix::pointer pointer;
Chris@16 899
Chris@16 900 typedef iterator1 dual_iterator_type;
Chris@16 901 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 902
Chris@16 903 // Construction and destruction
Chris@16 904 BOOST_UBLAS_INLINE
Chris@16 905 iterator2 ():
Chris@16 906 container_reference<self_type> (), it_ () {}
Chris@16 907 BOOST_UBLAS_INLINE
Chris@16 908 iterator2 (self_type &m, const subiterator_type &it):
Chris@16 909 container_reference<self_type> (m), it_ (it) {}
Chris@16 910
Chris@16 911 // Arithmetic
Chris@16 912 BOOST_UBLAS_INLINE
Chris@16 913 iterator2 &operator ++ () {
Chris@16 914 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 915 return *this;
Chris@16 916 }
Chris@16 917 BOOST_UBLAS_INLINE
Chris@16 918 iterator2 &operator -- () {
Chris@16 919 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 920 return *this;
Chris@16 921 }
Chris@16 922 BOOST_UBLAS_INLINE
Chris@16 923 iterator2 &operator += (difference_type n) {
Chris@16 924 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 925 return *this;
Chris@16 926 }
Chris@16 927 BOOST_UBLAS_INLINE
Chris@16 928 iterator2 &operator -= (difference_type n) {
Chris@16 929 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 930 return *this;
Chris@16 931 }
Chris@16 932 BOOST_UBLAS_INLINE
Chris@16 933 difference_type operator - (const iterator2 &it) const {
Chris@16 934 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 935 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 936 }
Chris@16 937
Chris@16 938 // Dereference
Chris@16 939 BOOST_UBLAS_INLINE
Chris@16 940 reference operator * () const {
Chris@16 941 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 942 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 943 return *it_;
Chris@16 944 }
Chris@16 945 BOOST_UBLAS_INLINE
Chris@16 946 reference operator [] (difference_type n) const {
Chris@16 947 return *(*this + n);
Chris@16 948 }
Chris@16 949
Chris@16 950 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 951 BOOST_UBLAS_INLINE
Chris@16 952 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 953 typename self_type::
Chris@16 954 #endif
Chris@16 955 iterator1 begin () const {
Chris@16 956 self_type &m = (*this) ();
Chris@16 957 return m.find1 (1, 0, index2 ());
Chris@16 958 }
Chris@16 959 BOOST_UBLAS_INLINE
Chris@16 960 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 961 typename self_type::
Chris@16 962 #endif
Chris@16 963 iterator1 end () const {
Chris@16 964 self_type &m = (*this) ();
Chris@16 965 return m.find1 (1, m.size1 (), index2 ());
Chris@16 966 }
Chris@16 967 BOOST_UBLAS_INLINE
Chris@16 968 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 969 typename self_type::
Chris@16 970 #endif
Chris@16 971 reverse_iterator1 rbegin () const {
Chris@16 972 return reverse_iterator1 (end ());
Chris@16 973 }
Chris@16 974 BOOST_UBLAS_INLINE
Chris@16 975 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 976 typename self_type::
Chris@16 977 #endif
Chris@16 978 reverse_iterator1 rend () const {
Chris@16 979 return reverse_iterator1 (begin ());
Chris@16 980 }
Chris@16 981 #endif
Chris@16 982
Chris@16 983 // Indices
Chris@16 984 BOOST_UBLAS_INLINE
Chris@16 985 size_type index1 () const {
Chris@16 986 self_type &m = (*this) ();
Chris@16 987 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@16 988 }
Chris@16 989 BOOST_UBLAS_INLINE
Chris@16 990 size_type index2 () const {
Chris@16 991 self_type &m = (*this) ();
Chris@16 992 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@16 993 }
Chris@16 994
Chris@16 995 // Assignment
Chris@16 996 BOOST_UBLAS_INLINE
Chris@16 997 iterator2 &operator = (const iterator2 &it) {
Chris@16 998 container_reference<self_type>::assign (&it ());
Chris@16 999 it_ = it.it_;
Chris@16 1000 return *this;
Chris@16 1001 }
Chris@16 1002
Chris@16 1003 // Comparison
Chris@16 1004 BOOST_UBLAS_INLINE
Chris@16 1005 bool operator == (const iterator2 &it) const {
Chris@16 1006 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1007 return it_ == it.it_;
Chris@16 1008 }
Chris@16 1009 BOOST_UBLAS_INLINE
Chris@16 1010 bool operator < (const iterator2 &it) const {
Chris@16 1011 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1012 return it_ < it.it_;
Chris@16 1013 }
Chris@16 1014
Chris@16 1015 private:
Chris@16 1016 subiterator_type it_;
Chris@16 1017
Chris@16 1018 friend class const_iterator2;
Chris@16 1019 };
Chris@16 1020 #endif
Chris@16 1021
Chris@16 1022 BOOST_UBLAS_INLINE
Chris@16 1023 iterator2 begin2 () {
Chris@16 1024 return find2 (0, 0, 0);
Chris@16 1025 }
Chris@16 1026 BOOST_UBLAS_INLINE
Chris@16 1027 iterator2 end2 () {
Chris@16 1028 return find2 (0, 0, size2_);
Chris@16 1029 }
Chris@16 1030
Chris@16 1031 // Reverse iterators
Chris@16 1032
Chris@16 1033 BOOST_UBLAS_INLINE
Chris@16 1034 const_reverse_iterator1 rbegin1 () const {
Chris@16 1035 return const_reverse_iterator1 (end1 ());
Chris@16 1036 }
Chris@16 1037 BOOST_UBLAS_INLINE
Chris@16 1038 const_reverse_iterator1 rend1 () const {
Chris@16 1039 return const_reverse_iterator1 (begin1 ());
Chris@16 1040 }
Chris@16 1041
Chris@16 1042 BOOST_UBLAS_INLINE
Chris@16 1043 reverse_iterator1 rbegin1 () {
Chris@16 1044 return reverse_iterator1 (end1 ());
Chris@16 1045 }
Chris@16 1046 BOOST_UBLAS_INLINE
Chris@16 1047 reverse_iterator1 rend1 () {
Chris@16 1048 return reverse_iterator1 (begin1 ());
Chris@16 1049 }
Chris@16 1050
Chris@16 1051 BOOST_UBLAS_INLINE
Chris@16 1052 const_reverse_iterator2 rbegin2 () const {
Chris@16 1053 return const_reverse_iterator2 (end2 ());
Chris@16 1054 }
Chris@16 1055 BOOST_UBLAS_INLINE
Chris@16 1056 const_reverse_iterator2 rend2 () const {
Chris@16 1057 return const_reverse_iterator2 (begin2 ());
Chris@16 1058 }
Chris@16 1059
Chris@16 1060 BOOST_UBLAS_INLINE
Chris@16 1061 reverse_iterator2 rbegin2 () {
Chris@16 1062 return reverse_iterator2 (end2 ());
Chris@16 1063 }
Chris@16 1064 BOOST_UBLAS_INLINE
Chris@16 1065 reverse_iterator2 rend2 () {
Chris@16 1066 return reverse_iterator2 (begin2 ());
Chris@16 1067 }
Chris@16 1068
Chris@16 1069 // Serialization
Chris@16 1070 template<class Archive>
Chris@16 1071 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 1072
Chris@16 1073 // we need to copy to a collection_size_type to get a portable
Chris@16 1074 // and efficient serialization
Chris@16 1075 serialization::collection_size_type s1 (size1_);
Chris@16 1076 serialization::collection_size_type s2 (size2_);
Chris@16 1077
Chris@16 1078 // serialize the sizes
Chris@16 1079 ar & serialization::make_nvp("size1",s1)
Chris@16 1080 & serialization::make_nvp("size2",s2);
Chris@16 1081
Chris@16 1082 // copy the values back if loading
Chris@16 1083 if (Archive::is_loading::value) {
Chris@16 1084 size1_ = s1;
Chris@16 1085 size2_ = s2;
Chris@16 1086 }
Chris@16 1087 ar & serialization::make_nvp("data",data_);
Chris@16 1088 }
Chris@16 1089
Chris@16 1090 private:
Chris@16 1091 size_type size1_;
Chris@16 1092 size_type size2_;
Chris@16 1093 array_type data_;
Chris@16 1094 };
Chris@16 1095
Chris@16 1096 /** \brief A dense matrix of values of type \c T with a variable size bounded to a maximum of \f$M\f$ by \f$N\f$.
Chris@16 1097 *
Chris@16 1098 * For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$m_{i,j}\f$ is mapped
Chris@16 1099 * to the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$(i + j.m)\f$-th element
Chris@16 1100 * of the container for column major orientation. Finally in a dense matrix all elements are represented in memory
Chris@16 1101 * in a contiguous chunk of memory.
Chris@16 1102 *
Chris@16 1103 * Orientation can be specified. Default is \c row_major
Chris@16 1104 * The default constructor creates the matrix with size \f$M\f$ by \f$N\f$. Elements are constructed by the storage
Chris@16 1105 * type \c bounded_array, which need not initialise their value.
Chris@16 1106 *
Chris@16 1107 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 1108 * \tparam M maximum and default number of rows (if not specified at construction)
Chris@16 1109 * \tparam N maximum and default number of columns (if not specified at construction)
Chris@16 1110 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
Chris@16 1111 */
Chris@16 1112 template<class T, std::size_t M, std::size_t N, class L>
Chris@16 1113 class bounded_matrix:
Chris@16 1114 public matrix<T, L, bounded_array<T, M * N> > {
Chris@16 1115
Chris@16 1116 typedef matrix<T, L, bounded_array<T, M * N> > matrix_type;
Chris@16 1117 public:
Chris@16 1118 typedef typename matrix_type::size_type size_type;
Chris@16 1119 static const size_type max_size1 = M;
Chris@16 1120 static const size_type max_size2 = N;
Chris@16 1121
Chris@16 1122 // Construction and destruction
Chris@16 1123 BOOST_UBLAS_INLINE
Chris@16 1124 bounded_matrix ():
Chris@16 1125 matrix_type (M, N) {}
Chris@16 1126 BOOST_UBLAS_INLINE
Chris@16 1127 bounded_matrix (size_type size1, size_type size2):
Chris@16 1128 matrix_type (size1, size2) {}
Chris@16 1129 BOOST_UBLAS_INLINE
Chris@16 1130 bounded_matrix (const bounded_matrix &m):
Chris@16 1131 matrix_type (m) {}
Chris@16 1132 template<class A2> // Allow matrix<T, L, bounded_array<M,N> > construction
Chris@16 1133 BOOST_UBLAS_INLINE
Chris@16 1134 bounded_matrix (const matrix<T, L, A2> &m):
Chris@16 1135 matrix_type (m) {}
Chris@16 1136 template<class AE>
Chris@16 1137 BOOST_UBLAS_INLINE
Chris@16 1138 bounded_matrix (const matrix_expression<AE> &ae):
Chris@16 1139 matrix_type (ae) {}
Chris@16 1140 BOOST_UBLAS_INLINE
Chris@16 1141 ~bounded_matrix () {}
Chris@16 1142
Chris@16 1143 // Assignment
Chris@16 1144 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
Chris@16 1145
Chris@16 1146 /*! @note "pass by value" the key idea to enable move semantics */
Chris@16 1147 BOOST_UBLAS_INLINE
Chris@16 1148 bounded_matrix &operator = (bounded_matrix m) {
Chris@16 1149 matrix_type::operator = (m);
Chris@16 1150 return *this;
Chris@16 1151 }
Chris@16 1152 #else
Chris@16 1153 BOOST_UBLAS_INLINE
Chris@16 1154 bounded_matrix &operator = (const bounded_matrix &m) {
Chris@16 1155 matrix_type::operator = (m);
Chris@16 1156 return *this;
Chris@16 1157 }
Chris@16 1158 #endif
Chris@16 1159 template<class L2, class A2> // Generic matrix assignment
Chris@16 1160 BOOST_UBLAS_INLINE
Chris@16 1161 bounded_matrix &operator = (const matrix<T, L2, A2> &m) {
Chris@16 1162 matrix_type::operator = (m);
Chris@16 1163 return *this;
Chris@16 1164 }
Chris@16 1165 template<class C> // Container assignment without temporary
Chris@16 1166 BOOST_UBLAS_INLINE
Chris@16 1167 bounded_matrix &operator = (const matrix_container<C> &m) {
Chris@16 1168 matrix_type::operator = (m);
Chris@16 1169 return *this;
Chris@16 1170 }
Chris@16 1171 template<class AE>
Chris@16 1172 BOOST_UBLAS_INLINE
Chris@16 1173 bounded_matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 1174 matrix_type::operator = (ae);
Chris@16 1175 return *this;
Chris@16 1176 }
Chris@16 1177 };
Chris@16 1178
Chris@16 1179 /** \brief A dense matrix of values of type \c T stored as a vector of vectors.
Chris@16 1180 *
Chris@16 1181 * Rows or columns are not stored into contiguous chunks of memory but data inside rows (or columns) are.
Chris@16 1182 * Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used.
Chris@16 1183 * The data is stored as a vector of vectors, meaning that rows or columns might not be stored into contiguous chunks
Chris@16 1184 * of memory. Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used.
Chris@16 1185 * The storage type defaults to \c unbounded_array<unbounded_array<T>> and orientation is \c row_major. It is \b not
Chris@16 1186 * required by the storage to initialize elements of the matrix. For a \f$(m \times n)\f$-dimensional matrix and
Chris@16 1187 * \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$m_{i,j}\f$ is mapped to the \f$(i.n + j)\f$-th element of the
Chris@16 1188 * container for row major orientation or the \f$(i + j.m)\f$-th element of the container for column major orientation.
Chris@16 1189 *
Chris@16 1190 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 1191 * \tparam L the storage organization. It can be either \c row_major or \c column_major. By default it is \c row_major
Chris@16 1192 * \tparam A the type of Storage array. By default, it is an \unbounded_array<unbounder_array<T>>
Chris@16 1193 */
Chris@16 1194 template<class T, class L, class A>
Chris@16 1195 class vector_of_vector:
Chris@16 1196 public matrix_container<vector_of_vector<T, L, A> > {
Chris@16 1197
Chris@16 1198 typedef T *pointer;
Chris@16 1199 typedef L layout_type;
Chris@16 1200 typedef vector_of_vector<T, L, A> self_type;
Chris@16 1201 public:
Chris@16 1202 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 1203 using matrix_container<self_type>::operator ();
Chris@16 1204 #endif
Chris@16 1205 typedef typename A::size_type size_type;
Chris@16 1206 typedef typename A::difference_type difference_type;
Chris@16 1207 typedef T value_type;
Chris@16 1208 typedef const T &const_reference;
Chris@16 1209 typedef T &reference;
Chris@16 1210 typedef A array_type;
Chris@16 1211 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 1212 typedef matrix_reference<self_type> closure_type;
Chris@16 1213 typedef vector<T, typename A::value_type> vector_temporary_type;
Chris@16 1214 typedef self_type matrix_temporary_type;
Chris@16 1215 typedef dense_tag storage_category;
Chris@16 1216 // This could be better for performance,
Chris@16 1217 // typedef typename unknown_orientation_tag orientation_category;
Chris@16 1218 // but others depend on the orientation information...
Chris@16 1219 typedef typename L::orientation_category orientation_category;
Chris@16 1220
Chris@16 1221 // Construction and destruction
Chris@16 1222 BOOST_UBLAS_INLINE
Chris@16 1223 vector_of_vector ():
Chris@16 1224 matrix_container<self_type> (),
Chris@16 1225 size1_ (0), size2_ (0), data_ (1) {}
Chris@16 1226 BOOST_UBLAS_INLINE
Chris@16 1227 vector_of_vector (size_type size1, size_type size2):
Chris@16 1228 matrix_container<self_type> (),
Chris@16 1229 size1_ (size1), size2_ (size2), data_ (1) {
Chris@16 1230 resize (size1, size2, true);
Chris@16 1231 }
Chris@16 1232 BOOST_UBLAS_INLINE
Chris@16 1233 vector_of_vector (const vector_of_vector &m):
Chris@16 1234 matrix_container<self_type> (),
Chris@16 1235 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
Chris@16 1236 template<class AE>
Chris@16 1237 BOOST_UBLAS_INLINE
Chris@16 1238 vector_of_vector (const matrix_expression<AE> &ae):
Chris@16 1239 matrix_container<self_type> (),
Chris@16 1240 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) {
Chris@16 1241 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
Chris@16 1242 data ()[k].resize (layout_type::size_m (size1_, size2_));
Chris@16 1243 matrix_assign<scalar_assign> (*this, ae);
Chris@16 1244 }
Chris@16 1245
Chris@16 1246 // Accessors
Chris@16 1247 BOOST_UBLAS_INLINE
Chris@16 1248 size_type size1 () const {
Chris@16 1249 return size1_;
Chris@16 1250 }
Chris@16 1251 BOOST_UBLAS_INLINE
Chris@16 1252 size_type size2 () const {
Chris@16 1253 return size2_;
Chris@16 1254 }
Chris@16 1255
Chris@16 1256 // Storage accessors
Chris@16 1257 BOOST_UBLAS_INLINE
Chris@16 1258 const array_type &data () const {
Chris@16 1259 return data_;
Chris@16 1260 }
Chris@16 1261 BOOST_UBLAS_INLINE
Chris@16 1262 array_type &data () {
Chris@16 1263 return data_;
Chris@16 1264 }
Chris@16 1265
Chris@16 1266 // Resizing
Chris@16 1267 BOOST_UBLAS_INLINE
Chris@16 1268 void resize (size_type size1, size_type size2, bool preserve = true) {
Chris@16 1269 size1_ = size1;
Chris@16 1270 size2_ = size2;
Chris@16 1271 if (preserve)
Chris@16 1272 data ().resize (layout_type::size_M (size1, size2) + 1, typename array_type::value_type ());
Chris@16 1273 else
Chris@16 1274 data ().resize (layout_type::size_M (size1, size2) + 1);
Chris@16 1275 for (size_type k = 0; k < layout_type::size_M (size1, size2); ++ k) {
Chris@16 1276 if (preserve)
Chris@16 1277 data () [k].resize (layout_type::size_m (size1, size2), value_type ());
Chris@16 1278 else
Chris@16 1279 data () [k].resize (layout_type::size_m (size1, size2));
Chris@16 1280 }
Chris@16 1281 }
Chris@16 1282
Chris@16 1283 // Element access
Chris@16 1284 BOOST_UBLAS_INLINE
Chris@16 1285 const_reference operator () (size_type i, size_type j) const {
Chris@16 1286 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
Chris@16 1287 }
Chris@16 1288 BOOST_UBLAS_INLINE
Chris@16 1289 reference at_element (size_type i, size_type j) {
Chris@16 1290 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
Chris@16 1291 }
Chris@16 1292 BOOST_UBLAS_INLINE
Chris@16 1293 reference operator () (size_type i, size_type j) {
Chris@16 1294 return at_element (i, j);
Chris@16 1295 }
Chris@16 1296
Chris@16 1297 // Element assignment
Chris@16 1298 BOOST_UBLAS_INLINE
Chris@16 1299 reference insert_element (size_type i, size_type j, const_reference t) {
Chris@16 1300 return (at_element (i, j) = t);
Chris@16 1301 }
Chris@16 1302 BOOST_UBLAS_INLINE
Chris@16 1303 void erase_element (size_type i, size_type j) {
Chris@16 1304 at_element (i, j) = value_type/*zero*/();
Chris@16 1305 }
Chris@16 1306
Chris@16 1307 // Zeroing
Chris@16 1308 BOOST_UBLAS_INLINE
Chris@16 1309 void clear () {
Chris@16 1310 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
Chris@16 1311 std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/());
Chris@16 1312 }
Chris@16 1313
Chris@16 1314 // Assignment
Chris@16 1315 BOOST_UBLAS_INLINE
Chris@16 1316 vector_of_vector &operator = (const vector_of_vector &m) {
Chris@16 1317 size1_ = m.size1_;
Chris@16 1318 size2_ = m.size2_;
Chris@16 1319 data () = m.data ();
Chris@16 1320 return *this;
Chris@16 1321 }
Chris@16 1322 BOOST_UBLAS_INLINE
Chris@16 1323 vector_of_vector &assign_temporary (vector_of_vector &m) {
Chris@16 1324 swap (m);
Chris@16 1325 return *this;
Chris@16 1326 }
Chris@16 1327 template<class AE>
Chris@16 1328 BOOST_UBLAS_INLINE
Chris@16 1329 vector_of_vector &operator = (const matrix_expression<AE> &ae) {
Chris@16 1330 self_type temporary (ae);
Chris@16 1331 return assign_temporary (temporary);
Chris@16 1332 }
Chris@16 1333 template<class C> // Container assignment without temporary
Chris@16 1334 BOOST_UBLAS_INLINE
Chris@16 1335 vector_of_vector &operator = (const matrix_container<C> &m) {
Chris@16 1336 resize (m ().size1 (), m ().size2 (), false);
Chris@16 1337 assign (m);
Chris@16 1338 return *this;
Chris@16 1339 }
Chris@16 1340 template<class AE>
Chris@16 1341 BOOST_UBLAS_INLINE
Chris@16 1342 vector_of_vector &assign (const matrix_expression<AE> &ae) {
Chris@16 1343 matrix_assign<scalar_assign> (*this, ae);
Chris@16 1344 return *this;
Chris@16 1345 }
Chris@16 1346 template<class AE>
Chris@16 1347 BOOST_UBLAS_INLINE
Chris@16 1348 vector_of_vector& operator += (const matrix_expression<AE> &ae) {
Chris@16 1349 self_type temporary (*this + ae);
Chris@16 1350 return assign_temporary (temporary);
Chris@16 1351 }
Chris@16 1352 template<class C> // Container assignment without temporary
Chris@16 1353 BOOST_UBLAS_INLINE
Chris@16 1354 vector_of_vector &operator += (const matrix_container<C> &m) {
Chris@16 1355 plus_assign (m);
Chris@16 1356 return *this;
Chris@16 1357 }
Chris@16 1358 template<class AE>
Chris@16 1359 BOOST_UBLAS_INLINE
Chris@16 1360 vector_of_vector &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 1361 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 1362 return *this;
Chris@16 1363 }
Chris@16 1364 template<class AE>
Chris@16 1365 BOOST_UBLAS_INLINE
Chris@16 1366 vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
Chris@16 1367 self_type temporary (*this - ae);
Chris@16 1368 return assign_temporary (temporary);
Chris@16 1369 }
Chris@16 1370 template<class C> // Container assignment without temporary
Chris@16 1371 BOOST_UBLAS_INLINE
Chris@16 1372 vector_of_vector &operator -= (const matrix_container<C> &m) {
Chris@16 1373 minus_assign (m);
Chris@16 1374 return *this;
Chris@16 1375 }
Chris@16 1376 template<class AE>
Chris@16 1377 BOOST_UBLAS_INLINE
Chris@16 1378 vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 1379 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 1380 return *this;
Chris@16 1381 }
Chris@16 1382 template<class AT>
Chris@16 1383 BOOST_UBLAS_INLINE
Chris@16 1384 vector_of_vector& operator *= (const AT &at) {
Chris@16 1385 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 1386 return *this;
Chris@16 1387 }
Chris@16 1388 template<class AT>
Chris@16 1389 BOOST_UBLAS_INLINE
Chris@16 1390 vector_of_vector& operator /= (const AT &at) {
Chris@16 1391 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 1392 return *this;
Chris@16 1393 }
Chris@16 1394
Chris@16 1395 // Swapping
Chris@16 1396 BOOST_UBLAS_INLINE
Chris@16 1397 void swap (vector_of_vector &m) {
Chris@16 1398 if (this != &m) {
Chris@16 1399 std::swap (size1_, m.size1_);
Chris@16 1400 std::swap (size2_, m.size2_);
Chris@16 1401 data ().swap (m.data ());
Chris@16 1402 }
Chris@16 1403 }
Chris@16 1404 BOOST_UBLAS_INLINE
Chris@16 1405 friend void swap (vector_of_vector &m1, vector_of_vector &m2) {
Chris@16 1406 m1.swap (m2);
Chris@16 1407 }
Chris@16 1408
Chris@16 1409 // Iterator types
Chris@16 1410 private:
Chris@16 1411 // Use the vector iterator
Chris@16 1412 typedef typename A::value_type::const_iterator const_subiterator_type;
Chris@16 1413 typedef typename A::value_type::iterator subiterator_type;
Chris@16 1414 public:
Chris@16 1415 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1416 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@16 1417 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@16 1418 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 1419 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 1420 #else
Chris@16 1421 class const_iterator1;
Chris@16 1422 class iterator1;
Chris@16 1423 class const_iterator2;
Chris@16 1424 class iterator2;
Chris@16 1425 #endif
Chris@16 1426 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 1427 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 1428 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 1429 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 1430
Chris@16 1431 // Element lookup
Chris@16 1432 BOOST_UBLAS_INLINE
Chris@16 1433 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
Chris@16 1434 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1435 return const_iterator1 (*this, i, j);
Chris@16 1436 #else
Chris@16 1437 return const_iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
Chris@16 1438 #endif
Chris@16 1439 }
Chris@16 1440 BOOST_UBLAS_INLINE
Chris@16 1441 iterator1 find1 (int /*rank*/, size_type i, size_type j) {
Chris@16 1442 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1443 return iterator1 (*this, i, j);
Chris@16 1444 #else
Chris@16 1445 return iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
Chris@16 1446 #endif
Chris@16 1447 }
Chris@16 1448 BOOST_UBLAS_INLINE
Chris@16 1449 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
Chris@16 1450 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1451 return const_iterator2 (*this, i, j);
Chris@16 1452 #else
Chris@16 1453 return const_iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
Chris@16 1454 #endif
Chris@16 1455 }
Chris@16 1456 BOOST_UBLAS_INLINE
Chris@16 1457 iterator2 find2 (int /*rank*/, size_type i, size_type j) {
Chris@16 1458 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1459 return iterator2 (*this, i, j);
Chris@16 1460 #else
Chris@16 1461 return iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
Chris@16 1462 #endif
Chris@16 1463 }
Chris@16 1464
Chris@16 1465
Chris@16 1466 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1467 class const_iterator1:
Chris@16 1468 public container_const_reference<vector_of_vector>,
Chris@16 1469 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 1470 const_iterator1, value_type> {
Chris@16 1471 public:
Chris@16 1472 typedef typename vector_of_vector::value_type value_type;
Chris@16 1473 typedef typename vector_of_vector::difference_type difference_type;
Chris@16 1474 typedef typename vector_of_vector::const_reference reference;
Chris@16 1475 typedef const typename vector_of_vector::pointer pointer;
Chris@16 1476
Chris@16 1477 typedef const_iterator2 dual_iterator_type;
Chris@16 1478 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 1479
Chris@16 1480 // Construction and destruction
Chris@16 1481 BOOST_UBLAS_INLINE
Chris@16 1482 const_iterator1 ():
Chris@16 1483 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
Chris@16 1484 BOOST_UBLAS_INLINE
Chris@16 1485 const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
Chris@16 1486 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
Chris@16 1487 BOOST_UBLAS_INLINE
Chris@16 1488 const_iterator1 (const iterator1 &it):
Chris@16 1489 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
Chris@16 1490
Chris@16 1491 // Arithmetic
Chris@16 1492 BOOST_UBLAS_INLINE
Chris@16 1493 const_iterator1 &operator ++ () {
Chris@16 1494 ++ i_;
Chris@16 1495 const self_type &m = (*this) ();
Chris@16 1496 if (layout_type::fast_i ())
Chris@16 1497 ++ it_;
Chris@16 1498 else
Chris@16 1499 it_ = m.find1 (1, i_, j_).it_;
Chris@16 1500 return *this;
Chris@16 1501 }
Chris@16 1502 BOOST_UBLAS_INLINE
Chris@16 1503 const_iterator1 &operator -- () {
Chris@16 1504 -- i_;
Chris@16 1505 const self_type &m = (*this) ();
Chris@16 1506 if (layout_type::fast_i ())
Chris@16 1507 -- it_;
Chris@16 1508 else
Chris@16 1509 it_ = m.find1 (1, i_, j_).it_;
Chris@16 1510 return *this;
Chris@16 1511 }
Chris@16 1512 BOOST_UBLAS_INLINE
Chris@16 1513 const_iterator1 &operator += (difference_type n) {
Chris@16 1514 i_ += n;
Chris@16 1515 const self_type &m = (*this) ();
Chris@16 1516 it_ = m.find1 (1, i_, j_).it_;
Chris@16 1517 return *this;
Chris@16 1518 }
Chris@16 1519 BOOST_UBLAS_INLINE
Chris@16 1520 const_iterator1 &operator -= (difference_type n) {
Chris@16 1521 i_ -= n;
Chris@16 1522 const self_type &m = (*this) ();
Chris@16 1523 it_ = m.find1 (1, i_, j_).it_;
Chris@16 1524 return *this;
Chris@16 1525 }
Chris@16 1526 BOOST_UBLAS_INLINE
Chris@16 1527 difference_type operator - (const const_iterator1 &it) const {
Chris@16 1528 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1529 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 1530 return index1 () - it.index1 ();
Chris@16 1531 }
Chris@16 1532
Chris@16 1533 // Dereference
Chris@16 1534 BOOST_UBLAS_INLINE
Chris@16 1535 const_reference operator * () const {
Chris@16 1536 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 1537 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 1538 return *it_;
Chris@16 1539 }
Chris@16 1540 BOOST_UBLAS_INLINE
Chris@16 1541 const_reference operator [] (difference_type n) const {
Chris@16 1542 return *(*this + n);
Chris@16 1543 }
Chris@16 1544
Chris@16 1545 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1546 BOOST_UBLAS_INLINE
Chris@16 1547 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1548 typename self_type::
Chris@16 1549 #endif
Chris@16 1550 const_iterator2 begin () const {
Chris@16 1551 const self_type &m = (*this) ();
Chris@16 1552 return m.find2 (1, index1 (), 0);
Chris@16 1553 }
Chris@16 1554 BOOST_UBLAS_INLINE
Chris@16 1555 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1556 typename self_type::
Chris@16 1557 #endif
Chris@16 1558 const_iterator2 end () const {
Chris@16 1559 const self_type &m = (*this) ();
Chris@16 1560 return m.find2 (1, index1 (), m.size2 ());
Chris@16 1561 }
Chris@16 1562 BOOST_UBLAS_INLINE
Chris@16 1563 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1564 typename self_type::
Chris@16 1565 #endif
Chris@16 1566 const_reverse_iterator2 rbegin () const {
Chris@16 1567 return const_reverse_iterator2 (end ());
Chris@16 1568 }
Chris@16 1569 BOOST_UBLAS_INLINE
Chris@16 1570 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1571 typename self_type::
Chris@16 1572 #endif
Chris@16 1573 const_reverse_iterator2 rend () const {
Chris@16 1574 return const_reverse_iterator2 (begin ());
Chris@16 1575 }
Chris@16 1576 #endif
Chris@16 1577
Chris@16 1578 // Indices
Chris@16 1579 BOOST_UBLAS_INLINE
Chris@16 1580 size_type index1 () const {
Chris@16 1581 return i_;
Chris@16 1582 }
Chris@16 1583 BOOST_UBLAS_INLINE
Chris@16 1584 size_type index2 () const {
Chris@16 1585 return j_;
Chris@16 1586 }
Chris@16 1587
Chris@16 1588 // Assignment
Chris@16 1589 BOOST_UBLAS_INLINE
Chris@16 1590 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 1591 container_const_reference<self_type>::assign (&it ());
Chris@16 1592 it_ = it.it_;
Chris@16 1593 return *this;
Chris@16 1594 }
Chris@16 1595
Chris@16 1596 // Comparison
Chris@16 1597 BOOST_UBLAS_INLINE
Chris@16 1598 bool operator == (const const_iterator1 &it) const {
Chris@16 1599 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1600 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 1601 return it_ == it.it_;
Chris@16 1602 }
Chris@16 1603 BOOST_UBLAS_INLINE
Chris@16 1604 bool operator < (const const_iterator1 &it) const {
Chris@16 1605 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1606 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 1607 return it_ < it.it_;
Chris@16 1608 }
Chris@16 1609
Chris@16 1610 private:
Chris@16 1611 size_type i_;
Chris@16 1612 size_type j_;
Chris@16 1613 const_subiterator_type it_;
Chris@16 1614
Chris@16 1615 friend class iterator1;
Chris@16 1616 };
Chris@16 1617 #endif
Chris@16 1618
Chris@16 1619 BOOST_UBLAS_INLINE
Chris@16 1620 const_iterator1 begin1 () const {
Chris@16 1621 return find1 (0, 0, 0);
Chris@16 1622 }
Chris@16 1623 BOOST_UBLAS_INLINE
Chris@16 1624 const_iterator1 end1 () const {
Chris@16 1625 return find1 (0, size1_, 0);
Chris@16 1626 }
Chris@16 1627
Chris@16 1628 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1629 class iterator1:
Chris@16 1630 public container_reference<vector_of_vector>,
Chris@16 1631 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 1632 iterator1, value_type> {
Chris@16 1633 public:
Chris@16 1634 typedef typename vector_of_vector::value_type value_type;
Chris@16 1635 typedef typename vector_of_vector::difference_type difference_type;
Chris@16 1636 typedef typename vector_of_vector::reference reference;
Chris@16 1637 typedef typename vector_of_vector::pointer pointer;
Chris@16 1638
Chris@16 1639 typedef iterator2 dual_iterator_type;
Chris@16 1640 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 1641
Chris@16 1642 // Construction and destruction
Chris@16 1643 BOOST_UBLAS_INLINE
Chris@16 1644 iterator1 ():
Chris@16 1645 container_reference<self_type> (), i_ (), j_ (), it_ () {}
Chris@16 1646 BOOST_UBLAS_INLINE
Chris@16 1647 iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it):
Chris@16 1648 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
Chris@16 1649
Chris@16 1650 // Arithmetic
Chris@16 1651 BOOST_UBLAS_INLINE
Chris@16 1652 iterator1 &operator ++ () {
Chris@16 1653 ++ i_;
Chris@16 1654 self_type &m = (*this) ();
Chris@16 1655 if (layout_type::fast_i ())
Chris@16 1656 ++ it_;
Chris@16 1657 else
Chris@16 1658 it_ = m.find1 (1, i_, j_).it_;
Chris@16 1659 return *this;
Chris@16 1660 }
Chris@16 1661 BOOST_UBLAS_INLINE
Chris@16 1662 iterator1 &operator -- () {
Chris@16 1663 -- i_;
Chris@16 1664 self_type &m = (*this) ();
Chris@16 1665 if (layout_type::fast_i ())
Chris@16 1666 -- it_;
Chris@16 1667 else
Chris@16 1668 it_ = m.find1 (1, i_, j_).it_;
Chris@16 1669 return *this;
Chris@16 1670 }
Chris@16 1671 BOOST_UBLAS_INLINE
Chris@16 1672 iterator1 &operator += (difference_type n) {
Chris@16 1673 i_ += n;
Chris@16 1674 self_type &m = (*this) ();
Chris@16 1675 it_ = m.find1 (1, i_, j_).it_;
Chris@16 1676 return *this;
Chris@16 1677 }
Chris@16 1678 BOOST_UBLAS_INLINE
Chris@16 1679 iterator1 &operator -= (difference_type n) {
Chris@16 1680 i_ -= n;
Chris@16 1681 self_type &m = (*this) ();
Chris@16 1682 it_ = m.find1 (1, i_, j_).it_;
Chris@16 1683 return *this;
Chris@16 1684 }
Chris@16 1685 BOOST_UBLAS_INLINE
Chris@16 1686 difference_type operator - (const iterator1 &it) const {
Chris@16 1687 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1688 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 1689 return index1 () - it.index1 ();
Chris@16 1690 }
Chris@16 1691
Chris@16 1692 // Dereference
Chris@16 1693 BOOST_UBLAS_INLINE
Chris@16 1694 reference operator * () const {
Chris@16 1695 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 1696 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 1697 return *it_;
Chris@16 1698 }
Chris@16 1699 BOOST_UBLAS_INLINE
Chris@16 1700 reference operator [] (difference_type n) const {
Chris@16 1701 return *(*this + n);
Chris@16 1702 }
Chris@16 1703
Chris@16 1704 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1705 BOOST_UBLAS_INLINE
Chris@16 1706 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1707 typename self_type::
Chris@16 1708 #endif
Chris@16 1709 iterator2 begin () const {
Chris@16 1710 self_type &m = (*this) ();
Chris@16 1711 return m.find2 (1, index1 (), 0);
Chris@16 1712 }
Chris@16 1713 BOOST_UBLAS_INLINE
Chris@16 1714 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1715 typename self_type::
Chris@16 1716 #endif
Chris@16 1717 iterator2 end () const {
Chris@16 1718 self_type &m = (*this) ();
Chris@16 1719 return m.find2 (1, index1 (), m.size2 ());
Chris@16 1720 }
Chris@16 1721 BOOST_UBLAS_INLINE
Chris@16 1722 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1723 typename self_type::
Chris@16 1724 #endif
Chris@16 1725 reverse_iterator2 rbegin () const {
Chris@16 1726 return reverse_iterator2 (end ());
Chris@16 1727 }
Chris@16 1728 BOOST_UBLAS_INLINE
Chris@16 1729 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1730 typename self_type::
Chris@16 1731 #endif
Chris@16 1732 reverse_iterator2 rend () const {
Chris@16 1733 return reverse_iterator2 (begin ());
Chris@16 1734 }
Chris@16 1735 #endif
Chris@16 1736
Chris@16 1737 // Indices
Chris@16 1738 BOOST_UBLAS_INLINE
Chris@16 1739 size_type index1 () const {
Chris@16 1740 return i_;
Chris@16 1741 }
Chris@16 1742 BOOST_UBLAS_INLINE
Chris@16 1743 size_type index2 () const {
Chris@16 1744 return j_;
Chris@16 1745 }
Chris@16 1746
Chris@16 1747 // Assignment
Chris@16 1748 BOOST_UBLAS_INLINE
Chris@16 1749 iterator1 &operator = (const iterator1 &it) {
Chris@16 1750 container_reference<self_type>::assign (&it ());
Chris@16 1751 it_ = it.it_;
Chris@16 1752 return *this;
Chris@16 1753 }
Chris@16 1754
Chris@16 1755 // Comparison
Chris@16 1756 BOOST_UBLAS_INLINE
Chris@16 1757 bool operator == (const iterator1 &it) const {
Chris@16 1758 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1759 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 1760 return it_ == it.it_;
Chris@16 1761 }
Chris@16 1762 BOOST_UBLAS_INLINE
Chris@16 1763 bool operator < (const iterator1 &it) const {
Chris@16 1764 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1765 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 1766 return it_ < it.it_;
Chris@16 1767 }
Chris@16 1768
Chris@16 1769 private:
Chris@16 1770 size_type i_;
Chris@16 1771 size_type j_;
Chris@16 1772 subiterator_type it_;
Chris@16 1773
Chris@16 1774 friend class const_iterator1;
Chris@16 1775 };
Chris@16 1776 #endif
Chris@16 1777
Chris@16 1778 BOOST_UBLAS_INLINE
Chris@16 1779 iterator1 begin1 () {
Chris@16 1780 return find1 (0, 0, 0);
Chris@16 1781 }
Chris@16 1782 BOOST_UBLAS_INLINE
Chris@16 1783 iterator1 end1 () {
Chris@16 1784 return find1 (0, size1_, 0);
Chris@16 1785 }
Chris@16 1786
Chris@16 1787 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1788 class const_iterator2:
Chris@16 1789 public container_const_reference<vector_of_vector>,
Chris@16 1790 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 1791 const_iterator2, value_type> {
Chris@16 1792 public:
Chris@16 1793 typedef typename vector_of_vector::value_type value_type;
Chris@16 1794 typedef typename vector_of_vector::difference_type difference_type;
Chris@16 1795 typedef typename vector_of_vector::const_reference reference;
Chris@16 1796 typedef const typename vector_of_vector::pointer pointer;
Chris@16 1797
Chris@16 1798 typedef const_iterator1 dual_iterator_type;
Chris@16 1799 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 1800
Chris@16 1801 // Construction and destruction
Chris@16 1802 BOOST_UBLAS_INLINE
Chris@16 1803 const_iterator2 ():
Chris@16 1804 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
Chris@16 1805 BOOST_UBLAS_INLINE
Chris@16 1806 const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
Chris@16 1807 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
Chris@16 1808 BOOST_UBLAS_INLINE
Chris@16 1809 const_iterator2 (const iterator2 &it):
Chris@16 1810 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
Chris@16 1811
Chris@16 1812 // Arithmetic
Chris@16 1813 BOOST_UBLAS_INLINE
Chris@16 1814 const_iterator2 &operator ++ () {
Chris@16 1815 ++ j_;
Chris@16 1816 const self_type &m = (*this) ();
Chris@16 1817 if (layout_type::fast_j ())
Chris@16 1818 ++ it_;
Chris@16 1819 else
Chris@16 1820 it_ = m.find2 (1, i_, j_).it_;
Chris@16 1821 return *this;
Chris@16 1822 }
Chris@16 1823 BOOST_UBLAS_INLINE
Chris@16 1824 const_iterator2 &operator -- () {
Chris@16 1825 -- j_;
Chris@16 1826 const self_type &m = (*this) ();
Chris@16 1827 if (layout_type::fast_j ())
Chris@16 1828 -- it_;
Chris@16 1829 else
Chris@16 1830 it_ = m.find2 (1, i_, j_).it_;
Chris@16 1831 return *this;
Chris@16 1832 }
Chris@16 1833 BOOST_UBLAS_INLINE
Chris@16 1834 const_iterator2 &operator += (difference_type n) {
Chris@16 1835 j_ += n;
Chris@16 1836 const self_type &m = (*this) ();
Chris@16 1837 it_ = m.find2 (1, i_, j_).it_;
Chris@16 1838 return *this;
Chris@16 1839 }
Chris@16 1840 BOOST_UBLAS_INLINE
Chris@16 1841 const_iterator2 &operator -= (difference_type n) {
Chris@16 1842 j_ -= n;
Chris@16 1843 const self_type &m = (*this) ();
Chris@16 1844 it_ = m.find2 (1, i_, j_).it_;
Chris@16 1845 return *this;
Chris@16 1846 }
Chris@16 1847 BOOST_UBLAS_INLINE
Chris@16 1848 difference_type operator - (const const_iterator2 &it) const {
Chris@16 1849 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1850 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 1851 return index2 () - it.index2 ();
Chris@16 1852 }
Chris@16 1853
Chris@16 1854 // Dereference
Chris@16 1855 BOOST_UBLAS_INLINE
Chris@16 1856 const_reference operator * () const {
Chris@16 1857 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 1858 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 1859 return *it_;
Chris@16 1860 }
Chris@16 1861 BOOST_UBLAS_INLINE
Chris@16 1862 const_reference operator [] (difference_type n) const {
Chris@16 1863 return *(*this + n);
Chris@16 1864 }
Chris@16 1865
Chris@16 1866 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1867 BOOST_UBLAS_INLINE
Chris@16 1868 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1869 typename self_type::
Chris@16 1870 #endif
Chris@16 1871 const_iterator1 begin () const {
Chris@16 1872 const self_type &m = (*this) ();
Chris@16 1873 return m.find1 (1, 0, index2 ());
Chris@16 1874 }
Chris@16 1875 BOOST_UBLAS_INLINE
Chris@16 1876 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1877 typename self_type::
Chris@16 1878 #endif
Chris@16 1879 const_iterator1 end () const {
Chris@16 1880 const self_type &m = (*this) ();
Chris@16 1881 return m.find1 (1, m.size1 (), index2 ());
Chris@16 1882 }
Chris@16 1883 BOOST_UBLAS_INLINE
Chris@16 1884 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1885 typename self_type::
Chris@16 1886 #endif
Chris@16 1887 const_reverse_iterator1 rbegin () const {
Chris@16 1888 return const_reverse_iterator1 (end ());
Chris@16 1889 }
Chris@16 1890 BOOST_UBLAS_INLINE
Chris@16 1891 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1892 typename self_type::
Chris@16 1893 #endif
Chris@16 1894 const_reverse_iterator1 rend () const {
Chris@16 1895 return const_reverse_iterator1 (begin ());
Chris@16 1896 }
Chris@16 1897 #endif
Chris@16 1898
Chris@16 1899 // Indices
Chris@16 1900 BOOST_UBLAS_INLINE
Chris@16 1901 size_type index1 () const {
Chris@16 1902 return i_;
Chris@16 1903 }
Chris@16 1904 BOOST_UBLAS_INLINE
Chris@16 1905 size_type index2 () const {
Chris@16 1906 return j_;
Chris@16 1907 }
Chris@16 1908
Chris@16 1909 // Assignment
Chris@16 1910 BOOST_UBLAS_INLINE
Chris@16 1911 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 1912 container_const_reference<self_type>::assign (&it ());
Chris@16 1913 it_ = it.it_;
Chris@16 1914 return *this;
Chris@16 1915 }
Chris@16 1916
Chris@16 1917 // Comparison
Chris@16 1918 BOOST_UBLAS_INLINE
Chris@16 1919 bool operator == (const const_iterator2 &it) const {
Chris@16 1920 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1921 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 1922 return it_ == it.it_;
Chris@16 1923 }
Chris@16 1924 BOOST_UBLAS_INLINE
Chris@16 1925 bool operator < (const const_iterator2 &it) const {
Chris@16 1926 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1927 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 1928 return it_ < it.it_;
Chris@16 1929 }
Chris@16 1930
Chris@16 1931 private:
Chris@16 1932 size_type i_;
Chris@16 1933 size_type j_;
Chris@16 1934 const_subiterator_type it_;
Chris@16 1935
Chris@16 1936 friend class iterator2;
Chris@16 1937 };
Chris@16 1938 #endif
Chris@16 1939
Chris@16 1940 BOOST_UBLAS_INLINE
Chris@16 1941 const_iterator2 begin2 () const {
Chris@16 1942 return find2 (0, 0, 0);
Chris@16 1943 }
Chris@16 1944 BOOST_UBLAS_INLINE
Chris@16 1945 const_iterator2 end2 () const {
Chris@16 1946 return find2 (0, 0, size2_);
Chris@16 1947 }
Chris@16 1948
Chris@16 1949 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1950 class iterator2:
Chris@16 1951 public container_reference<vector_of_vector>,
Chris@16 1952 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 1953 iterator2, value_type> {
Chris@16 1954 public:
Chris@16 1955 typedef typename vector_of_vector::value_type value_type;
Chris@16 1956 typedef typename vector_of_vector::difference_type difference_type;
Chris@16 1957 typedef typename vector_of_vector::reference reference;
Chris@16 1958 typedef typename vector_of_vector::pointer pointer;
Chris@16 1959
Chris@16 1960 typedef iterator1 dual_iterator_type;
Chris@16 1961 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 1962
Chris@16 1963 // Construction and destruction
Chris@16 1964 BOOST_UBLAS_INLINE
Chris@16 1965 iterator2 ():
Chris@16 1966 container_reference<self_type> (), i_ (), j_ (), it_ () {}
Chris@16 1967 BOOST_UBLAS_INLINE
Chris@16 1968 iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it):
Chris@16 1969 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
Chris@16 1970
Chris@16 1971 // Arithmetic
Chris@16 1972 BOOST_UBLAS_INLINE
Chris@16 1973 iterator2 &operator ++ () {
Chris@16 1974 ++ j_;
Chris@16 1975 self_type &m = (*this) ();
Chris@16 1976 if (layout_type::fast_j ())
Chris@16 1977 ++ it_;
Chris@16 1978 else
Chris@16 1979 it_ = m.find2 (1, i_, j_).it_;
Chris@16 1980 return *this;
Chris@16 1981 }
Chris@16 1982 BOOST_UBLAS_INLINE
Chris@16 1983 iterator2 &operator -- () {
Chris@16 1984 -- j_;
Chris@16 1985 self_type &m = (*this) ();
Chris@16 1986 if (layout_type::fast_j ())
Chris@16 1987 -- it_;
Chris@16 1988 else
Chris@16 1989 it_ = m.find2 (1, i_, j_).it_;
Chris@16 1990 return *this;
Chris@16 1991 }
Chris@16 1992 BOOST_UBLAS_INLINE
Chris@16 1993 iterator2 &operator += (difference_type n) {
Chris@16 1994 j_ += n;
Chris@16 1995 self_type &m = (*this) ();
Chris@16 1996 it_ = m.find2 (1, i_, j_).it_;
Chris@16 1997 return *this;
Chris@16 1998 }
Chris@16 1999 BOOST_UBLAS_INLINE
Chris@16 2000 iterator2 &operator -= (difference_type n) {
Chris@16 2001 j_ -= n;
Chris@16 2002 self_type &m = (*this) ();
Chris@16 2003 it_ = m.find2 (1, i_, j_).it_;
Chris@16 2004 return *this;
Chris@16 2005 }
Chris@16 2006 BOOST_UBLAS_INLINE
Chris@16 2007 difference_type operator - (const iterator2 &it) const {
Chris@16 2008 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2009 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 2010 return index2 () - it.index2 ();
Chris@16 2011 }
Chris@16 2012
Chris@16 2013 // Dereference
Chris@16 2014 BOOST_UBLAS_INLINE
Chris@16 2015 reference operator * () const {
Chris@16 2016 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 2017 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 2018 return *it_;
Chris@16 2019 }
Chris@16 2020 BOOST_UBLAS_INLINE
Chris@16 2021 reference operator [] (difference_type n) const {
Chris@16 2022 return *(*this + n);
Chris@16 2023 }
Chris@16 2024
Chris@16 2025 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2026 BOOST_UBLAS_INLINE
Chris@16 2027 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2028 typename self_type::
Chris@16 2029 #endif
Chris@16 2030 iterator1 begin () const {
Chris@16 2031 self_type &m = (*this) ();
Chris@16 2032 return m.find1 (1, 0, index2 ());
Chris@16 2033 }
Chris@16 2034 BOOST_UBLAS_INLINE
Chris@16 2035 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2036 typename self_type::
Chris@16 2037 #endif
Chris@16 2038 iterator1 end () const {
Chris@16 2039 self_type &m = (*this) ();
Chris@16 2040 return m.find1 (1, m.size1 (), index2 ());
Chris@16 2041 }
Chris@16 2042 BOOST_UBLAS_INLINE
Chris@16 2043 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2044 typename self_type::
Chris@16 2045 #endif
Chris@16 2046 reverse_iterator1 rbegin () const {
Chris@16 2047 return reverse_iterator1 (end ());
Chris@16 2048 }
Chris@16 2049 BOOST_UBLAS_INLINE
Chris@16 2050 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2051 typename self_type::
Chris@16 2052 #endif
Chris@16 2053 reverse_iterator1 rend () const {
Chris@16 2054 return reverse_iterator1 (begin ());
Chris@16 2055 }
Chris@16 2056 #endif
Chris@16 2057
Chris@16 2058 // Indices
Chris@16 2059 BOOST_UBLAS_INLINE
Chris@16 2060 size_type index1 () const {
Chris@16 2061 return i_;
Chris@16 2062 }
Chris@16 2063 BOOST_UBLAS_INLINE
Chris@16 2064 size_type index2 () const {
Chris@16 2065 return j_;
Chris@16 2066 }
Chris@16 2067
Chris@16 2068 // Assignment
Chris@16 2069 BOOST_UBLAS_INLINE
Chris@16 2070 iterator2 &operator = (const iterator2 &it) {
Chris@16 2071 container_reference<self_type>::assign (&it ());
Chris@16 2072 it_ = it.it_;
Chris@16 2073 return *this;
Chris@16 2074 }
Chris@16 2075
Chris@16 2076 // Comparison
Chris@16 2077 BOOST_UBLAS_INLINE
Chris@16 2078 bool operator == (const iterator2 &it) const {
Chris@16 2079 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2080 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 2081 return it_ == it.it_;
Chris@16 2082 }
Chris@16 2083 BOOST_UBLAS_INLINE
Chris@16 2084 bool operator < (const iterator2 &it) const {
Chris@16 2085 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2086 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 2087 return it_ < it.it_;
Chris@16 2088 }
Chris@16 2089
Chris@16 2090 private:
Chris@16 2091 size_type i_;
Chris@16 2092 size_type j_;
Chris@16 2093 subiterator_type it_;
Chris@16 2094
Chris@16 2095 friend class const_iterator2;
Chris@16 2096 };
Chris@16 2097 #endif
Chris@16 2098
Chris@16 2099 BOOST_UBLAS_INLINE
Chris@16 2100 iterator2 begin2 () {
Chris@16 2101 return find2 (0, 0, 0);
Chris@16 2102 }
Chris@16 2103 BOOST_UBLAS_INLINE
Chris@16 2104 iterator2 end2 () {
Chris@16 2105 return find2 (0, 0, size2_);
Chris@16 2106 }
Chris@16 2107
Chris@16 2108 // Reverse iterators
Chris@16 2109
Chris@16 2110 BOOST_UBLAS_INLINE
Chris@16 2111 const_reverse_iterator1 rbegin1 () const {
Chris@16 2112 return const_reverse_iterator1 (end1 ());
Chris@16 2113 }
Chris@16 2114 BOOST_UBLAS_INLINE
Chris@16 2115 const_reverse_iterator1 rend1 () const {
Chris@16 2116 return const_reverse_iterator1 (begin1 ());
Chris@16 2117 }
Chris@16 2118
Chris@16 2119 BOOST_UBLAS_INLINE
Chris@16 2120 reverse_iterator1 rbegin1 () {
Chris@16 2121 return reverse_iterator1 (end1 ());
Chris@16 2122 }
Chris@16 2123 BOOST_UBLAS_INLINE
Chris@16 2124 reverse_iterator1 rend1 () {
Chris@16 2125 return reverse_iterator1 (begin1 ());
Chris@16 2126 }
Chris@16 2127
Chris@16 2128 BOOST_UBLAS_INLINE
Chris@16 2129 const_reverse_iterator2 rbegin2 () const {
Chris@16 2130 return const_reverse_iterator2 (end2 ());
Chris@16 2131 }
Chris@16 2132 BOOST_UBLAS_INLINE
Chris@16 2133 const_reverse_iterator2 rend2 () const {
Chris@16 2134 return const_reverse_iterator2 (begin2 ());
Chris@16 2135 }
Chris@16 2136
Chris@16 2137 BOOST_UBLAS_INLINE
Chris@16 2138 reverse_iterator2 rbegin2 () {
Chris@16 2139 return reverse_iterator2 (end2 ());
Chris@16 2140 }
Chris@16 2141 BOOST_UBLAS_INLINE
Chris@16 2142 reverse_iterator2 rend2 () {
Chris@16 2143 return reverse_iterator2 (begin2 ());
Chris@16 2144 }
Chris@16 2145
Chris@16 2146 // Serialization
Chris@16 2147 template<class Archive>
Chris@16 2148 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 2149
Chris@16 2150 // we need to copy to a collection_size_type to get a portable
Chris@16 2151 // and efficient serialization
Chris@16 2152 serialization::collection_size_type s1 (size1_);
Chris@16 2153 serialization::collection_size_type s2 (size2_);
Chris@16 2154
Chris@16 2155 // serialize the sizes
Chris@16 2156 ar & serialization::make_nvp("size1",s1)
Chris@16 2157 & serialization::make_nvp("size2",s2);
Chris@16 2158
Chris@16 2159 // copy the values back if loading
Chris@16 2160 if (Archive::is_loading::value) {
Chris@16 2161 size1_ = s1;
Chris@16 2162 size2_ = s2;
Chris@16 2163 }
Chris@16 2164 ar & serialization::make_nvp("data",data_);
Chris@16 2165 }
Chris@16 2166
Chris@16 2167 private:
Chris@16 2168 size_type size1_;
Chris@16 2169 size_type size2_;
Chris@16 2170 array_type data_;
Chris@16 2171 };
Chris@16 2172
Chris@16 2173
Chris@16 2174 /** \brief A matrix with all values of type \c T equal to zero
Chris@16 2175 *
Chris@16 2176 * Changing values does not affect the matrix, however assigning it to a normal matrix will put zero
Chris@16 2177 * everywhere in the target matrix. All accesses are constant time, due to the trivial value.
Chris@16 2178 *
Chris@16 2179 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 2180 * \tparam ALLOC an allocator for storing the zero element. By default, a standar allocator is used.
Chris@16 2181 */
Chris@16 2182 template<class T, class ALLOC>
Chris@16 2183 class zero_matrix:
Chris@16 2184 public matrix_container<zero_matrix<T, ALLOC> > {
Chris@16 2185
Chris@16 2186 typedef const T *const_pointer;
Chris@16 2187 typedef zero_matrix<T, ALLOC> self_type;
Chris@16 2188 public:
Chris@16 2189 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 2190 using matrix_container<self_type>::operator ();
Chris@16 2191 #endif
Chris@16 2192 typedef typename ALLOC::size_type size_type;
Chris@16 2193 typedef typename ALLOC::difference_type difference_type;
Chris@16 2194 typedef T value_type;
Chris@16 2195 typedef const T &const_reference;
Chris@16 2196 typedef T &reference;
Chris@16 2197 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 2198 typedef matrix_reference<self_type> closure_type;
Chris@16 2199 typedef sparse_tag storage_category;
Chris@16 2200 typedef unknown_orientation_tag orientation_category;
Chris@16 2201
Chris@16 2202 // Construction and destruction
Chris@16 2203 BOOST_UBLAS_INLINE
Chris@16 2204 zero_matrix ():
Chris@16 2205 matrix_container<self_type> (),
Chris@16 2206 size1_ (0), size2_ (0) {}
Chris@16 2207 BOOST_UBLAS_INLINE
Chris@16 2208 zero_matrix (size_type size):
Chris@16 2209 matrix_container<self_type> (),
Chris@16 2210 size1_ (size), size2_ (size) {}
Chris@16 2211 BOOST_UBLAS_INLINE
Chris@16 2212 zero_matrix (size_type size1, size_type size2):
Chris@16 2213 matrix_container<self_type> (),
Chris@16 2214 size1_ (size1), size2_ (size2) {}
Chris@16 2215 BOOST_UBLAS_INLINE
Chris@16 2216 zero_matrix (const zero_matrix &m):
Chris@16 2217 matrix_container<self_type> (),
Chris@16 2218 size1_ (m.size1_), size2_ (m.size2_) {}
Chris@16 2219
Chris@16 2220 // Accessors
Chris@16 2221 BOOST_UBLAS_INLINE
Chris@16 2222 size_type size1 () const {
Chris@16 2223 return size1_;
Chris@16 2224 }
Chris@16 2225 BOOST_UBLAS_INLINE
Chris@16 2226 size_type size2 () const {
Chris@16 2227 return size2_;
Chris@16 2228 }
Chris@16 2229
Chris@16 2230 // Resizing
Chris@16 2231 BOOST_UBLAS_INLINE
Chris@16 2232 void resize (size_type size, bool preserve = true) {
Chris@16 2233 size1_ = size;
Chris@16 2234 size2_ = size;
Chris@16 2235 }
Chris@16 2236 BOOST_UBLAS_INLINE
Chris@16 2237 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
Chris@16 2238 size1_ = size1;
Chris@16 2239 size2_ = size2;
Chris@16 2240 }
Chris@16 2241
Chris@16 2242 // Element access
Chris@16 2243 BOOST_UBLAS_INLINE
Chris@16 2244 const_reference operator () (size_type /* i */, size_type /* j */) const {
Chris@16 2245 return zero_;
Chris@16 2246 }
Chris@16 2247
Chris@16 2248 // Assignment
Chris@16 2249 BOOST_UBLAS_INLINE
Chris@16 2250 zero_matrix &operator = (const zero_matrix &m) {
Chris@16 2251 size1_ = m.size1_;
Chris@16 2252 size2_ = m.size2_;
Chris@16 2253 return *this;
Chris@16 2254 }
Chris@16 2255 BOOST_UBLAS_INLINE
Chris@16 2256 zero_matrix &assign_temporary (zero_matrix &m) {
Chris@16 2257 swap (m);
Chris@16 2258 return *this;
Chris@16 2259 }
Chris@16 2260
Chris@16 2261 // Swapping
Chris@16 2262 BOOST_UBLAS_INLINE
Chris@16 2263 void swap (zero_matrix &m) {
Chris@16 2264 if (this != &m) {
Chris@16 2265 std::swap (size1_, m.size1_);
Chris@16 2266 std::swap (size2_, m.size2_);
Chris@16 2267 }
Chris@16 2268 }
Chris@16 2269 BOOST_UBLAS_INLINE
Chris@16 2270 friend void swap (zero_matrix &m1, zero_matrix &m2) {
Chris@16 2271 m1.swap (m2);
Chris@16 2272 }
Chris@16 2273
Chris@16 2274 // Iterator types
Chris@16 2275 public:
Chris@16 2276 class const_iterator1;
Chris@16 2277 class const_iterator2;
Chris@16 2278 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 2279 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 2280
Chris@16 2281 // Element lookup
Chris@16 2282 BOOST_UBLAS_INLINE
Chris@16 2283 const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
Chris@16 2284 return const_iterator1 (*this);
Chris@16 2285 }
Chris@16 2286 BOOST_UBLAS_INLINE
Chris@16 2287 const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
Chris@16 2288 return const_iterator2 (*this);
Chris@16 2289 }
Chris@16 2290
Chris@16 2291 class const_iterator1:
Chris@16 2292 public container_const_reference<zero_matrix>,
Chris@16 2293 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
Chris@16 2294 const_iterator1, value_type> {
Chris@16 2295 public:
Chris@16 2296 typedef typename zero_matrix::value_type value_type;
Chris@16 2297 typedef typename zero_matrix::difference_type difference_type;
Chris@16 2298 typedef typename zero_matrix::const_reference reference;
Chris@16 2299 typedef typename zero_matrix::const_pointer pointer;
Chris@16 2300
Chris@16 2301 typedef const_iterator2 dual_iterator_type;
Chris@16 2302 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 2303
Chris@16 2304 // Construction and destruction
Chris@16 2305 BOOST_UBLAS_INLINE
Chris@16 2306 const_iterator1 ():
Chris@16 2307 container_const_reference<self_type> () {}
Chris@16 2308 BOOST_UBLAS_INLINE
Chris@16 2309 const_iterator1 (const self_type &m):
Chris@16 2310 container_const_reference<self_type> (m) {}
Chris@16 2311
Chris@16 2312 // Arithmetic
Chris@16 2313 BOOST_UBLAS_INLINE
Chris@16 2314 const_iterator1 &operator ++ () {
Chris@16 2315 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2316 return *this;
Chris@16 2317 }
Chris@16 2318 BOOST_UBLAS_INLINE
Chris@16 2319 const_iterator1 &operator -- () {
Chris@16 2320 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2321 return *this;
Chris@16 2322 }
Chris@16 2323
Chris@16 2324 // Dereference
Chris@16 2325 BOOST_UBLAS_INLINE
Chris@16 2326 const_reference operator * () const {
Chris@16 2327 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2328 return zero_; // arbitary return value
Chris@16 2329 }
Chris@16 2330
Chris@16 2331 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2332 BOOST_UBLAS_INLINE
Chris@16 2333 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2334 typename self_type::
Chris@16 2335 #endif
Chris@16 2336 const_iterator2 begin () const {
Chris@16 2337 return const_iterator2 ((*this) ());
Chris@16 2338 }
Chris@16 2339 BOOST_UBLAS_INLINE
Chris@16 2340 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2341 typename self_type::
Chris@16 2342 #endif
Chris@16 2343 const_iterator2 end () const {
Chris@16 2344 return const_iterator2 ((*this) ());
Chris@16 2345 }
Chris@16 2346 BOOST_UBLAS_INLINE
Chris@16 2347 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2348 typename self_type::
Chris@16 2349 #endif
Chris@16 2350 const_reverse_iterator2 rbegin () const {
Chris@16 2351 return const_reverse_iterator2 (end ());
Chris@16 2352 }
Chris@16 2353 BOOST_UBLAS_INLINE
Chris@16 2354 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2355 typename self_type::
Chris@16 2356 #endif
Chris@16 2357 const_reverse_iterator2 rend () const {
Chris@16 2358 return const_reverse_iterator2 (begin ());
Chris@16 2359 }
Chris@16 2360 #endif
Chris@16 2361
Chris@16 2362 // Indices
Chris@16 2363 BOOST_UBLAS_INLINE
Chris@16 2364 size_type index1 () const {
Chris@16 2365 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2366 return 0; // arbitary return value
Chris@16 2367 }
Chris@16 2368 BOOST_UBLAS_INLINE
Chris@16 2369 size_type index2 () const {
Chris@16 2370 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2371 return 0; // arbitary return value
Chris@16 2372 }
Chris@16 2373
Chris@16 2374 // Assignment
Chris@16 2375 BOOST_UBLAS_INLINE
Chris@16 2376 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 2377 container_const_reference<self_type>::assign (&it ());
Chris@16 2378 return *this;
Chris@16 2379 }
Chris@16 2380
Chris@16 2381 // Comparison
Chris@16 2382 BOOST_UBLAS_INLINE
Chris@16 2383 bool operator == (const const_iterator1 &it) const {
Chris@16 2384 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2385 detail::ignore_unused_variable_warning(it);
Chris@16 2386 return true;
Chris@16 2387 }
Chris@16 2388 };
Chris@16 2389
Chris@16 2390 typedef const_iterator1 iterator1;
Chris@16 2391
Chris@16 2392 BOOST_UBLAS_INLINE
Chris@16 2393 const_iterator1 begin1 () const {
Chris@16 2394 return const_iterator1 (*this);
Chris@16 2395 }
Chris@16 2396 BOOST_UBLAS_INLINE
Chris@16 2397 const_iterator1 end1 () const {
Chris@16 2398 return const_iterator1 (*this);
Chris@16 2399 }
Chris@16 2400
Chris@16 2401 class const_iterator2:
Chris@16 2402 public container_const_reference<zero_matrix>,
Chris@16 2403 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
Chris@16 2404 const_iterator2, value_type> {
Chris@16 2405 public:
Chris@16 2406 typedef typename zero_matrix::value_type value_type;
Chris@16 2407 typedef typename zero_matrix::difference_type difference_type;
Chris@16 2408 typedef typename zero_matrix::const_reference reference;
Chris@16 2409 typedef typename zero_matrix::const_pointer pointer;
Chris@16 2410
Chris@16 2411 typedef const_iterator1 dual_iterator_type;
Chris@16 2412 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 2413
Chris@16 2414 // Construction and destruction
Chris@16 2415 BOOST_UBLAS_INLINE
Chris@16 2416 const_iterator2 ():
Chris@16 2417 container_const_reference<self_type> () {}
Chris@16 2418 BOOST_UBLAS_INLINE
Chris@16 2419 const_iterator2 (const self_type &m):
Chris@16 2420 container_const_reference<self_type> (m) {}
Chris@16 2421
Chris@16 2422 // Arithmetic
Chris@16 2423 BOOST_UBLAS_INLINE
Chris@16 2424 const_iterator2 &operator ++ () {
Chris@16 2425 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2426 return *this;
Chris@16 2427 }
Chris@16 2428 BOOST_UBLAS_INLINE
Chris@16 2429 const_iterator2 &operator -- () {
Chris@16 2430 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2431 return *this;
Chris@16 2432 }
Chris@16 2433
Chris@16 2434 // Dereference
Chris@16 2435 BOOST_UBLAS_INLINE
Chris@16 2436 const_reference operator * () const {
Chris@16 2437 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2438 return zero_; // arbitary return value
Chris@16 2439 }
Chris@16 2440
Chris@16 2441 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2442 BOOST_UBLAS_INLINE
Chris@16 2443 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2444 typename self_type::
Chris@16 2445 #endif
Chris@16 2446 const_iterator1 begin () const {
Chris@16 2447 return const_iterator1 ((*this) ());
Chris@16 2448 }
Chris@16 2449 BOOST_UBLAS_INLINE
Chris@16 2450 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2451 typename self_type::
Chris@16 2452 #endif
Chris@16 2453 const_iterator1 end () const {
Chris@16 2454 return const_iterator1 ((*this) ());
Chris@16 2455 }
Chris@16 2456 BOOST_UBLAS_INLINE
Chris@16 2457 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2458 typename self_type::
Chris@16 2459 #endif
Chris@16 2460 const_reverse_iterator1 rbegin () const {
Chris@16 2461 return const_reverse_iterator1 (end ());
Chris@16 2462 }
Chris@16 2463 BOOST_UBLAS_INLINE
Chris@16 2464 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2465 typename self_type::
Chris@16 2466 #endif
Chris@16 2467 const_reverse_iterator1 rend () const {
Chris@16 2468 return const_reverse_iterator1 (begin ());
Chris@16 2469 }
Chris@16 2470 #endif
Chris@16 2471
Chris@16 2472 // Indices
Chris@16 2473 BOOST_UBLAS_INLINE
Chris@16 2474 size_type index1 () const {
Chris@16 2475 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2476 return 0; // arbitary return value
Chris@16 2477 }
Chris@16 2478 BOOST_UBLAS_INLINE
Chris@16 2479 size_type index2 () const {
Chris@16 2480 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 2481 return 0; // arbitary return value
Chris@16 2482 }
Chris@16 2483
Chris@16 2484 // Assignment
Chris@16 2485 BOOST_UBLAS_INLINE
Chris@16 2486 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 2487 container_const_reference<self_type>::assign (&it ());
Chris@16 2488 return *this;
Chris@16 2489 }
Chris@16 2490
Chris@16 2491 // Comparison
Chris@16 2492 BOOST_UBLAS_INLINE
Chris@16 2493 bool operator == (const const_iterator2 &it) const {
Chris@16 2494 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2495 detail::ignore_unused_variable_warning(it);
Chris@16 2496 return true;
Chris@16 2497 }
Chris@16 2498 };
Chris@16 2499
Chris@16 2500 typedef const_iterator2 iterator2;
Chris@16 2501
Chris@16 2502 BOOST_UBLAS_INLINE
Chris@16 2503 const_iterator2 begin2 () const {
Chris@16 2504 return find2 (0, 0, 0);
Chris@16 2505 }
Chris@16 2506 BOOST_UBLAS_INLINE
Chris@16 2507 const_iterator2 end2 () const {
Chris@16 2508 return find2 (0, 0, size2_);
Chris@16 2509 }
Chris@16 2510
Chris@16 2511 // Reverse iterators
Chris@16 2512
Chris@16 2513 BOOST_UBLAS_INLINE
Chris@16 2514 const_reverse_iterator1 rbegin1 () const {
Chris@16 2515 return const_reverse_iterator1 (end1 ());
Chris@16 2516 }
Chris@16 2517 BOOST_UBLAS_INLINE
Chris@16 2518 const_reverse_iterator1 rend1 () const {
Chris@16 2519 return const_reverse_iterator1 (begin1 ());
Chris@16 2520 }
Chris@16 2521
Chris@16 2522 BOOST_UBLAS_INLINE
Chris@16 2523 const_reverse_iterator2 rbegin2 () const {
Chris@16 2524 return const_reverse_iterator2 (end2 ());
Chris@16 2525 }
Chris@16 2526 BOOST_UBLAS_INLINE
Chris@16 2527 const_reverse_iterator2 rend2 () const {
Chris@16 2528 return const_reverse_iterator2 (begin2 ());
Chris@16 2529 }
Chris@16 2530
Chris@16 2531 // Serialization
Chris@16 2532 template<class Archive>
Chris@16 2533 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 2534
Chris@16 2535 // we need to copy to a collection_size_type to get a portable
Chris@16 2536 // and efficient serialization
Chris@16 2537 serialization::collection_size_type s1 (size1_);
Chris@16 2538 serialization::collection_size_type s2 (size2_);
Chris@16 2539
Chris@16 2540 // serialize the sizes
Chris@16 2541 ar & serialization::make_nvp("size1",s1)
Chris@16 2542 & serialization::make_nvp("size2",s2);
Chris@16 2543
Chris@16 2544 // copy the values back if loading
Chris@16 2545 if (Archive::is_loading::value) {
Chris@16 2546 size1_ = s1;
Chris@16 2547 size2_ = s2;
Chris@16 2548 }
Chris@16 2549 }
Chris@16 2550
Chris@16 2551 private:
Chris@16 2552 size_type size1_;
Chris@16 2553 size_type size2_;
Chris@16 2554 static const value_type zero_;
Chris@16 2555 };
Chris@16 2556
Chris@16 2557 template<class T, class ALLOC>
Chris@16 2558 const typename zero_matrix<T, ALLOC>::value_type zero_matrix<T, ALLOC>::zero_ = T(/*zero*/);
Chris@16 2559
Chris@16 2560 /** \brief An identity matrix with values of type \c T
Chris@16 2561 *
Chris@16 2562 * Elements or cordinates \f$(i,i)\f$ are equal to 1 (one) and all others to 0 (zero).
Chris@16 2563 * Changing values does not affect the matrix, however assigning it to a normal matrix will
Chris@16 2564 * make the matrix equal to an identity matrix. All accesses are constant du to the trivial values.
Chris@16 2565 *
Chris@16 2566 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 2567 * \tparam ALLOC an allocator for storing the zeros and one elements. By default, a standar allocator is used.
Chris@16 2568 */
Chris@16 2569 template<class T, class ALLOC>
Chris@16 2570 class identity_matrix:
Chris@16 2571 public matrix_container<identity_matrix<T, ALLOC> > {
Chris@16 2572
Chris@16 2573 typedef const T *const_pointer;
Chris@16 2574 typedef identity_matrix<T, ALLOC> self_type;
Chris@16 2575 public:
Chris@16 2576 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 2577 using matrix_container<self_type>::operator ();
Chris@16 2578 #endif
Chris@16 2579 typedef typename ALLOC::size_type size_type;
Chris@16 2580 typedef typename ALLOC::difference_type difference_type;
Chris@16 2581 typedef T value_type;
Chris@16 2582 typedef const T &const_reference;
Chris@16 2583 typedef T &reference;
Chris@16 2584 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 2585 typedef matrix_reference<self_type> closure_type;
Chris@16 2586 typedef sparse_tag storage_category;
Chris@16 2587 typedef unknown_orientation_tag orientation_category;
Chris@16 2588
Chris@16 2589 // Construction and destruction
Chris@16 2590 BOOST_UBLAS_INLINE
Chris@16 2591 identity_matrix ():
Chris@16 2592 matrix_container<self_type> (),
Chris@16 2593 size1_ (0), size2_ (0), size_common_ (0) {}
Chris@16 2594 BOOST_UBLAS_INLINE
Chris@16 2595 identity_matrix (size_type size):
Chris@16 2596 matrix_container<self_type> (),
Chris@16 2597 size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {}
Chris@16 2598 BOOST_UBLAS_INLINE
Chris@16 2599 identity_matrix (size_type size1, size_type size2):
Chris@16 2600 matrix_container<self_type> (),
Chris@16 2601 size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {}
Chris@16 2602 BOOST_UBLAS_INLINE
Chris@16 2603 identity_matrix (const identity_matrix &m):
Chris@16 2604 matrix_container<self_type> (),
Chris@16 2605 size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {}
Chris@16 2606
Chris@16 2607 // Accessors
Chris@16 2608 BOOST_UBLAS_INLINE
Chris@16 2609 size_type size1 () const {
Chris@16 2610 return size1_;
Chris@16 2611 }
Chris@16 2612 BOOST_UBLAS_INLINE
Chris@16 2613 size_type size2 () const {
Chris@16 2614 return size2_;
Chris@16 2615 }
Chris@16 2616
Chris@16 2617 // Resizing
Chris@16 2618 BOOST_UBLAS_INLINE
Chris@16 2619 void resize (size_type size, bool preserve = true) {
Chris@16 2620 size1_ = size;
Chris@16 2621 size2_ = size;
Chris@16 2622 size_common_ = ((std::min)(size1_, size2_));
Chris@16 2623 }
Chris@16 2624 BOOST_UBLAS_INLINE
Chris@16 2625 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
Chris@16 2626 size1_ = size1;
Chris@16 2627 size2_ = size2;
Chris@16 2628 size_common_ = ((std::min)(size1_, size2_));
Chris@16 2629 }
Chris@16 2630
Chris@16 2631 // Element access
Chris@16 2632 BOOST_UBLAS_INLINE
Chris@16 2633 const_reference operator () (size_type i, size_type j) const {
Chris@16 2634 if (i == j)
Chris@16 2635 return one_;
Chris@16 2636 else
Chris@16 2637 return zero_;
Chris@16 2638 }
Chris@16 2639
Chris@16 2640 // Assignment
Chris@16 2641 BOOST_UBLAS_INLINE
Chris@16 2642 identity_matrix &operator = (const identity_matrix &m) {
Chris@16 2643 size1_ = m.size1_;
Chris@16 2644 size2_ = m.size2_;
Chris@16 2645 size_common_ = m.size_common_;
Chris@16 2646 return *this;
Chris@16 2647 }
Chris@16 2648 BOOST_UBLAS_INLINE
Chris@16 2649 identity_matrix &assign_temporary (identity_matrix &m) {
Chris@16 2650 swap (m);
Chris@16 2651 return *this;
Chris@16 2652 }
Chris@16 2653
Chris@16 2654 // Swapping
Chris@16 2655 BOOST_UBLAS_INLINE
Chris@16 2656 void swap (identity_matrix &m) {
Chris@16 2657 if (this != &m) {
Chris@16 2658 std::swap (size1_, m.size1_);
Chris@16 2659 std::swap (size2_, m.size2_);
Chris@16 2660 std::swap (size_common_, m.size_common_);
Chris@16 2661 }
Chris@16 2662 }
Chris@16 2663 BOOST_UBLAS_INLINE
Chris@16 2664 friend void swap (identity_matrix &m1, identity_matrix &m2) {
Chris@16 2665 m1.swap (m2);
Chris@16 2666 }
Chris@16 2667
Chris@16 2668 // Iterator types
Chris@16 2669 private:
Chris@16 2670 // Use an index
Chris@16 2671 typedef size_type const_subiterator_type;
Chris@16 2672
Chris@16 2673 public:
Chris@16 2674 class const_iterator1;
Chris@16 2675 class const_iterator2;
Chris@16 2676 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 2677 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 2678
Chris@16 2679 // Element lookup
Chris@16 2680 BOOST_UBLAS_INLINE
Chris@16 2681 const_iterator1 find1 (int rank, size_type i, size_type j) const {
Chris@16 2682 if (rank == 1) {
Chris@16 2683 i = (std::max) (i, j);
Chris@16 2684 i = (std::min) (i, j + 1);
Chris@16 2685 }
Chris@16 2686 return const_iterator1 (*this, i);
Chris@16 2687 }
Chris@16 2688 BOOST_UBLAS_INLINE
Chris@16 2689 const_iterator2 find2 (int rank, size_type i, size_type j) const {
Chris@16 2690 if (rank == 1) {
Chris@16 2691 j = (std::max) (j, i);
Chris@16 2692 j = (std::min) (j, i + 1);
Chris@16 2693 }
Chris@16 2694 return const_iterator2 (*this, j);
Chris@16 2695 }
Chris@16 2696
Chris@16 2697
Chris@16 2698 class const_iterator1:
Chris@16 2699 public container_const_reference<identity_matrix>,
Chris@16 2700 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
Chris@16 2701 const_iterator1, value_type> {
Chris@16 2702 public:
Chris@16 2703 typedef typename identity_matrix::value_type value_type;
Chris@16 2704 typedef typename identity_matrix::difference_type difference_type;
Chris@16 2705 typedef typename identity_matrix::const_reference reference;
Chris@16 2706 typedef typename identity_matrix::const_pointer pointer;
Chris@16 2707
Chris@16 2708 typedef const_iterator2 dual_iterator_type;
Chris@16 2709 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 2710
Chris@16 2711 // Construction and destruction
Chris@16 2712 BOOST_UBLAS_INLINE
Chris@16 2713 const_iterator1 ():
Chris@16 2714 container_const_reference<self_type> (), it_ () {}
Chris@16 2715 BOOST_UBLAS_INLINE
Chris@16 2716 const_iterator1 (const self_type &m, const const_subiterator_type &it):
Chris@16 2717 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 2718
Chris@16 2719 // Arithmetic
Chris@16 2720 BOOST_UBLAS_INLINE
Chris@16 2721 const_iterator1 &operator ++ () {
Chris@16 2722 BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ());
Chris@16 2723 ++it_;
Chris@16 2724 return *this;
Chris@16 2725 }
Chris@16 2726 BOOST_UBLAS_INLINE
Chris@16 2727 const_iterator1 &operator -- () {
Chris@16 2728 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
Chris@16 2729 --it_;
Chris@16 2730 return *this;
Chris@16 2731 }
Chris@16 2732
Chris@16 2733 // Dereference
Chris@16 2734 BOOST_UBLAS_INLINE
Chris@16 2735 const_reference operator * () const {
Chris@16 2736 return one_;
Chris@16 2737 }
Chris@16 2738
Chris@16 2739 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2740 BOOST_UBLAS_INLINE
Chris@16 2741 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2742 typename self_type::
Chris@16 2743 #endif
Chris@16 2744 const_iterator2 begin () const {
Chris@16 2745 return const_iterator2 ((*this) (), it_);
Chris@16 2746 }
Chris@16 2747 BOOST_UBLAS_INLINE
Chris@16 2748 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2749 typename self_type::
Chris@16 2750 #endif
Chris@16 2751 const_iterator2 end () const {
Chris@16 2752 return const_iterator2 ((*this) (), it_ + 1);
Chris@16 2753 }
Chris@16 2754 BOOST_UBLAS_INLINE
Chris@16 2755 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2756 typename self_type::
Chris@16 2757 #endif
Chris@16 2758 const_reverse_iterator2 rbegin () const {
Chris@16 2759 return const_reverse_iterator2 (end ());
Chris@16 2760 }
Chris@16 2761 BOOST_UBLAS_INLINE
Chris@16 2762 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2763 typename self_type::
Chris@16 2764 #endif
Chris@16 2765 const_reverse_iterator2 rend () const {
Chris@16 2766 return const_reverse_iterator2 (begin ());
Chris@16 2767 }
Chris@16 2768 #endif
Chris@16 2769
Chris@16 2770 // Indices
Chris@16 2771 BOOST_UBLAS_INLINE
Chris@16 2772 size_type index1 () const {
Chris@16 2773 return it_;
Chris@16 2774 }
Chris@16 2775 BOOST_UBLAS_INLINE
Chris@16 2776 size_type index2 () const {
Chris@16 2777 return it_;
Chris@16 2778 }
Chris@16 2779
Chris@16 2780 // Assignment
Chris@16 2781 BOOST_UBLAS_INLINE
Chris@16 2782 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 2783 container_const_reference<self_type>::assign (&it ());
Chris@16 2784 it_ = it.it_;
Chris@16 2785 return *this;
Chris@16 2786 }
Chris@16 2787
Chris@16 2788 // Comparison
Chris@16 2789 BOOST_UBLAS_INLINE
Chris@16 2790 bool operator == (const const_iterator1 &it) const {
Chris@16 2791 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2792 return it_ == it.it_;
Chris@16 2793 }
Chris@16 2794
Chris@16 2795 private:
Chris@16 2796 const_subiterator_type it_;
Chris@16 2797 };
Chris@16 2798
Chris@16 2799 typedef const_iterator1 iterator1;
Chris@16 2800
Chris@16 2801 BOOST_UBLAS_INLINE
Chris@16 2802 const_iterator1 begin1 () const {
Chris@16 2803 return const_iterator1 (*this, 0);
Chris@16 2804 }
Chris@16 2805 BOOST_UBLAS_INLINE
Chris@16 2806 const_iterator1 end1 () const {
Chris@16 2807 return const_iterator1 (*this, size_common_);
Chris@16 2808 }
Chris@16 2809
Chris@16 2810 class const_iterator2:
Chris@16 2811 public container_const_reference<identity_matrix>,
Chris@16 2812 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
Chris@16 2813 const_iterator2, value_type> {
Chris@16 2814 public:
Chris@16 2815 typedef typename identity_matrix::value_type value_type;
Chris@16 2816 typedef typename identity_matrix::difference_type difference_type;
Chris@16 2817 typedef typename identity_matrix::const_reference reference;
Chris@16 2818 typedef typename identity_matrix::const_pointer pointer;
Chris@16 2819
Chris@16 2820 typedef const_iterator1 dual_iterator_type;
Chris@16 2821 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 2822
Chris@16 2823 // Construction and destruction
Chris@16 2824 BOOST_UBLAS_INLINE
Chris@16 2825 const_iterator2 ():
Chris@16 2826 container_const_reference<self_type> (), it_ () {}
Chris@16 2827 BOOST_UBLAS_INLINE
Chris@16 2828 const_iterator2 (const self_type &m, const const_subiterator_type &it):
Chris@16 2829 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 2830
Chris@16 2831 // Arithmetic
Chris@16 2832 BOOST_UBLAS_INLINE
Chris@16 2833 const_iterator2 &operator ++ () {
Chris@16 2834 BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ());
Chris@16 2835 ++it_;
Chris@16 2836 return *this;
Chris@16 2837 }
Chris@16 2838 BOOST_UBLAS_INLINE
Chris@16 2839 const_iterator2 &operator -- () {
Chris@16 2840 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
Chris@16 2841 --it_;
Chris@16 2842 return *this;
Chris@16 2843 }
Chris@16 2844
Chris@16 2845 // Dereference
Chris@16 2846 BOOST_UBLAS_INLINE
Chris@16 2847 const_reference operator * () const {
Chris@16 2848 return one_;
Chris@16 2849 }
Chris@16 2850
Chris@16 2851 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2852 BOOST_UBLAS_INLINE
Chris@16 2853 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2854 typename self_type::
Chris@16 2855 #endif
Chris@16 2856 const_iterator1 begin () const {
Chris@16 2857 return const_iterator1 ((*this) (), it_);
Chris@16 2858 }
Chris@16 2859 BOOST_UBLAS_INLINE
Chris@16 2860 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2861 typename self_type::
Chris@16 2862 #endif
Chris@16 2863 const_iterator1 end () const {
Chris@16 2864 return const_iterator1 ((*this) (), it_ + 1);
Chris@16 2865 }
Chris@16 2866 BOOST_UBLAS_INLINE
Chris@16 2867 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2868 typename self_type::
Chris@16 2869 #endif
Chris@16 2870 const_reverse_iterator1 rbegin () const {
Chris@16 2871 return const_reverse_iterator1 (end ());
Chris@16 2872 }
Chris@16 2873 BOOST_UBLAS_INLINE
Chris@16 2874 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2875 typename self_type::
Chris@16 2876 #endif
Chris@16 2877 const_reverse_iterator1 rend () const {
Chris@16 2878 return const_reverse_iterator1 (begin ());
Chris@16 2879 }
Chris@16 2880 #endif
Chris@16 2881
Chris@16 2882 // Indices
Chris@16 2883 BOOST_UBLAS_INLINE
Chris@16 2884 size_type index1 () const {
Chris@16 2885 return it_;
Chris@16 2886 }
Chris@16 2887 BOOST_UBLAS_INLINE
Chris@16 2888 size_type index2 () const {
Chris@16 2889 return it_;
Chris@16 2890 }
Chris@16 2891
Chris@16 2892 // Assignment
Chris@16 2893 BOOST_UBLAS_INLINE
Chris@16 2894 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 2895 container_const_reference<self_type>::assign (&it ());
Chris@16 2896 it_ = it.it_;
Chris@16 2897 return *this;
Chris@16 2898 }
Chris@16 2899
Chris@16 2900 // Comparison
Chris@16 2901 BOOST_UBLAS_INLINE
Chris@16 2902 bool operator == (const const_iterator2 &it) const {
Chris@16 2903 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2904 return it_ == it.it_;
Chris@16 2905 }
Chris@16 2906
Chris@16 2907 private:
Chris@16 2908 const_subiterator_type it_;
Chris@16 2909 };
Chris@16 2910
Chris@16 2911 typedef const_iterator2 iterator2;
Chris@16 2912
Chris@16 2913 BOOST_UBLAS_INLINE
Chris@16 2914 const_iterator2 begin2 () const {
Chris@16 2915 return const_iterator2 (*this, 0);
Chris@16 2916 }
Chris@16 2917 BOOST_UBLAS_INLINE
Chris@16 2918 const_iterator2 end2 () const {
Chris@16 2919 return const_iterator2 (*this, size_common_);
Chris@16 2920 }
Chris@16 2921
Chris@16 2922 // Reverse iterators
Chris@16 2923
Chris@16 2924 BOOST_UBLAS_INLINE
Chris@16 2925 const_reverse_iterator1 rbegin1 () const {
Chris@16 2926 return const_reverse_iterator1 (end1 ());
Chris@16 2927 }
Chris@16 2928 BOOST_UBLAS_INLINE
Chris@16 2929 const_reverse_iterator1 rend1 () const {
Chris@16 2930 return const_reverse_iterator1 (begin1 ());
Chris@16 2931 }
Chris@16 2932
Chris@16 2933 BOOST_UBLAS_INLINE
Chris@16 2934 const_reverse_iterator2 rbegin2 () const {
Chris@16 2935 return const_reverse_iterator2 (end2 ());
Chris@16 2936 }
Chris@16 2937 BOOST_UBLAS_INLINE
Chris@16 2938 const_reverse_iterator2 rend2 () const {
Chris@16 2939 return const_reverse_iterator2 (begin2 ());
Chris@16 2940 }
Chris@16 2941
Chris@16 2942 // Serialization
Chris@16 2943 template<class Archive>
Chris@16 2944 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 2945
Chris@16 2946 // we need to copy to a collection_size_type to get a portable
Chris@16 2947 // and efficient serialization
Chris@16 2948 serialization::collection_size_type s1 (size1_);
Chris@16 2949 serialization::collection_size_type s2 (size2_);
Chris@16 2950
Chris@16 2951 // serialize the sizes
Chris@16 2952 ar & serialization::make_nvp("size1",s1)
Chris@16 2953 & serialization::make_nvp("size2",s2);
Chris@16 2954
Chris@16 2955 // copy the values back if loading
Chris@16 2956 if (Archive::is_loading::value) {
Chris@16 2957 size1_ = s1;
Chris@16 2958 size2_ = s2;
Chris@16 2959 size_common_ = ((std::min)(size1_, size2_));
Chris@16 2960 }
Chris@16 2961 }
Chris@16 2962
Chris@16 2963 private:
Chris@16 2964 size_type size1_;
Chris@16 2965 size_type size2_;
Chris@16 2966 size_type size_common_;
Chris@16 2967 static const value_type zero_;
Chris@16 2968 static const value_type one_;
Chris@16 2969 };
Chris@16 2970
Chris@16 2971 template<class T, class ALLOC>
Chris@16 2972 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::zero_ = T(/*zero*/);
Chris@16 2973 template<class T, class ALLOC>
Chris@16 2974 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here
Chris@16 2975
Chris@16 2976
Chris@16 2977 /** \brief A matrix with all values of type \c T equal to the same value
Chris@16 2978 *
Chris@16 2979 * Changing one value has the effect of changing all the values. Assigning it to a normal matrix will copy
Chris@16 2980 * the same value everywhere in this matrix. All accesses are constant time, due to the trivial value.
Chris@16 2981 *
Chris@16 2982 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 2983 * \tparam ALLOC an allocator for storing the unique value. By default, a standar allocator is used.
Chris@16 2984 */
Chris@16 2985 template<class T, class ALLOC>
Chris@16 2986 class scalar_matrix:
Chris@16 2987 public matrix_container<scalar_matrix<T, ALLOC> > {
Chris@16 2988
Chris@16 2989 typedef const T *const_pointer;
Chris@16 2990 typedef scalar_matrix<T, ALLOC> self_type;
Chris@16 2991 public:
Chris@16 2992 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 2993 using matrix_container<self_type>::operator ();
Chris@16 2994 #endif
Chris@16 2995 typedef std::size_t size_type;
Chris@16 2996 typedef std::ptrdiff_t difference_type;
Chris@16 2997 typedef T value_type;
Chris@16 2998 typedef const T &const_reference;
Chris@16 2999 typedef T &reference;
Chris@16 3000 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 3001 typedef matrix_reference<self_type> closure_type;
Chris@16 3002 typedef dense_tag storage_category;
Chris@16 3003 typedef unknown_orientation_tag orientation_category;
Chris@16 3004
Chris@16 3005 // Construction and destruction
Chris@16 3006 BOOST_UBLAS_INLINE
Chris@16 3007 scalar_matrix ():
Chris@16 3008 matrix_container<self_type> (),
Chris@16 3009 size1_ (0), size2_ (0), value_ () {}
Chris@16 3010 BOOST_UBLAS_INLINE
Chris@16 3011 scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)):
Chris@16 3012 matrix_container<self_type> (),
Chris@16 3013 size1_ (size1), size2_ (size2), value_ (value) {}
Chris@16 3014 BOOST_UBLAS_INLINE
Chris@16 3015 scalar_matrix (const scalar_matrix &m):
Chris@16 3016 matrix_container<self_type> (),
Chris@16 3017 size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {}
Chris@16 3018
Chris@16 3019 // Accessors
Chris@16 3020 BOOST_UBLAS_INLINE
Chris@16 3021 size_type size1 () const {
Chris@16 3022 return size1_;
Chris@16 3023 }
Chris@16 3024 BOOST_UBLAS_INLINE
Chris@16 3025 size_type size2 () const {
Chris@16 3026 return size2_;
Chris@16 3027 }
Chris@16 3028
Chris@16 3029 // Resizing
Chris@16 3030 BOOST_UBLAS_INLINE
Chris@16 3031 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
Chris@16 3032 size1_ = size1;
Chris@16 3033 size2_ = size2;
Chris@16 3034 }
Chris@16 3035
Chris@16 3036 // Element access
Chris@16 3037 BOOST_UBLAS_INLINE
Chris@16 3038 const_reference operator () (size_type /*i*/, size_type /*j*/) const {
Chris@16 3039 return value_;
Chris@16 3040 }
Chris@16 3041
Chris@16 3042 // Assignment
Chris@16 3043 BOOST_UBLAS_INLINE
Chris@16 3044 scalar_matrix &operator = (const scalar_matrix &m) {
Chris@16 3045 size1_ = m.size1_;
Chris@16 3046 size2_ = m.size2_;
Chris@16 3047 value_ = m.value_;
Chris@16 3048 return *this;
Chris@16 3049 }
Chris@16 3050 BOOST_UBLAS_INLINE
Chris@16 3051 scalar_matrix &assign_temporary (scalar_matrix &m) {
Chris@16 3052 swap (m);
Chris@16 3053 return *this;
Chris@16 3054 }
Chris@16 3055
Chris@16 3056 // Swapping
Chris@16 3057 BOOST_UBLAS_INLINE
Chris@16 3058 void swap (scalar_matrix &m) {
Chris@16 3059 if (this != &m) {
Chris@16 3060 std::swap (size1_, m.size1_);
Chris@16 3061 std::swap (size2_, m.size2_);
Chris@16 3062 std::swap (value_, m.value_);
Chris@16 3063 }
Chris@16 3064 }
Chris@16 3065 BOOST_UBLAS_INLINE
Chris@16 3066 friend void swap (scalar_matrix &m1, scalar_matrix &m2) {
Chris@16 3067 m1.swap (m2);
Chris@16 3068 }
Chris@16 3069
Chris@16 3070 // Iterator types
Chris@16 3071 private:
Chris@16 3072 // Use an index
Chris@16 3073 typedef size_type const_subiterator_type;
Chris@16 3074
Chris@16 3075 public:
Chris@16 3076 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3077 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@16 3078 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@16 3079 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 3080 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 3081 #else
Chris@16 3082 class const_iterator1;
Chris@16 3083 class const_iterator2;
Chris@16 3084 #endif
Chris@16 3085 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 3086 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 3087
Chris@16 3088 // Element lookup
Chris@16 3089 BOOST_UBLAS_INLINE
Chris@16 3090 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
Chris@16 3091 return const_iterator1 (*this, i, j);
Chris@16 3092 }
Chris@16 3093 BOOST_UBLAS_INLINE
Chris@16 3094 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
Chris@16 3095 return const_iterator2 (*this, i, j);
Chris@16 3096 }
Chris@16 3097
Chris@16 3098
Chris@16 3099 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3100 class const_iterator1:
Chris@16 3101 public container_const_reference<scalar_matrix>,
Chris@16 3102 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 3103 const_iterator1, value_type> {
Chris@16 3104 public:
Chris@16 3105 typedef typename scalar_matrix::value_type value_type;
Chris@16 3106 typedef typename scalar_matrix::difference_type difference_type;
Chris@16 3107 typedef typename scalar_matrix::const_reference reference;
Chris@16 3108 typedef typename scalar_matrix::const_pointer pointer;
Chris@16 3109
Chris@16 3110 typedef const_iterator2 dual_iterator_type;
Chris@16 3111 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 3112
Chris@16 3113 // Construction and destruction
Chris@16 3114 BOOST_UBLAS_INLINE
Chris@16 3115 const_iterator1 ():
Chris@16 3116 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
Chris@16 3117 BOOST_UBLAS_INLINE
Chris@16 3118 const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
Chris@16 3119 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
Chris@16 3120
Chris@16 3121 // Arithmetic
Chris@16 3122 BOOST_UBLAS_INLINE
Chris@16 3123 const_iterator1 &operator ++ () {
Chris@16 3124 ++ it1_;
Chris@16 3125 return *this;
Chris@16 3126 }
Chris@16 3127 BOOST_UBLAS_INLINE
Chris@16 3128 const_iterator1 &operator -- () {
Chris@16 3129 -- it1_;
Chris@16 3130 return *this;
Chris@16 3131 }
Chris@16 3132 BOOST_UBLAS_INLINE
Chris@16 3133 const_iterator1 &operator += (difference_type n) {
Chris@16 3134 it1_ += n;
Chris@16 3135 return *this;
Chris@16 3136 }
Chris@16 3137 BOOST_UBLAS_INLINE
Chris@16 3138 const_iterator1 &operator -= (difference_type n) {
Chris@16 3139 it1_ -= n;
Chris@16 3140 return *this;
Chris@16 3141 }
Chris@16 3142 BOOST_UBLAS_INLINE
Chris@16 3143 difference_type operator - (const const_iterator1 &it) const {
Chris@16 3144 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3145 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 3146 return it1_ - it.it1_;
Chris@16 3147 }
Chris@16 3148
Chris@16 3149 // Dereference
Chris@16 3150 BOOST_UBLAS_INLINE
Chris@16 3151 const_reference operator * () const {
Chris@16 3152 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 3153 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 3154 return (*this) () (index1 (), index2 ());
Chris@16 3155 }
Chris@16 3156 BOOST_UBLAS_INLINE
Chris@16 3157 const_reference operator [] (difference_type n) const {
Chris@16 3158 return *(*this + n);
Chris@16 3159 }
Chris@16 3160
Chris@16 3161 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 3162 BOOST_UBLAS_INLINE
Chris@16 3163 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3164 typename self_type::
Chris@16 3165 #endif
Chris@16 3166 const_iterator2 begin () const {
Chris@16 3167 const scalar_matrix &m = (*this) ();
Chris@16 3168 return m.find2 (1, index1 (), 0);
Chris@16 3169 }
Chris@16 3170 BOOST_UBLAS_INLINE
Chris@16 3171 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3172 typename self_type::
Chris@16 3173 #endif
Chris@16 3174 const_iterator2 end () const {
Chris@16 3175 const scalar_matrix &m = (*this) ();
Chris@16 3176 return m.find2 (1, index1 (), m.size2 ());
Chris@16 3177 }
Chris@16 3178 BOOST_UBLAS_INLINE
Chris@16 3179 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3180 typename self_type::
Chris@16 3181 #endif
Chris@16 3182 const_reverse_iterator2 rbegin () const {
Chris@16 3183 return const_reverse_iterator2 (end ());
Chris@16 3184 }
Chris@16 3185 BOOST_UBLAS_INLINE
Chris@16 3186 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3187 typename self_type::
Chris@16 3188 #endif
Chris@16 3189 const_reverse_iterator2 rend () const {
Chris@16 3190 return const_reverse_iterator2 (begin ());
Chris@16 3191 }
Chris@16 3192 #endif
Chris@16 3193
Chris@16 3194 // Indices
Chris@16 3195 BOOST_UBLAS_INLINE
Chris@16 3196 size_type index1 () const {
Chris@16 3197 return it1_;
Chris@16 3198 }
Chris@16 3199 BOOST_UBLAS_INLINE
Chris@16 3200 size_type index2 () const {
Chris@16 3201 return it2_;
Chris@16 3202 }
Chris@16 3203
Chris@16 3204 // Assignment
Chris@16 3205 BOOST_UBLAS_INLINE
Chris@16 3206 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 3207 container_const_reference<scalar_matrix>::assign (&it ());
Chris@16 3208 it1_ = it.it1_;
Chris@16 3209 it2_ = it.it2_;
Chris@16 3210 return *this;
Chris@16 3211 }
Chris@16 3212
Chris@16 3213 // Comparison
Chris@16 3214 BOOST_UBLAS_INLINE
Chris@16 3215 bool operator == (const const_iterator1 &it) const {
Chris@16 3216 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3217 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 3218 return it1_ == it.it1_;
Chris@16 3219 }
Chris@16 3220 BOOST_UBLAS_INLINE
Chris@16 3221 bool operator < (const const_iterator1 &it) const {
Chris@16 3222 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3223 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 3224 return it1_ < it.it1_;
Chris@16 3225 }
Chris@16 3226
Chris@16 3227 private:
Chris@16 3228 const_subiterator_type it1_;
Chris@16 3229 const_subiterator_type it2_;
Chris@16 3230 };
Chris@16 3231
Chris@16 3232 typedef const_iterator1 iterator1;
Chris@16 3233 #endif
Chris@16 3234
Chris@16 3235 BOOST_UBLAS_INLINE
Chris@16 3236 const_iterator1 begin1 () const {
Chris@16 3237 return find1 (0, 0, 0);
Chris@16 3238 }
Chris@16 3239 BOOST_UBLAS_INLINE
Chris@16 3240 const_iterator1 end1 () const {
Chris@16 3241 return find1 (0, size1_, 0);
Chris@16 3242 }
Chris@16 3243
Chris@16 3244 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3245 class const_iterator2:
Chris@16 3246 public container_const_reference<scalar_matrix>,
Chris@16 3247 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 3248 const_iterator2, value_type> {
Chris@16 3249 public:
Chris@16 3250 typedef typename scalar_matrix::value_type value_type;
Chris@16 3251 typedef typename scalar_matrix::difference_type difference_type;
Chris@16 3252 typedef typename scalar_matrix::const_reference reference;
Chris@16 3253 typedef typename scalar_matrix::const_pointer pointer;
Chris@16 3254
Chris@16 3255 typedef const_iterator1 dual_iterator_type;
Chris@16 3256 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 3257
Chris@16 3258 // Construction and destruction
Chris@16 3259 BOOST_UBLAS_INLINE
Chris@16 3260 const_iterator2 ():
Chris@16 3261 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
Chris@16 3262 BOOST_UBLAS_INLINE
Chris@16 3263 const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
Chris@16 3264 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
Chris@16 3265
Chris@16 3266 // Arithmetic
Chris@16 3267 BOOST_UBLAS_INLINE
Chris@16 3268 const_iterator2 &operator ++ () {
Chris@16 3269 ++ it2_;
Chris@16 3270 return *this;
Chris@16 3271 }
Chris@16 3272 BOOST_UBLAS_INLINE
Chris@16 3273 const_iterator2 &operator -- () {
Chris@16 3274 -- it2_;
Chris@16 3275 return *this;
Chris@16 3276 }
Chris@16 3277 BOOST_UBLAS_INLINE
Chris@16 3278 const_iterator2 &operator += (difference_type n) {
Chris@16 3279 it2_ += n;
Chris@16 3280 return *this;
Chris@16 3281 }
Chris@16 3282 BOOST_UBLAS_INLINE
Chris@16 3283 const_iterator2 &operator -= (difference_type n) {
Chris@16 3284 it2_ -= n;
Chris@16 3285 return *this;
Chris@16 3286 }
Chris@16 3287 BOOST_UBLAS_INLINE
Chris@16 3288 difference_type operator - (const const_iterator2 &it) const {
Chris@16 3289 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3290 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 3291 return it2_ - it.it2_;
Chris@16 3292 }
Chris@16 3293
Chris@16 3294 // Dereference
Chris@16 3295 BOOST_UBLAS_INLINE
Chris@16 3296 const_reference operator * () const {
Chris@16 3297 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 3298 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 3299 return (*this) () (index1 (), index2 ());
Chris@16 3300 }
Chris@16 3301 BOOST_UBLAS_INLINE
Chris@16 3302 const_reference operator [] (difference_type n) const {
Chris@16 3303 return *(*this + n);
Chris@16 3304 }
Chris@16 3305
Chris@16 3306 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 3307 BOOST_UBLAS_INLINE
Chris@16 3308 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3309 typename self_type::
Chris@16 3310 #endif
Chris@16 3311 const_iterator1 begin () const {
Chris@16 3312 const scalar_matrix &m = (*this) ();
Chris@16 3313 return m.find1 (1, 0, index2 ());
Chris@16 3314 }
Chris@16 3315 BOOST_UBLAS_INLINE
Chris@16 3316 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3317 typename self_type::
Chris@16 3318 #endif
Chris@16 3319 const_iterator1 end () const {
Chris@16 3320 const scalar_matrix &m = (*this) ();
Chris@16 3321 return m.find1 (1, m.size1 (), index2 ());
Chris@16 3322 }
Chris@16 3323 BOOST_UBLAS_INLINE
Chris@16 3324 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3325 typename self_type::
Chris@16 3326 #endif
Chris@16 3327 const_reverse_iterator1 rbegin () const {
Chris@16 3328 return const_reverse_iterator1 (end ());
Chris@16 3329 }
Chris@16 3330 BOOST_UBLAS_INLINE
Chris@16 3331 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3332 typename self_type::
Chris@16 3333 #endif
Chris@16 3334 const_reverse_iterator1 rend () const {
Chris@16 3335 return const_reverse_iterator1 (begin ());
Chris@16 3336 }
Chris@16 3337 #endif
Chris@16 3338
Chris@16 3339 // Indices
Chris@16 3340 BOOST_UBLAS_INLINE
Chris@16 3341 size_type index1 () const {
Chris@16 3342 return it1_;
Chris@16 3343 }
Chris@16 3344 BOOST_UBLAS_INLINE
Chris@16 3345 size_type index2 () const {
Chris@16 3346 return it2_;
Chris@16 3347 }
Chris@16 3348
Chris@16 3349 // Assignment
Chris@16 3350 BOOST_UBLAS_INLINE
Chris@16 3351 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 3352 container_const_reference<scalar_matrix>::assign (&it ());
Chris@16 3353 it1_ = it.it1_;
Chris@16 3354 it2_ = it.it2_;
Chris@16 3355 return *this;
Chris@16 3356 }
Chris@16 3357
Chris@16 3358 // Comparison
Chris@16 3359 BOOST_UBLAS_INLINE
Chris@16 3360 bool operator == (const const_iterator2 &it) const {
Chris@16 3361 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3362 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 3363 return it2_ == it.it2_;
Chris@16 3364 }
Chris@16 3365 BOOST_UBLAS_INLINE
Chris@16 3366 bool operator < (const const_iterator2 &it) const {
Chris@16 3367 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3368 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 3369 return it2_ < it.it2_;
Chris@16 3370 }
Chris@16 3371
Chris@16 3372 private:
Chris@16 3373 const_subiterator_type it1_;
Chris@16 3374 const_subiterator_type it2_;
Chris@16 3375 };
Chris@16 3376
Chris@16 3377 typedef const_iterator2 iterator2;
Chris@16 3378 #endif
Chris@16 3379
Chris@16 3380 BOOST_UBLAS_INLINE
Chris@16 3381 const_iterator2 begin2 () const {
Chris@16 3382 return find2 (0, 0, 0);
Chris@16 3383 }
Chris@16 3384 BOOST_UBLAS_INLINE
Chris@16 3385 const_iterator2 end2 () const {
Chris@16 3386 return find2 (0, 0, size2_);
Chris@16 3387 }
Chris@16 3388
Chris@16 3389 // Reverse iterators
Chris@16 3390
Chris@16 3391 BOOST_UBLAS_INLINE
Chris@16 3392 const_reverse_iterator1 rbegin1 () const {
Chris@16 3393 return const_reverse_iterator1 (end1 ());
Chris@16 3394 }
Chris@16 3395 BOOST_UBLAS_INLINE
Chris@16 3396 const_reverse_iterator1 rend1 () const {
Chris@16 3397 return const_reverse_iterator1 (begin1 ());
Chris@16 3398 }
Chris@16 3399
Chris@16 3400 BOOST_UBLAS_INLINE
Chris@16 3401 const_reverse_iterator2 rbegin2 () const {
Chris@16 3402 return const_reverse_iterator2 (end2 ());
Chris@16 3403 }
Chris@16 3404 BOOST_UBLAS_INLINE
Chris@16 3405 const_reverse_iterator2 rend2 () const {
Chris@16 3406 return const_reverse_iterator2 (begin2 ());
Chris@16 3407 }
Chris@16 3408
Chris@16 3409 // Serialization
Chris@16 3410 template<class Archive>
Chris@16 3411 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 3412
Chris@16 3413 // we need to copy to a collection_size_type to get a portable
Chris@16 3414 // and efficient serialization
Chris@16 3415 serialization::collection_size_type s1 (size1_);
Chris@16 3416 serialization::collection_size_type s2 (size2_);
Chris@16 3417
Chris@16 3418 // serialize the sizes
Chris@16 3419 ar & serialization::make_nvp("size1",s1)
Chris@16 3420 & serialization::make_nvp("size2",s2);
Chris@16 3421
Chris@16 3422 // copy the values back if loading
Chris@16 3423 if (Archive::is_loading::value) {
Chris@16 3424 size1_ = s1;
Chris@16 3425 size2_ = s2;
Chris@16 3426 }
Chris@16 3427
Chris@16 3428 ar & serialization::make_nvp("value", value_);
Chris@16 3429 }
Chris@16 3430
Chris@16 3431 private:
Chris@16 3432 size_type size1_;
Chris@16 3433 size_type size2_;
Chris@16 3434 value_type value_;
Chris@16 3435 };
Chris@16 3436
Chris@16 3437
Chris@16 3438 /** \brief An array based matrix class which size is defined at type specification or object instanciation
Chris@16 3439 *
Chris@16 3440 * This matrix is directly based on a predefined C-style arry of data, thus providing the fastest
Chris@16 3441 * implementation possible. The constraint is that dimensions of the matrix must be specified at
Chris@16 3442 * the instanciation or the type specification.
Chris@16 3443 *
Chris@16 3444 * For instance, \code typedef c_matrix<double,4,4> my_4by4_matrix \endcode
Chris@16 3445 * defines a 4 by 4 double-precision matrix. You can also instantiate it directly with
Chris@16 3446 * \code c_matrix<int,8,5> my_fast_matrix \endcode. This will make a 8 by 5 integer matrix. The
Chris@16 3447 * price to pay for this speed is that you cannot resize it to a size larger than the one defined
Chris@16 3448 * in the template parameters. In the previous example, a size of 4 by 5 or 3 by 2 is acceptable,
Chris@16 3449 * but a new size of 9 by 5 or even 10 by 10 will raise a bad_size() exception.
Chris@16 3450 *
Chris@16 3451 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 3452 * \tparam N the default maximum number of rows
Chris@16 3453 * \tparam M the default maximum number of columns
Chris@16 3454 */
Chris@16 3455 template<class T, std::size_t N, std::size_t M>
Chris@16 3456 class c_matrix:
Chris@16 3457 public matrix_container<c_matrix<T, N, M> > {
Chris@16 3458
Chris@16 3459 typedef c_matrix<T, N, M> self_type;
Chris@16 3460 public:
Chris@16 3461 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 3462 using matrix_container<self_type>::operator ();
Chris@16 3463 #endif
Chris@16 3464 typedef std::size_t size_type;
Chris@16 3465 typedef std::ptrdiff_t difference_type;
Chris@16 3466 typedef T value_type;
Chris@16 3467 typedef const T &const_reference;
Chris@16 3468 typedef T &reference;
Chris@16 3469 typedef const T *const_pointer;
Chris@16 3470 typedef T *pointer;
Chris@16 3471 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 3472 typedef matrix_reference<self_type> closure_type;
Chris@16 3473 typedef c_vector<T, N * M> vector_temporary_type; // vector able to store all elements of c_matrix
Chris@16 3474 typedef self_type matrix_temporary_type;
Chris@16 3475 typedef dense_tag storage_category;
Chris@16 3476 // This could be better for performance,
Chris@16 3477 // typedef typename unknown_orientation_tag orientation_category;
Chris@16 3478 // but others depend on the orientation information...
Chris@16 3479 typedef row_major_tag orientation_category;
Chris@16 3480
Chris@16 3481 // Construction and destruction
Chris@16 3482 BOOST_UBLAS_INLINE
Chris@16 3483 c_matrix ():
Chris@16 3484 size1_ (N), size2_ (M) /* , data_ () */ {
Chris@16 3485 }
Chris@16 3486 BOOST_UBLAS_INLINE
Chris@16 3487 c_matrix (size_type size1, size_type size2):
Chris@16 3488 size1_ (size1), size2_ (size2) /* , data_ () */ {
Chris@16 3489 if (size1_ > N || size2_ > M)
Chris@16 3490 bad_size ().raise ();
Chris@16 3491 }
Chris@16 3492 BOOST_UBLAS_INLINE
Chris@16 3493 c_matrix (const c_matrix &m):
Chris@16 3494 size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ {
Chris@16 3495 if (size1_ > N || size2_ > M)
Chris@16 3496 bad_size ().raise ();
Chris@16 3497 assign(m);
Chris@16 3498 }
Chris@16 3499 template<class AE>
Chris@16 3500 BOOST_UBLAS_INLINE
Chris@16 3501 c_matrix (const matrix_expression<AE> &ae):
Chris@16 3502 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ {
Chris@16 3503 if (size1_ > N || size2_ > M)
Chris@16 3504 bad_size ().raise ();
Chris@16 3505 matrix_assign<scalar_assign> (*this, ae);
Chris@16 3506 }
Chris@16 3507
Chris@16 3508 // Accessors
Chris@16 3509 BOOST_UBLAS_INLINE
Chris@16 3510 size_type size1 () const {
Chris@16 3511 return size1_;
Chris@16 3512 }
Chris@16 3513 BOOST_UBLAS_INLINE
Chris@16 3514 size_type size2 () const {
Chris@16 3515 return size2_;
Chris@16 3516 }
Chris@16 3517 BOOST_UBLAS_INLINE
Chris@16 3518 const_pointer data () const {
Chris@16 3519 return reinterpret_cast<const_pointer> (data_);
Chris@16 3520 }
Chris@16 3521 BOOST_UBLAS_INLINE
Chris@16 3522 pointer data () {
Chris@16 3523 return reinterpret_cast<pointer> (data_);
Chris@16 3524 }
Chris@16 3525
Chris@16 3526 // Resizing
Chris@16 3527 BOOST_UBLAS_INLINE
Chris@16 3528 void resize (size_type size1, size_type size2, bool preserve = true) {
Chris@16 3529 if (size1 > N || size2 > M)
Chris@16 3530 bad_size ().raise ();
Chris@16 3531 if (preserve) {
Chris@16 3532 self_type temporary (size1, size2);
Chris@16 3533 // Common elements to preserve
Chris@16 3534 const size_type size1_min = (std::min) (size1, size1_);
Chris@16 3535 const size_type size2_min = (std::min) (size2, size2_);
Chris@16 3536 for (size_type i = 0; i != size1_min; ++i) { // indexing copy over major
Chris@16 3537 for (size_type j = 0; j != size2_min; ++j) {
Chris@16 3538 temporary.data_[i][j] = data_[i][j];
Chris@16 3539 }
Chris@16 3540 }
Chris@16 3541 assign_temporary (temporary);
Chris@16 3542 }
Chris@16 3543 else {
Chris@16 3544 size1_ = size1;
Chris@16 3545 size2_ = size2;
Chris@16 3546 }
Chris@16 3547 }
Chris@16 3548
Chris@16 3549 // Element access
Chris@16 3550 BOOST_UBLAS_INLINE
Chris@16 3551 const_reference operator () (size_type i, size_type j) const {
Chris@16 3552 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
Chris@16 3553 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
Chris@16 3554 return data_ [i] [j];
Chris@16 3555 }
Chris@16 3556 BOOST_UBLAS_INLINE
Chris@16 3557 reference at_element (size_type i, size_type j) {
Chris@16 3558 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
Chris@16 3559 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
Chris@16 3560 return data_ [i] [j];
Chris@16 3561 }
Chris@16 3562 BOOST_UBLAS_INLINE
Chris@16 3563 reference operator () (size_type i, size_type j) {
Chris@16 3564 return at_element (i, j);
Chris@16 3565 }
Chris@16 3566
Chris@16 3567 // Element assignment
Chris@16 3568 BOOST_UBLAS_INLINE
Chris@16 3569 reference insert_element (size_type i, size_type j, const_reference t) {
Chris@16 3570 return (at_element (i, j) = t);
Chris@16 3571 }
Chris@16 3572
Chris@16 3573 // Zeroing
Chris@16 3574 BOOST_UBLAS_INLINE
Chris@16 3575 void clear () {
Chris@16 3576 for (size_type i = 0; i < size1_; ++ i)
Chris@16 3577 std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/());
Chris@16 3578 }
Chris@16 3579
Chris@16 3580 // Assignment
Chris@16 3581 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
Chris@16 3582
Chris@16 3583 /*! @note "pass by value" the key idea to enable move semantics */
Chris@16 3584 BOOST_UBLAS_INLINE
Chris@16 3585 c_matrix &operator = (c_matrix m) {
Chris@16 3586 assign_temporary(m);
Chris@16 3587 return *this;
Chris@16 3588 }
Chris@16 3589 #else
Chris@16 3590 BOOST_UBLAS_INLINE
Chris@16 3591 c_matrix &operator = (const c_matrix &m) {
Chris@16 3592 size1_ = m.size1_;
Chris@16 3593 size2_ = m.size2_;
Chris@16 3594 for (size_type i = 0; i < m.size1_; ++ i)
Chris@16 3595 std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]);
Chris@16 3596 return *this;
Chris@16 3597 }
Chris@16 3598 #endif
Chris@16 3599 template<class C> // Container assignment without temporary
Chris@16 3600 BOOST_UBLAS_INLINE
Chris@16 3601 c_matrix &operator = (const matrix_container<C> &m) {
Chris@16 3602 resize (m ().size1 (), m ().size2 (), false);
Chris@16 3603 assign (m);
Chris@16 3604 return *this;
Chris@16 3605 }
Chris@16 3606 BOOST_UBLAS_INLINE
Chris@16 3607 c_matrix &assign_temporary (c_matrix &m) {
Chris@16 3608 swap (m);
Chris@16 3609 return *this;
Chris@16 3610 }
Chris@16 3611 template<class AE>
Chris@16 3612 BOOST_UBLAS_INLINE
Chris@16 3613 c_matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 3614 self_type temporary (ae);
Chris@16 3615 return assign_temporary (temporary);
Chris@16 3616 }
Chris@16 3617 template<class AE>
Chris@16 3618 BOOST_UBLAS_INLINE
Chris@16 3619 c_matrix &assign (const matrix_expression<AE> &ae) {
Chris@16 3620 matrix_assign<scalar_assign> (*this, ae);
Chris@16 3621 return *this;
Chris@16 3622 }
Chris@16 3623 template<class AE>
Chris@16 3624 BOOST_UBLAS_INLINE
Chris@16 3625 c_matrix& operator += (const matrix_expression<AE> &ae) {
Chris@16 3626 self_type temporary (*this + ae);
Chris@16 3627 return assign_temporary (temporary);
Chris@16 3628 }
Chris@16 3629 template<class C> // Container assignment without temporary
Chris@16 3630 BOOST_UBLAS_INLINE
Chris@16 3631 c_matrix &operator += (const matrix_container<C> &m) {
Chris@16 3632 plus_assign (m);
Chris@16 3633 return *this;
Chris@16 3634 }
Chris@16 3635 template<class AE>
Chris@16 3636 BOOST_UBLAS_INLINE
Chris@16 3637 c_matrix &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 3638 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 3639 return *this;
Chris@16 3640 }
Chris@16 3641 template<class AE>
Chris@16 3642 BOOST_UBLAS_INLINE
Chris@16 3643 c_matrix& operator -= (const matrix_expression<AE> &ae) {
Chris@16 3644 self_type temporary (*this - ae);
Chris@16 3645 return assign_temporary (temporary);
Chris@16 3646 }
Chris@16 3647 template<class C> // Container assignment without temporary
Chris@16 3648 BOOST_UBLAS_INLINE
Chris@16 3649 c_matrix &operator -= (const matrix_container<C> &m) {
Chris@16 3650 minus_assign (m);
Chris@16 3651 return *this;
Chris@16 3652 }
Chris@16 3653 template<class AE>
Chris@16 3654 BOOST_UBLAS_INLINE
Chris@16 3655 c_matrix &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 3656 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 3657 return *this;
Chris@16 3658 }
Chris@16 3659 template<class AT>
Chris@16 3660 BOOST_UBLAS_INLINE
Chris@16 3661 c_matrix& operator *= (const AT &at) {
Chris@16 3662 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 3663 return *this;
Chris@16 3664 }
Chris@16 3665 template<class AT>
Chris@16 3666 BOOST_UBLAS_INLINE
Chris@16 3667 c_matrix& operator /= (const AT &at) {
Chris@16 3668 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 3669 return *this;
Chris@16 3670 }
Chris@16 3671
Chris@16 3672 // Swapping
Chris@16 3673 BOOST_UBLAS_INLINE
Chris@16 3674 void swap (c_matrix &m) {
Chris@16 3675 if (this != &m) {
Chris@16 3676 BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ());
Chris@16 3677 BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ());
Chris@16 3678 std::swap (size1_, m.size1_);
Chris@16 3679 std::swap (size2_, m.size2_);
Chris@16 3680 for (size_type i = 0; i < size1_; ++ i)
Chris@16 3681 std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]);
Chris@16 3682 }
Chris@16 3683 }
Chris@16 3684 BOOST_UBLAS_INLINE
Chris@16 3685 friend void swap (c_matrix &m1, c_matrix &m2) {
Chris@16 3686 m1.swap (m2);
Chris@16 3687 }
Chris@16 3688
Chris@16 3689 // Iterator types
Chris@16 3690 private:
Chris@16 3691 // Use pointers for iterator
Chris@16 3692 typedef const_pointer const_subiterator_type;
Chris@16 3693 typedef pointer subiterator_type;
Chris@16 3694
Chris@16 3695 public:
Chris@16 3696 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3697 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@16 3698 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@16 3699 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 3700 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 3701 #else
Chris@16 3702 class const_iterator1;
Chris@16 3703 class iterator1;
Chris@16 3704 class const_iterator2;
Chris@16 3705 class iterator2;
Chris@16 3706 #endif
Chris@16 3707 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 3708 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 3709 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 3710 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 3711
Chris@16 3712 // Element lookup
Chris@16 3713 BOOST_UBLAS_INLINE
Chris@16 3714 const_iterator1 find1 (int rank, size_type i, size_type j) const {
Chris@16 3715 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3716 return const_iterator1 (*this, i, j);
Chris@16 3717 #else
Chris@16 3718 return const_iterator1 (*this, &data_ [i] [j]);
Chris@16 3719 #endif
Chris@16 3720 }
Chris@16 3721 BOOST_UBLAS_INLINE
Chris@16 3722 iterator1 find1 (int rank, size_type i, size_type j) {
Chris@16 3723 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3724 return iterator1 (*this, i, j);
Chris@16 3725 #else
Chris@16 3726 return iterator1 (*this, &data_ [i] [j]);
Chris@16 3727 #endif
Chris@16 3728 }
Chris@16 3729 BOOST_UBLAS_INLINE
Chris@16 3730 const_iterator2 find2 (int rank, size_type i, size_type j) const {
Chris@16 3731 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3732 return const_iterator2 (*this, i, j);
Chris@16 3733 #else
Chris@16 3734 return const_iterator2 (*this, &data_ [i] [j]);
Chris@16 3735 #endif
Chris@16 3736 }
Chris@16 3737 BOOST_UBLAS_INLINE
Chris@16 3738 iterator2 find2 (int rank, size_type i, size_type j) {
Chris@16 3739 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3740 return iterator2 (*this, i, j);
Chris@16 3741 #else
Chris@16 3742 return iterator2 (*this, &data_ [i] [j]);
Chris@16 3743 #endif
Chris@16 3744 }
Chris@16 3745
Chris@16 3746
Chris@16 3747 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3748 class const_iterator1:
Chris@16 3749 public container_const_reference<c_matrix>,
Chris@16 3750 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 3751 const_iterator1, value_type> {
Chris@16 3752 public:
Chris@16 3753 typedef typename c_matrix::difference_type difference_type;
Chris@16 3754 typedef typename c_matrix::value_type value_type;
Chris@16 3755 typedef typename c_matrix::const_reference reference;
Chris@16 3756 typedef typename c_matrix::const_pointer pointer;
Chris@16 3757
Chris@16 3758 typedef const_iterator2 dual_iterator_type;
Chris@16 3759 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 3760
Chris@16 3761 // Construction and destruction
Chris@16 3762 BOOST_UBLAS_INLINE
Chris@16 3763 const_iterator1 ():
Chris@16 3764 container_const_reference<self_type> (), it_ () {}
Chris@16 3765 BOOST_UBLAS_INLINE
Chris@16 3766 const_iterator1 (const self_type &m, const const_subiterator_type &it):
Chris@16 3767 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 3768 BOOST_UBLAS_INLINE
Chris@16 3769 const_iterator1 (const iterator1 &it):
Chris@16 3770 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 3771
Chris@16 3772 // Arithmetic
Chris@16 3773 BOOST_UBLAS_INLINE
Chris@16 3774 const_iterator1 &operator ++ () {
Chris@16 3775 it_ += M;
Chris@16 3776 return *this;
Chris@16 3777 }
Chris@16 3778 BOOST_UBLAS_INLINE
Chris@16 3779 const_iterator1 &operator -- () {
Chris@16 3780 it_ -= M;
Chris@16 3781 return *this;
Chris@16 3782 }
Chris@16 3783 BOOST_UBLAS_INLINE
Chris@16 3784 const_iterator1 &operator += (difference_type n) {
Chris@16 3785 it_ += n * M;
Chris@16 3786 return *this;
Chris@16 3787 }
Chris@16 3788 BOOST_UBLAS_INLINE
Chris@16 3789 const_iterator1 &operator -= (difference_type n) {
Chris@16 3790 it_ -= n * M;
Chris@16 3791 return *this;
Chris@16 3792 }
Chris@16 3793 BOOST_UBLAS_INLINE
Chris@16 3794 difference_type operator - (const const_iterator1 &it) const {
Chris@16 3795 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3796 return (it_ - it.it_) / M;
Chris@16 3797 }
Chris@16 3798
Chris@16 3799 // Dereference
Chris@16 3800 BOOST_UBLAS_INLINE
Chris@16 3801 const_reference operator * () const {
Chris@16 3802 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 3803 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 3804 return *it_;
Chris@16 3805 }
Chris@16 3806 BOOST_UBLAS_INLINE
Chris@16 3807 const_reference operator [] (difference_type n) const {
Chris@16 3808 return *(*this + n);
Chris@16 3809 }
Chris@16 3810
Chris@16 3811 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 3812 BOOST_UBLAS_INLINE
Chris@16 3813 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3814 typename self_type::
Chris@16 3815 #endif
Chris@16 3816 const_iterator2 begin () const {
Chris@16 3817 const self_type &m = (*this) ();
Chris@16 3818 return m.find2 (1, index1 (), 0);
Chris@16 3819 }
Chris@16 3820 BOOST_UBLAS_INLINE
Chris@16 3821 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3822 typename self_type::
Chris@16 3823 #endif
Chris@16 3824 const_iterator2 end () const {
Chris@16 3825 const self_type &m = (*this) ();
Chris@16 3826 return m.find2 (1, index1 (), m.size2 ());
Chris@16 3827 }
Chris@16 3828 BOOST_UBLAS_INLINE
Chris@16 3829 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3830 typename self_type::
Chris@16 3831 #endif
Chris@16 3832 const_reverse_iterator2 rbegin () const {
Chris@16 3833 return const_reverse_iterator2 (end ());
Chris@16 3834 }
Chris@16 3835 BOOST_UBLAS_INLINE
Chris@16 3836 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3837 typename self_type::
Chris@16 3838 #endif
Chris@16 3839 const_reverse_iterator2 rend () const {
Chris@16 3840 return const_reverse_iterator2 (begin ());
Chris@16 3841 }
Chris@16 3842 #endif
Chris@16 3843
Chris@16 3844 // Indices
Chris@16 3845 BOOST_UBLAS_INLINE
Chris@16 3846 size_type index1 () const {
Chris@16 3847 const self_type &m = (*this) ();
Chris@16 3848 return (it_ - m.begin1 ().it_) / M;
Chris@16 3849 }
Chris@16 3850 BOOST_UBLAS_INLINE
Chris@16 3851 size_type index2 () const {
Chris@16 3852 const self_type &m = (*this) ();
Chris@16 3853 return (it_ - m.begin1 ().it_) % M;
Chris@16 3854 }
Chris@16 3855
Chris@16 3856 // Assignment
Chris@16 3857 BOOST_UBLAS_INLINE
Chris@16 3858 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 3859 container_const_reference<self_type>::assign (&it ());
Chris@16 3860 it_ = it.it_;
Chris@16 3861 return *this;
Chris@16 3862 }
Chris@16 3863
Chris@16 3864 // Comparison
Chris@16 3865 BOOST_UBLAS_INLINE
Chris@16 3866 bool operator == (const const_iterator1 &it) const {
Chris@16 3867 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3868 return it_ == it.it_;
Chris@16 3869 }
Chris@16 3870 BOOST_UBLAS_INLINE
Chris@16 3871 bool operator < (const const_iterator1 &it) const {
Chris@16 3872 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3873 return it_ < it.it_;
Chris@16 3874 }
Chris@16 3875
Chris@16 3876 private:
Chris@16 3877 const_subiterator_type it_;
Chris@16 3878
Chris@16 3879 friend class iterator1;
Chris@16 3880 };
Chris@16 3881 #endif
Chris@16 3882
Chris@16 3883 BOOST_UBLAS_INLINE
Chris@16 3884 const_iterator1 begin1 () const {
Chris@16 3885 return find1 (0, 0, 0);
Chris@16 3886 }
Chris@16 3887 BOOST_UBLAS_INLINE
Chris@16 3888 const_iterator1 end1 () const {
Chris@16 3889 return find1 (0, size1_, 0);
Chris@16 3890 }
Chris@16 3891
Chris@16 3892 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3893 class iterator1:
Chris@16 3894 public container_reference<c_matrix>,
Chris@16 3895 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 3896 iterator1, value_type> {
Chris@16 3897 public:
Chris@16 3898
Chris@16 3899 typedef typename c_matrix::difference_type difference_type;
Chris@16 3900 typedef typename c_matrix::value_type value_type;
Chris@16 3901 typedef typename c_matrix::reference reference;
Chris@16 3902 typedef typename c_matrix::pointer pointer;
Chris@16 3903
Chris@16 3904 typedef iterator2 dual_iterator_type;
Chris@16 3905 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 3906
Chris@16 3907 // Construction and destruction
Chris@16 3908 BOOST_UBLAS_INLINE
Chris@16 3909 iterator1 ():
Chris@16 3910 container_reference<self_type> (), it_ () {}
Chris@16 3911 BOOST_UBLAS_INLINE
Chris@16 3912 iterator1 (self_type &m, const subiterator_type &it):
Chris@16 3913 container_reference<self_type> (m), it_ (it) {}
Chris@16 3914
Chris@16 3915 // Arithmetic
Chris@16 3916 BOOST_UBLAS_INLINE
Chris@16 3917 iterator1 &operator ++ () {
Chris@16 3918 it_ += M;
Chris@16 3919 return *this;
Chris@16 3920 }
Chris@16 3921 BOOST_UBLAS_INLINE
Chris@16 3922 iterator1 &operator -- () {
Chris@16 3923 it_ -= M;
Chris@16 3924 return *this;
Chris@16 3925 }
Chris@16 3926 BOOST_UBLAS_INLINE
Chris@16 3927 iterator1 &operator += (difference_type n) {
Chris@16 3928 it_ += n * M;
Chris@16 3929 return *this;
Chris@16 3930 }
Chris@16 3931 BOOST_UBLAS_INLINE
Chris@16 3932 iterator1 &operator -= (difference_type n) {
Chris@16 3933 it_ -= n * M;
Chris@16 3934 return *this;
Chris@16 3935 }
Chris@16 3936 BOOST_UBLAS_INLINE
Chris@16 3937 difference_type operator - (const iterator1 &it) const {
Chris@16 3938 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3939 return (it_ - it.it_) / M;
Chris@16 3940 }
Chris@16 3941
Chris@16 3942 // Dereference
Chris@16 3943 BOOST_UBLAS_INLINE
Chris@16 3944 reference operator * () const {
Chris@16 3945 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 3946 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 3947 return *it_;
Chris@16 3948 }
Chris@16 3949 BOOST_UBLAS_INLINE
Chris@16 3950 reference operator [] (difference_type n) const {
Chris@16 3951 return *(*this + n);
Chris@16 3952 }
Chris@16 3953
Chris@16 3954 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 3955 BOOST_UBLAS_INLINE
Chris@16 3956 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3957 typename self_type::
Chris@16 3958 #endif
Chris@16 3959 iterator2 begin () const {
Chris@16 3960 self_type &m = (*this) ();
Chris@16 3961 return m.find2 (1, index1 (), 0);
Chris@16 3962 }
Chris@16 3963 BOOST_UBLAS_INLINE
Chris@16 3964 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3965 typename self_type::
Chris@16 3966 #endif
Chris@16 3967 iterator2 end () const {
Chris@16 3968 self_type &m = (*this) ();
Chris@16 3969 return m.find2 (1, index1 (), m.size2 ());
Chris@16 3970 }
Chris@16 3971 BOOST_UBLAS_INLINE
Chris@16 3972 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3973 typename self_type::
Chris@16 3974 #endif
Chris@16 3975 reverse_iterator2 rbegin () const {
Chris@16 3976 return reverse_iterator2 (end ());
Chris@16 3977 }
Chris@16 3978 BOOST_UBLAS_INLINE
Chris@16 3979 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3980 typename self_type::
Chris@16 3981 #endif
Chris@16 3982 reverse_iterator2 rend () const {
Chris@16 3983 return reverse_iterator2 (begin ());
Chris@16 3984 }
Chris@16 3985 #endif
Chris@16 3986
Chris@16 3987 // Indices
Chris@16 3988 BOOST_UBLAS_INLINE
Chris@16 3989 size_type index1 () const {
Chris@16 3990 const self_type &m = (*this) ();
Chris@16 3991 return (it_ - m.begin1 ().it_) / M;
Chris@16 3992 }
Chris@16 3993 BOOST_UBLAS_INLINE
Chris@16 3994 size_type index2 () const {
Chris@16 3995 const self_type &m = (*this) ();
Chris@16 3996 return (it_ - m.begin1 ().it_) % M;
Chris@16 3997 }
Chris@16 3998
Chris@16 3999 // Assignment
Chris@16 4000 BOOST_UBLAS_INLINE
Chris@16 4001 iterator1 &operator = (const iterator1 &it) {
Chris@16 4002 container_reference<self_type>::assign (&it ());
Chris@16 4003 it_ = it.it_;
Chris@16 4004 return *this;
Chris@16 4005 }
Chris@16 4006
Chris@16 4007 // Comparison
Chris@16 4008 BOOST_UBLAS_INLINE
Chris@16 4009 bool operator == (const iterator1 &it) const {
Chris@16 4010 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4011 return it_ == it.it_;
Chris@16 4012 }
Chris@16 4013 BOOST_UBLAS_INLINE
Chris@16 4014 bool operator < (const iterator1 &it) const {
Chris@16 4015 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4016 return it_ < it.it_;
Chris@16 4017 }
Chris@16 4018
Chris@16 4019 private:
Chris@16 4020 subiterator_type it_;
Chris@16 4021
Chris@16 4022 friend class const_iterator1;
Chris@16 4023 };
Chris@16 4024 #endif
Chris@16 4025
Chris@16 4026 BOOST_UBLAS_INLINE
Chris@16 4027 iterator1 begin1 () {
Chris@16 4028 return find1 (0, 0, 0);
Chris@16 4029 }
Chris@16 4030 BOOST_UBLAS_INLINE
Chris@16 4031 iterator1 end1 () {
Chris@16 4032 return find1 (0, size1_, 0);
Chris@16 4033 }
Chris@16 4034
Chris@16 4035 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 4036 class const_iterator2:
Chris@16 4037 public container_const_reference<c_matrix>,
Chris@16 4038 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 4039 const_iterator2, value_type> {
Chris@16 4040 public:
Chris@16 4041 typedef typename c_matrix::difference_type difference_type;
Chris@16 4042 typedef typename c_matrix::value_type value_type;
Chris@16 4043 typedef typename c_matrix::const_reference reference;
Chris@16 4044 typedef typename c_matrix::const_reference pointer;
Chris@16 4045
Chris@16 4046 typedef const_iterator1 dual_iterator_type;
Chris@16 4047 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 4048
Chris@16 4049 // Construction and destruction
Chris@16 4050 BOOST_UBLAS_INLINE
Chris@16 4051 const_iterator2 ():
Chris@16 4052 container_const_reference<self_type> (), it_ () {}
Chris@16 4053 BOOST_UBLAS_INLINE
Chris@16 4054 const_iterator2 (const self_type &m, const const_subiterator_type &it):
Chris@16 4055 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 4056 BOOST_UBLAS_INLINE
Chris@16 4057 const_iterator2 (const iterator2 &it):
Chris@16 4058 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 4059
Chris@16 4060 // Arithmetic
Chris@16 4061 BOOST_UBLAS_INLINE
Chris@16 4062 const_iterator2 &operator ++ () {
Chris@16 4063 ++ it_;
Chris@16 4064 return *this;
Chris@16 4065 }
Chris@16 4066 BOOST_UBLAS_INLINE
Chris@16 4067 const_iterator2 &operator -- () {
Chris@16 4068 -- it_;
Chris@16 4069 return *this;
Chris@16 4070 }
Chris@16 4071 BOOST_UBLAS_INLINE
Chris@16 4072 const_iterator2 &operator += (difference_type n) {
Chris@16 4073 it_ += n;
Chris@16 4074 return *this;
Chris@16 4075 }
Chris@16 4076 BOOST_UBLAS_INLINE
Chris@16 4077 const_iterator2 &operator -= (difference_type n) {
Chris@16 4078 it_ -= n;
Chris@16 4079 return *this;
Chris@16 4080 }
Chris@16 4081 BOOST_UBLAS_INLINE
Chris@16 4082 difference_type operator - (const const_iterator2 &it) const {
Chris@16 4083 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4084 return it_ - it.it_;
Chris@16 4085 }
Chris@16 4086
Chris@16 4087 // Dereference
Chris@16 4088 BOOST_UBLAS_INLINE
Chris@16 4089 const_reference operator * () const {
Chris@16 4090 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 4091 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 4092 return *it_;
Chris@16 4093 }
Chris@16 4094 BOOST_UBLAS_INLINE
Chris@16 4095 const_reference operator [] (difference_type n) const {
Chris@16 4096 return *(*this + n);
Chris@16 4097 }
Chris@16 4098
Chris@16 4099 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 4100 BOOST_UBLAS_INLINE
Chris@16 4101 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4102 typename self_type::
Chris@16 4103 #endif
Chris@16 4104 const_iterator1 begin () const {
Chris@16 4105 const self_type &m = (*this) ();
Chris@16 4106 return m.find1 (1, 0, index2 ());
Chris@16 4107 }
Chris@16 4108 BOOST_UBLAS_INLINE
Chris@16 4109 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4110 typename self_type::
Chris@16 4111 #endif
Chris@16 4112 const_iterator1 end () const {
Chris@16 4113 const self_type &m = (*this) ();
Chris@16 4114 return m.find1 (1, m.size1 (), index2 ());
Chris@16 4115 }
Chris@16 4116 BOOST_UBLAS_INLINE
Chris@16 4117 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4118 typename self_type::
Chris@16 4119 #endif
Chris@16 4120 const_reverse_iterator1 rbegin () const {
Chris@16 4121 return const_reverse_iterator1 (end ());
Chris@16 4122 }
Chris@16 4123 BOOST_UBLAS_INLINE
Chris@16 4124 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4125 typename self_type::
Chris@16 4126 #endif
Chris@16 4127 const_reverse_iterator1 rend () const {
Chris@16 4128 return const_reverse_iterator1 (begin ());
Chris@16 4129 }
Chris@16 4130 #endif
Chris@16 4131
Chris@16 4132 // Indices
Chris@16 4133 BOOST_UBLAS_INLINE
Chris@16 4134 size_type index1 () const {
Chris@16 4135 const self_type &m = (*this) ();
Chris@16 4136 return (it_ - m.begin2 ().it_) / M;
Chris@16 4137 }
Chris@16 4138 BOOST_UBLAS_INLINE
Chris@16 4139 size_type index2 () const {
Chris@16 4140 const self_type &m = (*this) ();
Chris@16 4141 return (it_ - m.begin2 ().it_) % M;
Chris@16 4142 }
Chris@16 4143
Chris@16 4144 // Assignment
Chris@16 4145 BOOST_UBLAS_INLINE
Chris@16 4146 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 4147 container_const_reference<self_type>::assign (&it ());
Chris@16 4148 it_ = it.it_;
Chris@16 4149 return *this;
Chris@16 4150 }
Chris@16 4151
Chris@16 4152 // Comparison
Chris@16 4153 BOOST_UBLAS_INLINE
Chris@16 4154 bool operator == (const const_iterator2 &it) const {
Chris@16 4155 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4156 return it_ == it.it_;
Chris@16 4157 }
Chris@16 4158 BOOST_UBLAS_INLINE
Chris@16 4159 bool operator < (const const_iterator2 &it) const {
Chris@16 4160 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4161 return it_ < it.it_;
Chris@16 4162 }
Chris@16 4163
Chris@16 4164 private:
Chris@16 4165 const_subiterator_type it_;
Chris@16 4166
Chris@16 4167 friend class iterator2;
Chris@16 4168 };
Chris@16 4169 #endif
Chris@16 4170
Chris@16 4171 BOOST_UBLAS_INLINE
Chris@16 4172 const_iterator2 begin2 () const {
Chris@16 4173 return find2 (0, 0, 0);
Chris@16 4174 }
Chris@16 4175 BOOST_UBLAS_INLINE
Chris@16 4176 const_iterator2 end2 () const {
Chris@16 4177 return find2 (0, 0, size2_);
Chris@16 4178 }
Chris@16 4179
Chris@16 4180 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 4181 class iterator2:
Chris@16 4182 public container_reference<c_matrix>,
Chris@16 4183 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 4184 iterator2, value_type> {
Chris@16 4185 public:
Chris@16 4186 typedef typename c_matrix::difference_type difference_type;
Chris@16 4187 typedef typename c_matrix::value_type value_type;
Chris@16 4188 typedef typename c_matrix::reference reference;
Chris@16 4189 typedef typename c_matrix::pointer pointer;
Chris@16 4190
Chris@16 4191 typedef iterator1 dual_iterator_type;
Chris@16 4192 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 4193
Chris@16 4194 // Construction and destruction
Chris@16 4195 BOOST_UBLAS_INLINE
Chris@16 4196 iterator2 ():
Chris@16 4197 container_reference<self_type> (), it_ () {}
Chris@16 4198 BOOST_UBLAS_INLINE
Chris@16 4199 iterator2 (self_type &m, const subiterator_type &it):
Chris@16 4200 container_reference<self_type> (m), it_ (it) {}
Chris@16 4201
Chris@16 4202 // Arithmetic
Chris@16 4203 BOOST_UBLAS_INLINE
Chris@16 4204 iterator2 &operator ++ () {
Chris@16 4205 ++ it_;
Chris@16 4206 return *this;
Chris@16 4207 }
Chris@16 4208 BOOST_UBLAS_INLINE
Chris@16 4209 iterator2 &operator -- () {
Chris@16 4210 -- it_;
Chris@16 4211 return *this;
Chris@16 4212 }
Chris@16 4213 BOOST_UBLAS_INLINE
Chris@16 4214 iterator2 &operator += (difference_type n) {
Chris@16 4215 it_ += n;
Chris@16 4216 return *this;
Chris@16 4217 }
Chris@16 4218 BOOST_UBLAS_INLINE
Chris@16 4219 iterator2 &operator -= (difference_type n) {
Chris@16 4220 it_ -= n;
Chris@16 4221 return *this;
Chris@16 4222 }
Chris@16 4223 BOOST_UBLAS_INLINE
Chris@16 4224 difference_type operator - (const iterator2 &it) const {
Chris@16 4225 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4226 return it_ - it.it_;
Chris@16 4227 }
Chris@16 4228
Chris@16 4229 // Dereference
Chris@16 4230 BOOST_UBLAS_INLINE
Chris@16 4231 reference operator * () const {
Chris@16 4232 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 4233 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 4234 return *it_;
Chris@16 4235 }
Chris@16 4236 BOOST_UBLAS_INLINE
Chris@16 4237 reference operator [] (difference_type n) const {
Chris@16 4238 return *(*this + n);
Chris@16 4239 }
Chris@16 4240
Chris@16 4241 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 4242 BOOST_UBLAS_INLINE
Chris@16 4243 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4244 typename self_type::
Chris@16 4245 #endif
Chris@16 4246 iterator1 begin () const {
Chris@16 4247 self_type &m = (*this) ();
Chris@16 4248 return m.find1 (1, 0, index2 ());
Chris@16 4249 }
Chris@16 4250 BOOST_UBLAS_INLINE
Chris@16 4251 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4252 typename self_type::
Chris@16 4253 #endif
Chris@16 4254 iterator1 end () const {
Chris@16 4255 self_type &m = (*this) ();
Chris@16 4256 return m.find1 (1, m.size1 (), index2 ());
Chris@16 4257 }
Chris@16 4258 BOOST_UBLAS_INLINE
Chris@16 4259 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4260 typename self_type::
Chris@16 4261 #endif
Chris@16 4262 reverse_iterator1 rbegin () const {
Chris@16 4263 return reverse_iterator1 (end ());
Chris@16 4264 }
Chris@16 4265 BOOST_UBLAS_INLINE
Chris@16 4266 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4267 typename self_type::
Chris@16 4268 #endif
Chris@16 4269 reverse_iterator1 rend () const {
Chris@16 4270 return reverse_iterator1 (begin ());
Chris@16 4271 }
Chris@16 4272 #endif
Chris@16 4273
Chris@16 4274 // Indices
Chris@16 4275 BOOST_UBLAS_INLINE
Chris@16 4276 size_type index1 () const {
Chris@16 4277 const self_type &m = (*this) ();
Chris@16 4278 return (it_ - m.begin2 ().it_) / M;
Chris@16 4279 }
Chris@16 4280 BOOST_UBLAS_INLINE
Chris@16 4281 size_type index2 () const {
Chris@16 4282 const self_type &m = (*this) ();
Chris@16 4283 return (it_ - m.begin2 ().it_) % M;
Chris@16 4284 }
Chris@16 4285
Chris@16 4286 // Assignment
Chris@16 4287 BOOST_UBLAS_INLINE
Chris@16 4288 iterator2 &operator = (const iterator2 &it) {
Chris@16 4289 container_reference<self_type>::assign (&it ());
Chris@16 4290 it_ = it.it_;
Chris@16 4291 return *this;
Chris@16 4292 }
Chris@16 4293
Chris@16 4294 // Comparison
Chris@16 4295 BOOST_UBLAS_INLINE
Chris@16 4296 bool operator == (const iterator2 &it) const {
Chris@16 4297 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4298 return it_ == it.it_;
Chris@16 4299 }
Chris@16 4300 BOOST_UBLAS_INLINE
Chris@16 4301 bool operator < (const iterator2 &it) const {
Chris@16 4302 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4303 return it_ < it.it_;
Chris@16 4304 }
Chris@16 4305
Chris@16 4306 private:
Chris@16 4307 subiterator_type it_;
Chris@16 4308
Chris@16 4309 friend class const_iterator2;
Chris@16 4310 };
Chris@16 4311 #endif
Chris@16 4312
Chris@16 4313 BOOST_UBLAS_INLINE
Chris@16 4314 iterator2 begin2 () {
Chris@16 4315 return find2 (0, 0, 0);
Chris@16 4316 }
Chris@16 4317 BOOST_UBLAS_INLINE
Chris@16 4318 iterator2 end2 () {
Chris@16 4319 return find2 (0, 0, size2_);
Chris@16 4320 }
Chris@16 4321
Chris@16 4322 // Reverse iterators
Chris@16 4323
Chris@16 4324 BOOST_UBLAS_INLINE
Chris@16 4325 const_reverse_iterator1 rbegin1 () const {
Chris@16 4326 return const_reverse_iterator1 (end1 ());
Chris@16 4327 }
Chris@16 4328 BOOST_UBLAS_INLINE
Chris@16 4329 const_reverse_iterator1 rend1 () const {
Chris@16 4330 return const_reverse_iterator1 (begin1 ());
Chris@16 4331 }
Chris@16 4332
Chris@16 4333 BOOST_UBLAS_INLINE
Chris@16 4334 reverse_iterator1 rbegin1 () {
Chris@16 4335 return reverse_iterator1 (end1 ());
Chris@16 4336 }
Chris@16 4337 BOOST_UBLAS_INLINE
Chris@16 4338 reverse_iterator1 rend1 () {
Chris@16 4339 return reverse_iterator1 (begin1 ());
Chris@16 4340 }
Chris@16 4341
Chris@16 4342 BOOST_UBLAS_INLINE
Chris@16 4343 const_reverse_iterator2 rbegin2 () const {
Chris@16 4344 return const_reverse_iterator2 (end2 ());
Chris@16 4345 }
Chris@16 4346 BOOST_UBLAS_INLINE
Chris@16 4347 const_reverse_iterator2 rend2 () const {
Chris@16 4348 return const_reverse_iterator2 (begin2 ());
Chris@16 4349 }
Chris@16 4350
Chris@16 4351 BOOST_UBLAS_INLINE
Chris@16 4352 reverse_iterator2 rbegin2 () {
Chris@16 4353 return reverse_iterator2 (end2 ());
Chris@16 4354 }
Chris@16 4355 BOOST_UBLAS_INLINE
Chris@16 4356 reverse_iterator2 rend2 () {
Chris@16 4357 return reverse_iterator2 (begin2 ());
Chris@16 4358 }
Chris@16 4359
Chris@16 4360 // Serialization
Chris@16 4361 template<class Archive>
Chris@16 4362 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 4363
Chris@16 4364 // we need to copy to a collection_size_type to get a portable
Chris@16 4365 // and efficient serialization
Chris@16 4366 serialization::collection_size_type s1 (size1_);
Chris@16 4367 serialization::collection_size_type s2 (size2_);
Chris@16 4368
Chris@16 4369 // serialize the sizes
Chris@16 4370 ar & serialization::make_nvp("size1",s1)
Chris@16 4371 & serialization::make_nvp("size2",s2);
Chris@16 4372
Chris@16 4373 // copy the values back if loading
Chris@16 4374 if (Archive::is_loading::value) {
Chris@16 4375 size1_ = s1;
Chris@16 4376 size2_ = s2;
Chris@16 4377 }
Chris@16 4378 // could probably use make_array( &(data[0][0]), N*M )
Chris@16 4379 ar & serialization::make_array(data_, N);
Chris@16 4380 }
Chris@16 4381
Chris@16 4382 private:
Chris@16 4383 size_type size1_;
Chris@16 4384 size_type size2_;
Chris@16 4385 value_type data_ [N] [M];
Chris@16 4386 };
Chris@16 4387
Chris@16 4388 }}}
Chris@16 4389
Chris@16 4390 #endif