annotate DEPENDENCIES/generic/include/boost/numeric/ublas/matrix.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
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@101 4 // Copyright (c) 2014, Athanasios Iliopoulos
Chris@16 5 //
Chris@16 6 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 7 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 //
Chris@16 10 // The authors gratefully acknowledge the support of
Chris@16 11 // GeNeSys mbH & Co. KG in producing this work.
Chris@16 12 //
Chris@16 13
Chris@16 14 #ifndef _BOOST_UBLAS_MATRIX_
Chris@16 15 #define _BOOST_UBLAS_MATRIX_
Chris@16 16
Chris@101 17 #include <boost/config.hpp>
Chris@16 18 #include <boost/numeric/ublas/vector.hpp>
Chris@16 19 #include <boost/numeric/ublas/matrix_expression.hpp>
Chris@16 20 #include <boost/numeric/ublas/detail/matrix_assign.hpp>
Chris@16 21 #include <boost/serialization/collection_size_type.hpp>
Chris@16 22 #include <boost/serialization/array.hpp>
Chris@16 23 #include <boost/serialization/nvp.hpp>
Chris@16 24
Chris@16 25 // Iterators based on ideas of Jeremy Siek
Chris@16 26
Chris@16 27 namespace boost { namespace numeric {
Chris@16 28
Chris@16 29 /** \brief main namespace of uBLAS.
Chris@16 30 *
Chris@16 31 * Use this namespace for all operations with uBLAS. It can also be abbreviated with
Chris@16 32 * \code namespace ublas = boost::numeric::ublas; \endcode
Chris@16 33 *
Chris@16 34 * A common practice is to bring this namespace into the current scope with
Chris@16 35 * \code using namespace boost::numeric::ublas; \endcode.
Chris@16 36 *
Chris@16 37 * 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 38 * 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 39 * write, you can define a new namespace like \c namespace ublas = boost::numeric::ublas and then just declare your vectors
Chris@16 40 * with \c ublas::vector<T>. STL vectors will be declared as vector<T>. No need to prefix with \c std::
Chris@16 41 */
Chris@16 42 namespace ublas {
Chris@16 43
Chris@16 44 namespace detail {
Chris@16 45 using namespace boost::numeric::ublas;
Chris@16 46
Chris@16 47 // Matrix resizing algorithm
Chris@16 48 template <class L, class M>
Chris@16 49 BOOST_UBLAS_INLINE
Chris@16 50 void matrix_resize_preserve (M& m, M& temporary) {
Chris@16 51 typedef L layout_type;
Chris@16 52 typedef typename M::size_type size_type;
Chris@16 53 const size_type msize1 (m.size1 ()); // original size
Chris@16 54 const size_type msize2 (m.size2 ());
Chris@16 55 const size_type size1 (temporary.size1 ()); // new size is specified by temporary
Chris@16 56 const size_type size2 (temporary.size2 ());
Chris@16 57 // Common elements to preserve
Chris@16 58 const size_type size1_min = (std::min) (size1, msize1);
Chris@16 59 const size_type size2_min = (std::min) (size2, msize2);
Chris@16 60 // Order for major and minor sizes
Chris@16 61 const size_type major_size = layout_type::size_M (size1_min, size2_min);
Chris@16 62 const size_type minor_size = layout_type::size_m (size1_min, size2_min);
Chris@16 63 // Indexing copy over major
Chris@16 64 for (size_type major = 0; major != major_size; ++major) {
Chris@16 65 for (size_type minor = 0; minor != minor_size; ++minor) {
Chris@16 66 // find indexes - use invertability of element_ functions
Chris@16 67 const size_type i1 = layout_type::index_M(major, minor);
Chris@16 68 const size_type i2 = layout_type::index_m(major, minor);
Chris@16 69 temporary.data () [layout_type::element (i1, size1, i2, size2)] =
Chris@16 70 m.data() [layout_type::element (i1, msize1, i2, msize2)];
Chris@16 71 }
Chris@16 72 }
Chris@16 73 m.assign_temporary (temporary);
Chris@16 74 }
Chris@16 75 }
Chris@16 76
Chris@16 77 /** \brief A dense matrix of values of type \c T.
Chris@16 78 *
Chris@16 79 * 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 80 * 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 81 * the container for column major orientation. In a dense matrix all elements are represented in memory in a
Chris@16 82 * contiguous chunk of memory by definition.
Chris@16 83 *
Chris@16 84 * Orientation and storage can also be specified, otherwise a \c row_major and \c unbounded_array are used. It is \b not
Chris@16 85 * required by the storage to initialize elements of the matrix.
Chris@16 86 *
Chris@16 87 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 88 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
Chris@16 89 * \tparam A the type of Storage array. Default is \c unbounded_array
Chris@16 90 */
Chris@16 91 template<class T, class L, class A>
Chris@16 92 class matrix:
Chris@16 93 public matrix_container<matrix<T, L, A> > {
Chris@16 94
Chris@16 95 typedef T *pointer;
Chris@16 96 typedef L layout_type;
Chris@16 97 typedef matrix<T, L, A> self_type;
Chris@16 98 public:
Chris@16 99 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 100 using matrix_container<self_type>::operator ();
Chris@16 101 #endif
Chris@16 102 typedef typename A::size_type size_type;
Chris@16 103 typedef typename A::difference_type difference_type;
Chris@16 104 typedef T value_type;
Chris@16 105 typedef const T &const_reference;
Chris@16 106 typedef T &reference;
Chris@16 107 typedef A array_type;
Chris@16 108 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 109 typedef matrix_reference<self_type> closure_type;
Chris@16 110 typedef vector<T, A> vector_temporary_type;
Chris@16 111 typedef self_type matrix_temporary_type;
Chris@16 112 typedef dense_tag storage_category;
Chris@16 113 // This could be better for performance,
Chris@16 114 // typedef typename unknown_orientation_tag orientation_category;
Chris@16 115 // but others depend on the orientation information...
Chris@16 116 typedef typename L::orientation_category orientation_category;
Chris@16 117
Chris@16 118 // Construction and destruction
Chris@16 119
Chris@16 120 /// Default dense matrix constructor. Make a dense matrix of size (0,0)
Chris@16 121 BOOST_UBLAS_INLINE
Chris@16 122 matrix ():
Chris@16 123 matrix_container<self_type> (),
Chris@16 124 size1_ (0), size2_ (0), data_ () {}
Chris@16 125
Chris@16 126 /** Dense matrix constructor with defined size
Chris@16 127 * \param size1 number of rows
Chris@16 128 * \param size2 number of columns
Chris@16 129 */
Chris@16 130 BOOST_UBLAS_INLINE
Chris@16 131 matrix (size_type size1, size_type size2):
Chris@16 132 matrix_container<self_type> (),
Chris@16 133 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) {
Chris@16 134 }
Chris@16 135
Chris@16 136 /** Dense matrix constructor with defined size a initial value for all the matrix elements
Chris@16 137 * \param size1 number of rows
Chris@16 138 * \param size2 number of columns
Chris@16 139 * \param init initial value assigned to all elements
Chris@16 140 */
Chris@16 141 matrix (size_type size1, size_type size2, const value_type &init):
Chris@16 142 matrix_container<self_type> (),
Chris@16 143 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2), init) {
Chris@16 144 }
Chris@16 145
Chris@16 146 /** Dense matrix constructor with defined size and an initial data array
Chris@16 147 * \param size1 number of rows
Chris@16 148 * \param size2 number of columns
Chris@16 149 * \param data array to copy into the matrix. Must have the same dimension as the matrix
Chris@16 150 */
Chris@16 151 BOOST_UBLAS_INLINE
Chris@16 152 matrix (size_type size1, size_type size2, const array_type &data):
Chris@16 153 matrix_container<self_type> (),
Chris@16 154 size1_ (size1), size2_ (size2), data_ (data) {}
Chris@16 155
Chris@16 156 /** Copy-constructor of a dense matrix
Chris@16 157 * \param m is a dense matrix
Chris@16 158 */
Chris@16 159 BOOST_UBLAS_INLINE
Chris@16 160 matrix (const matrix &m):
Chris@16 161 matrix_container<self_type> (),
Chris@16 162 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
Chris@16 163
Chris@16 164 /** Copy-constructor of a dense matrix from a matrix expression
Chris@16 165 * \param ae is a matrix expression
Chris@16 166 */
Chris@16 167 template<class AE>
Chris@16 168 BOOST_UBLAS_INLINE
Chris@16 169 matrix (const matrix_expression<AE> &ae):
Chris@16 170 matrix_container<self_type> (),
Chris@16 171 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) {
Chris@16 172 matrix_assign<scalar_assign> (*this, ae);
Chris@16 173 }
Chris@16 174
Chris@16 175 // Accessors
Chris@16 176 /** Return the number of rows of the matrix
Chris@16 177 * You can also use the free size<>() function in operation/size.hpp as size<1>(m) where m is a matrix
Chris@16 178 */
Chris@16 179 BOOST_UBLAS_INLINE
Chris@16 180 size_type size1 () const {
Chris@16 181 return size1_;
Chris@16 182 }
Chris@16 183
Chris@16 184 /** Return the number of colums of the matrix
Chris@16 185 * You can also use the free size<>() function in operation/size.hpp as size<2>(m) where m is a matrix
Chris@16 186 */
Chris@16 187 BOOST_UBLAS_INLINE
Chris@16 188 size_type size2 () const {
Chris@16 189 return size2_;
Chris@16 190 }
Chris@16 191
Chris@16 192 // Storage accessors
Chris@16 193 /** Return a constant reference to the internal storage of a dense matrix, i.e. the raw data
Chris@16 194 * It's type depends on the type used by the matrix to store its data
Chris@16 195 */
Chris@16 196 BOOST_UBLAS_INLINE
Chris@16 197 const array_type &data () const {
Chris@16 198 return data_;
Chris@16 199 }
Chris@16 200 /** Return a reference to the internal storage of a dense matrix, i.e. the raw data
Chris@16 201 * It's type depends on the type used by the matrix to store its data
Chris@16 202 */
Chris@16 203 BOOST_UBLAS_INLINE
Chris@16 204 array_type &data () {
Chris@16 205 return data_;
Chris@16 206 }
Chris@16 207
Chris@16 208 // Resizing
Chris@16 209 /** Resize a matrix to new dimensions
Chris@16 210 * If data are preserved, then if the size if bigger at least on one dimension, extra values are filled with zeros.
Chris@16 211 * If data are not preserved, then nothing has to be assumed regarding the content of the matrix after resizing.
Chris@16 212 * \param size1 the new number of rows
Chris@16 213 * \param size2 the new number of colums
Chris@16 214 * \param preserve a boolean to say if one wants the data to be preserved during the resizing. Default is true.
Chris@16 215 */
Chris@16 216 BOOST_UBLAS_INLINE
Chris@16 217 void resize (size_type size1, size_type size2, bool preserve = true) {
Chris@16 218 if (preserve) {
Chris@16 219 self_type temporary (size1, size2);
Chris@16 220 detail::matrix_resize_preserve<layout_type> (*this, temporary);
Chris@16 221 }
Chris@16 222 else {
Chris@16 223 data ().resize (layout_type::storage_size (size1, size2));
Chris@16 224 size1_ = size1;
Chris@16 225 size2_ = size2;
Chris@16 226 }
Chris@16 227 }
Chris@16 228
Chris@16 229 // Element access
Chris@16 230
Chris@16 231 /** Access a matrix element. Here we return a const reference
Chris@16 232 * \param i the first coordinate of the element. By default it's the row
Chris@16 233 * \param j the second coordinate of the element. By default it's the column
Chris@16 234 * \return a const reference to the element
Chris@16 235 */
Chris@16 236 BOOST_UBLAS_INLINE
Chris@16 237 const_reference operator () (size_type i, size_type j) const {
Chris@16 238 return data () [layout_type::element (i, size1_, j, size2_)];
Chris@16 239 }
Chris@16 240
Chris@16 241 /** Access a matrix element. Here we return a reference
Chris@16 242 * \param i the first coordinate of the element. By default it's the row
Chris@16 243 * \param j the second coordinate of the element. By default it's the column
Chris@16 244 * \return a reference to the element
Chris@16 245 */
Chris@16 246 BOOST_UBLAS_INLINE
Chris@16 247 reference at_element (size_type i, size_type j) {
Chris@16 248 return data () [layout_type::element (i, size1_, j, size2_)];
Chris@16 249 }
Chris@16 250
Chris@16 251 /** Access a matrix element. Here we return a reference
Chris@16 252 * \param i the first coordinate of the element. By default it's the row
Chris@16 253 * \param j the second coordinate of the element. By default it's the column
Chris@16 254 * \return a reference to the element
Chris@16 255 */
Chris@16 256 BOOST_UBLAS_INLINE
Chris@16 257 reference operator () (size_type i, size_type j) {
Chris@16 258 return at_element (i, j);
Chris@16 259 }
Chris@16 260
Chris@16 261 // Element assignment
Chris@16 262
Chris@16 263 /** Change the value of a matrix element. Return back a reference to it
Chris@16 264 * \param i the first coordinate of the element. By default it's the row
Chris@16 265 * \param j the second coordinate of the element. By default it's the column
Chris@16 266 * \param t the new value of the element
Chris@16 267 * \return a reference to the newly changed element
Chris@16 268 */
Chris@16 269 BOOST_UBLAS_INLINE
Chris@16 270 reference insert_element (size_type i, size_type j, const_reference t) {
Chris@16 271 return (at_element (i, j) = t);
Chris@16 272 }
Chris@16 273
Chris@16 274 /** Erase the element
Chris@16 275 * For most types (int, double, etc...) it means setting 0 (zero) the element at zero in fact.
Chris@16 276 * For user-defined types, it could be another value if you decided it. Your type in that case must
Chris@16 277 * contain a default null value.
Chris@16 278 * \param i the first coordinate of the element. By default it's the row
Chris@16 279 * \param j the second coordinate of the element. By default it's the column
Chris@16 280 */
Chris@16 281 void erase_element (size_type i, size_type j) {
Chris@16 282 at_element (i, j) = value_type/*zero*/();
Chris@16 283 }
Chris@16 284
Chris@16 285 // Zeroing
Chris@16 286 /** Erase all elements in the matrix
Chris@16 287 * For most types (int, double, etc...) it means writing 0 (zero) everywhere.
Chris@16 288 * For user-defined types, it could be another value if you decided it. Your type in that case must
Chris@16 289 * contain a default null value.
Chris@16 290 */
Chris@16 291 BOOST_UBLAS_INLINE
Chris@16 292 void clear () {
Chris@16 293 std::fill (data ().begin (), data ().end (), value_type/*zero*/());
Chris@16 294 }
Chris@16 295
Chris@16 296 // Assignment
Chris@16 297 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
Chris@16 298
Chris@16 299 /*! @note "pass by value" the key idea to enable move semantics */
Chris@16 300 BOOST_UBLAS_INLINE
Chris@16 301 matrix &operator = (matrix m) {
Chris@16 302 assign_temporary(m);
Chris@16 303 return *this;
Chris@16 304 }
Chris@16 305 #else
Chris@16 306 BOOST_UBLAS_INLINE
Chris@16 307 matrix &operator = (const matrix &m) {
Chris@16 308 size1_ = m.size1_;
Chris@16 309 size2_ = m.size2_;
Chris@16 310 data () = m.data ();
Chris@16 311 return *this;
Chris@16 312 }
Chris@16 313 #endif
Chris@16 314 template<class C> // Container assignment without temporary
Chris@16 315 BOOST_UBLAS_INLINE
Chris@16 316 matrix &operator = (const matrix_container<C> &m) {
Chris@16 317 resize (m ().size1 (), m ().size2 (), false);
Chris@16 318 assign (m);
Chris@16 319 return *this;
Chris@16 320 }
Chris@16 321 BOOST_UBLAS_INLINE
Chris@16 322 matrix &assign_temporary (matrix &m) {
Chris@16 323 swap (m);
Chris@16 324 return *this;
Chris@16 325 }
Chris@16 326 template<class AE>
Chris@16 327 BOOST_UBLAS_INLINE
Chris@16 328 matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 329 self_type temporary (ae);
Chris@16 330 return assign_temporary (temporary);
Chris@16 331 }
Chris@16 332 template<class AE>
Chris@16 333 BOOST_UBLAS_INLINE
Chris@16 334 matrix &assign (const matrix_expression<AE> &ae) {
Chris@16 335 matrix_assign<scalar_assign> (*this, ae);
Chris@16 336 return *this;
Chris@16 337 }
Chris@16 338 template<class AE>
Chris@16 339 BOOST_UBLAS_INLINE
Chris@16 340 matrix& operator += (const matrix_expression<AE> &ae) {
Chris@16 341 self_type temporary (*this + ae);
Chris@16 342 return assign_temporary (temporary);
Chris@16 343 }
Chris@16 344 template<class C> // Container assignment without temporary
Chris@16 345 BOOST_UBLAS_INLINE
Chris@16 346 matrix &operator += (const matrix_container<C> &m) {
Chris@16 347 plus_assign (m);
Chris@16 348 return *this;
Chris@16 349 }
Chris@16 350 template<class AE>
Chris@16 351 BOOST_UBLAS_INLINE
Chris@16 352 matrix &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 353 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 354 return *this;
Chris@16 355 }
Chris@16 356 template<class AE>
Chris@16 357 BOOST_UBLAS_INLINE
Chris@16 358 matrix& operator -= (const matrix_expression<AE> &ae) {
Chris@16 359 self_type temporary (*this - ae);
Chris@16 360 return assign_temporary (temporary);
Chris@16 361 }
Chris@16 362 template<class C> // Container assignment without temporary
Chris@16 363 BOOST_UBLAS_INLINE
Chris@16 364 matrix &operator -= (const matrix_container<C> &m) {
Chris@16 365 minus_assign (m);
Chris@16 366 return *this;
Chris@16 367 }
Chris@16 368 template<class AE>
Chris@16 369 BOOST_UBLAS_INLINE
Chris@16 370 matrix &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 371 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 372 return *this;
Chris@16 373 }
Chris@16 374 template<class AT>
Chris@16 375 BOOST_UBLAS_INLINE
Chris@16 376 matrix& operator *= (const AT &at) {
Chris@16 377 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 378 return *this;
Chris@16 379 }
Chris@16 380 template<class AT>
Chris@16 381 BOOST_UBLAS_INLINE
Chris@16 382 matrix& operator /= (const AT &at) {
Chris@16 383 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 384 return *this;
Chris@16 385 }
Chris@16 386
Chris@16 387 // Swapping
Chris@16 388 BOOST_UBLAS_INLINE
Chris@16 389 void swap (matrix &m) {
Chris@16 390 if (this != &m) {
Chris@16 391 std::swap (size1_, m.size1_);
Chris@16 392 std::swap (size2_, m.size2_);
Chris@16 393 data ().swap (m.data ());
Chris@16 394 }
Chris@16 395 }
Chris@16 396 BOOST_UBLAS_INLINE
Chris@16 397 friend void swap (matrix &m1, matrix &m2) {
Chris@16 398 m1.swap (m2);
Chris@16 399 }
Chris@16 400
Chris@16 401 // Iterator types
Chris@16 402 private:
Chris@16 403 // Use the storage array iterator
Chris@16 404 typedef typename A::const_iterator const_subiterator_type;
Chris@16 405 typedef typename A::iterator subiterator_type;
Chris@16 406
Chris@16 407 public:
Chris@16 408 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 409 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@16 410 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@16 411 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 412 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 413 #else
Chris@16 414 class const_iterator1;
Chris@16 415 class iterator1;
Chris@16 416 class const_iterator2;
Chris@16 417 class iterator2;
Chris@16 418 #endif
Chris@16 419 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 420 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 421 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 422 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 423
Chris@16 424 // Element lookup
Chris@16 425 BOOST_UBLAS_INLINE
Chris@16 426 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
Chris@16 427 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 428 return const_iterator1 (*this, i, j);
Chris@16 429 #else
Chris@16 430 return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
Chris@16 431 #endif
Chris@16 432 }
Chris@16 433 BOOST_UBLAS_INLINE
Chris@16 434 iterator1 find1 (int /* rank */, size_type i, size_type j) {
Chris@16 435 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 436 return iterator1 (*this, i, j);
Chris@16 437 #else
Chris@16 438 return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
Chris@16 439 #endif
Chris@16 440 }
Chris@16 441 BOOST_UBLAS_INLINE
Chris@16 442 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
Chris@16 443 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 444 return const_iterator2 (*this, i, j);
Chris@16 445 #else
Chris@16 446 return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
Chris@16 447 #endif
Chris@16 448 }
Chris@16 449 BOOST_UBLAS_INLINE
Chris@16 450 iterator2 find2 (int /* rank */, size_type i, size_type j) {
Chris@16 451 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 452 return iterator2 (*this, i, j);
Chris@16 453 #else
Chris@16 454 return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
Chris@16 455 #endif
Chris@16 456 }
Chris@16 457
Chris@16 458
Chris@16 459 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 460 class const_iterator1:
Chris@16 461 public container_const_reference<matrix>,
Chris@16 462 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 463 const_iterator1, value_type> {
Chris@16 464 public:
Chris@16 465 typedef typename matrix::value_type value_type;
Chris@16 466 typedef typename matrix::difference_type difference_type;
Chris@16 467 typedef typename matrix::const_reference reference;
Chris@16 468 typedef const typename matrix::pointer pointer;
Chris@16 469
Chris@16 470 typedef const_iterator2 dual_iterator_type;
Chris@16 471 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 472
Chris@16 473 // Construction and destruction
Chris@16 474 BOOST_UBLAS_INLINE
Chris@16 475 const_iterator1 ():
Chris@16 476 container_const_reference<self_type> (), it_ () {}
Chris@16 477 BOOST_UBLAS_INLINE
Chris@16 478 const_iterator1 (const self_type &m, const const_subiterator_type &it):
Chris@16 479 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 480 BOOST_UBLAS_INLINE
Chris@16 481 const_iterator1 (const iterator1 &it):
Chris@16 482 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 483
Chris@16 484 // Arithmetic
Chris@16 485 BOOST_UBLAS_INLINE
Chris@16 486 const_iterator1 &operator ++ () {
Chris@16 487 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 488 return *this;
Chris@16 489 }
Chris@16 490 BOOST_UBLAS_INLINE
Chris@16 491 const_iterator1 &operator -- () {
Chris@16 492 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 493 return *this;
Chris@16 494 }
Chris@16 495 BOOST_UBLAS_INLINE
Chris@16 496 const_iterator1 &operator += (difference_type n) {
Chris@16 497 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 498 return *this;
Chris@16 499 }
Chris@16 500 BOOST_UBLAS_INLINE
Chris@16 501 const_iterator1 &operator -= (difference_type n) {
Chris@16 502 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 503 return *this;
Chris@16 504 }
Chris@16 505 BOOST_UBLAS_INLINE
Chris@16 506 difference_type operator - (const const_iterator1 &it) const {
Chris@16 507 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 508 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 509 }
Chris@16 510
Chris@16 511 // Dereference
Chris@16 512 BOOST_UBLAS_INLINE
Chris@16 513 const_reference operator * () const {
Chris@16 514 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 515 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 516 return *it_;
Chris@16 517 }
Chris@16 518 BOOST_UBLAS_INLINE
Chris@16 519 const_reference operator [] (difference_type n) const {
Chris@16 520 return *(*this + n);
Chris@16 521 }
Chris@16 522
Chris@16 523 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 524 BOOST_UBLAS_INLINE
Chris@16 525 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 526 typename self_type::
Chris@16 527 #endif
Chris@16 528 const_iterator2 begin () const {
Chris@16 529 const self_type &m = (*this) ();
Chris@16 530 return m.find2 (1, index1 (), 0);
Chris@16 531 }
Chris@16 532 BOOST_UBLAS_INLINE
Chris@16 533 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 534 typename self_type::
Chris@16 535 #endif
Chris@101 536 const_iterator2 cbegin () const {
Chris@101 537 return begin ();
Chris@101 538 }
Chris@101 539 BOOST_UBLAS_INLINE
Chris@101 540 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 541 typename self_type::
Chris@101 542 #endif
Chris@16 543 const_iterator2 end () const {
Chris@16 544 const self_type &m = (*this) ();
Chris@16 545 return m.find2 (1, index1 (), m.size2 ());
Chris@16 546 }
Chris@16 547 BOOST_UBLAS_INLINE
Chris@16 548 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 549 typename self_type::
Chris@16 550 #endif
Chris@101 551 const_iterator2 cend () const {
Chris@101 552 return end ();
Chris@101 553 }
Chris@101 554 BOOST_UBLAS_INLINE
Chris@101 555 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 556 typename self_type::
Chris@101 557 #endif
Chris@16 558 const_reverse_iterator2 rbegin () const {
Chris@16 559 return const_reverse_iterator2 (end ());
Chris@16 560 }
Chris@16 561 BOOST_UBLAS_INLINE
Chris@16 562 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 563 typename self_type::
Chris@16 564 #endif
Chris@101 565 const_reverse_iterator2 crbegin () const {
Chris@101 566 return rbegin ();
Chris@101 567 }
Chris@101 568 BOOST_UBLAS_INLINE
Chris@101 569 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 570 typename self_type::
Chris@101 571 #endif
Chris@16 572 const_reverse_iterator2 rend () const {
Chris@16 573 return const_reverse_iterator2 (begin ());
Chris@16 574 }
Chris@101 575 BOOST_UBLAS_INLINE
Chris@101 576 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 577 typename self_type::
Chris@101 578 #endif
Chris@101 579 const_reverse_iterator2 crend () const {
Chris@101 580 return rend ();
Chris@101 581 }
Chris@16 582 #endif
Chris@16 583
Chris@16 584 // Indices
Chris@16 585 BOOST_UBLAS_INLINE
Chris@16 586 size_type index1 () const {
Chris@16 587 const self_type &m = (*this) ();
Chris@16 588 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@16 589 }
Chris@16 590 BOOST_UBLAS_INLINE
Chris@16 591 size_type index2 () const {
Chris@16 592 const self_type &m = (*this) ();
Chris@16 593 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@16 594 }
Chris@16 595
Chris@16 596 // Assignment
Chris@16 597 BOOST_UBLAS_INLINE
Chris@16 598 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 599 container_const_reference<self_type>::assign (&it ());
Chris@16 600 it_ = it.it_;
Chris@16 601 return *this;
Chris@16 602 }
Chris@16 603
Chris@16 604 // Comparison
Chris@16 605 BOOST_UBLAS_INLINE
Chris@16 606 bool operator == (const const_iterator1 &it) const {
Chris@16 607 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 608 return it_ == it.it_;
Chris@16 609 }
Chris@16 610 BOOST_UBLAS_INLINE
Chris@16 611 bool operator < (const const_iterator1 &it) const {
Chris@16 612 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 613 return it_ < it.it_;
Chris@16 614 }
Chris@16 615
Chris@16 616 private:
Chris@16 617 const_subiterator_type it_;
Chris@16 618
Chris@16 619 friend class iterator1;
Chris@16 620 };
Chris@16 621 #endif
Chris@16 622
Chris@16 623 BOOST_UBLAS_INLINE
Chris@16 624 const_iterator1 begin1 () const {
Chris@16 625 return find1 (0, 0, 0);
Chris@16 626 }
Chris@16 627 BOOST_UBLAS_INLINE
Chris@101 628 const_iterator1 cbegin1 () const {
Chris@101 629 return begin1 ();
Chris@101 630 }
Chris@101 631 BOOST_UBLAS_INLINE
Chris@16 632 const_iterator1 end1 () const {
Chris@16 633 return find1 (0, size1_, 0);
Chris@16 634 }
Chris@101 635 BOOST_UBLAS_INLINE
Chris@101 636 const_iterator1 cend1 () const {
Chris@101 637 return end1 ();
Chris@101 638 }
Chris@16 639
Chris@16 640 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 641 class iterator1:
Chris@16 642 public container_reference<matrix>,
Chris@16 643 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 644 iterator1, value_type> {
Chris@16 645 public:
Chris@16 646 typedef typename matrix::value_type value_type;
Chris@16 647 typedef typename matrix::difference_type difference_type;
Chris@16 648 typedef typename matrix::reference reference;
Chris@16 649 typedef typename matrix::pointer pointer;
Chris@16 650
Chris@16 651 typedef iterator2 dual_iterator_type;
Chris@16 652 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 653
Chris@16 654 // Construction and destruction
Chris@16 655 BOOST_UBLAS_INLINE
Chris@16 656 iterator1 ():
Chris@16 657 container_reference<self_type> (), it_ () {}
Chris@16 658 BOOST_UBLAS_INLINE
Chris@16 659 iterator1 (self_type &m, const subiterator_type &it):
Chris@16 660 container_reference<self_type> (m), it_ (it) {}
Chris@16 661
Chris@16 662 // Arithmetic
Chris@16 663 BOOST_UBLAS_INLINE
Chris@16 664 iterator1 &operator ++ () {
Chris@16 665 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 666 return *this;
Chris@16 667 }
Chris@16 668 BOOST_UBLAS_INLINE
Chris@16 669 iterator1 &operator -- () {
Chris@16 670 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 671 return *this;
Chris@16 672 }
Chris@16 673 BOOST_UBLAS_INLINE
Chris@16 674 iterator1 &operator += (difference_type n) {
Chris@16 675 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 676 return *this;
Chris@16 677 }
Chris@16 678 BOOST_UBLAS_INLINE
Chris@16 679 iterator1 &operator -= (difference_type n) {
Chris@16 680 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 681 return *this;
Chris@16 682 }
Chris@16 683 BOOST_UBLAS_INLINE
Chris@16 684 difference_type operator - (const iterator1 &it) const {
Chris@16 685 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 686 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 687 }
Chris@16 688
Chris@16 689 // Dereference
Chris@16 690 BOOST_UBLAS_INLINE
Chris@16 691 reference operator * () const {
Chris@16 692 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 693 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 694 return *it_;
Chris@16 695 }
Chris@16 696 BOOST_UBLAS_INLINE
Chris@16 697 reference operator [] (difference_type n) const {
Chris@16 698 return *(*this + n);
Chris@16 699 }
Chris@16 700
Chris@16 701 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 702 BOOST_UBLAS_INLINE
Chris@16 703 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 704 typename self_type::
Chris@16 705 #endif
Chris@16 706 iterator2 begin () const {
Chris@16 707 self_type &m = (*this) ();
Chris@16 708 return m.find2 (1, index1 (), 0);
Chris@16 709 }
Chris@16 710 BOOST_UBLAS_INLINE
Chris@16 711 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 712 typename self_type::
Chris@16 713 #endif
Chris@16 714 iterator2 end () const {
Chris@16 715 self_type &m = (*this) ();
Chris@16 716 return m.find2 (1, index1 (), m.size2 ());
Chris@16 717 }
Chris@16 718 BOOST_UBLAS_INLINE
Chris@16 719 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 720 typename self_type::
Chris@16 721 #endif
Chris@16 722 reverse_iterator2 rbegin () const {
Chris@16 723 return reverse_iterator2 (end ());
Chris@16 724 }
Chris@16 725 BOOST_UBLAS_INLINE
Chris@16 726 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 727 typename self_type::
Chris@16 728 #endif
Chris@16 729 reverse_iterator2 rend () const {
Chris@16 730 return reverse_iterator2 (begin ());
Chris@16 731 }
Chris@16 732 #endif
Chris@16 733
Chris@16 734 // Indices
Chris@16 735 BOOST_UBLAS_INLINE
Chris@16 736 size_type index1 () const {
Chris@16 737 self_type &m = (*this) ();
Chris@16 738 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@16 739 }
Chris@16 740 BOOST_UBLAS_INLINE
Chris@16 741 size_type index2 () const {
Chris@16 742 self_type &m = (*this) ();
Chris@16 743 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@16 744 }
Chris@16 745
Chris@16 746 // Assignment
Chris@16 747 BOOST_UBLAS_INLINE
Chris@16 748 iterator1 &operator = (const iterator1 &it) {
Chris@16 749 container_reference<self_type>::assign (&it ());
Chris@16 750 it_ = it.it_;
Chris@16 751 return *this;
Chris@16 752 }
Chris@16 753
Chris@16 754 // Comparison
Chris@16 755 BOOST_UBLAS_INLINE
Chris@16 756 bool operator == (const iterator1 &it) const {
Chris@16 757 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 758 return it_ == it.it_;
Chris@16 759 }
Chris@16 760 BOOST_UBLAS_INLINE
Chris@16 761 bool operator < (const iterator1 &it) const {
Chris@16 762 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 763 return it_ < it.it_;
Chris@16 764 }
Chris@16 765
Chris@16 766 private:
Chris@16 767 subiterator_type it_;
Chris@16 768
Chris@16 769 friend class const_iterator1;
Chris@16 770 };
Chris@16 771 #endif
Chris@16 772
Chris@16 773 BOOST_UBLAS_INLINE
Chris@16 774 iterator1 begin1 () {
Chris@16 775 return find1 (0, 0, 0);
Chris@16 776 }
Chris@16 777 BOOST_UBLAS_INLINE
Chris@16 778 iterator1 end1 () {
Chris@16 779 return find1 (0, size1_, 0);
Chris@16 780 }
Chris@16 781
Chris@16 782 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 783 class const_iterator2:
Chris@16 784 public container_const_reference<matrix>,
Chris@16 785 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 786 const_iterator2, value_type> {
Chris@16 787 public:
Chris@16 788 typedef typename matrix::value_type value_type;
Chris@16 789 typedef typename matrix::difference_type difference_type;
Chris@16 790 typedef typename matrix::const_reference reference;
Chris@16 791 typedef const typename matrix::pointer pointer;
Chris@16 792
Chris@16 793 typedef const_iterator1 dual_iterator_type;
Chris@16 794 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 795
Chris@16 796 // Construction and destruction
Chris@16 797 BOOST_UBLAS_INLINE
Chris@16 798 const_iterator2 ():
Chris@16 799 container_const_reference<self_type> (), it_ () {}
Chris@16 800 BOOST_UBLAS_INLINE
Chris@16 801 const_iterator2 (const self_type &m, const const_subiterator_type &it):
Chris@16 802 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 803 BOOST_UBLAS_INLINE
Chris@16 804 const_iterator2 (const iterator2 &it):
Chris@16 805 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 806
Chris@16 807 // Arithmetic
Chris@16 808 BOOST_UBLAS_INLINE
Chris@16 809 const_iterator2 &operator ++ () {
Chris@16 810 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 811 return *this;
Chris@16 812 }
Chris@16 813 BOOST_UBLAS_INLINE
Chris@16 814 const_iterator2 &operator -- () {
Chris@16 815 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 816 return *this;
Chris@16 817 }
Chris@16 818 BOOST_UBLAS_INLINE
Chris@16 819 const_iterator2 &operator += (difference_type n) {
Chris@16 820 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 821 return *this;
Chris@16 822 }
Chris@16 823 BOOST_UBLAS_INLINE
Chris@16 824 const_iterator2 &operator -= (difference_type n) {
Chris@16 825 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 826 return *this;
Chris@16 827 }
Chris@16 828 BOOST_UBLAS_INLINE
Chris@16 829 difference_type operator - (const const_iterator2 &it) const {
Chris@16 830 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 831 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 832 }
Chris@16 833
Chris@16 834 // Dereference
Chris@16 835 BOOST_UBLAS_INLINE
Chris@16 836 const_reference operator * () const {
Chris@16 837 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 838 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 839 return *it_;
Chris@16 840 }
Chris@16 841 BOOST_UBLAS_INLINE
Chris@16 842 const_reference operator [] (difference_type n) const {
Chris@16 843 return *(*this + n);
Chris@16 844 }
Chris@16 845
Chris@16 846 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 847 BOOST_UBLAS_INLINE
Chris@16 848 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 849 typename self_type::
Chris@16 850 #endif
Chris@16 851 const_iterator1 begin () const {
Chris@16 852 const self_type &m = (*this) ();
Chris@16 853 return m.find1 (1, 0, index2 ());
Chris@16 854 }
Chris@16 855 BOOST_UBLAS_INLINE
Chris@16 856 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 857 typename self_type::
Chris@16 858 #endif
Chris@101 859 const_iterator1 cbegin () const {
Chris@101 860 return begin ();
Chris@101 861 }
Chris@101 862 BOOST_UBLAS_INLINE
Chris@101 863 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 864 typename self_type::
Chris@101 865 #endif
Chris@16 866 const_iterator1 end () const {
Chris@16 867 const self_type &m = (*this) ();
Chris@16 868 return m.find1 (1, m.size1 (), index2 ());
Chris@16 869 }
Chris@16 870 BOOST_UBLAS_INLINE
Chris@16 871 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 872 typename self_type::
Chris@16 873 #endif
Chris@101 874 const_iterator1 cend () const {
Chris@101 875 return end ();
Chris@101 876 }
Chris@101 877 BOOST_UBLAS_INLINE
Chris@101 878 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 879 typename self_type::
Chris@101 880 #endif
Chris@16 881 const_reverse_iterator1 rbegin () const {
Chris@16 882 return const_reverse_iterator1 (end ());
Chris@16 883 }
Chris@16 884 BOOST_UBLAS_INLINE
Chris@16 885 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 886 typename self_type::
Chris@16 887 #endif
Chris@101 888 const_reverse_iterator1 crbegin () const {
Chris@101 889 return rbegin ();
Chris@101 890 }
Chris@101 891 BOOST_UBLAS_INLINE
Chris@101 892 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 893 typename self_type::
Chris@101 894 #endif
Chris@16 895 const_reverse_iterator1 rend () const {
Chris@16 896 return const_reverse_iterator1 (begin ());
Chris@16 897 }
Chris@101 898 BOOST_UBLAS_INLINE
Chris@101 899 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 900 typename self_type::
Chris@101 901 #endif
Chris@101 902 const_reverse_iterator1 crend () const {
Chris@101 903 return rend ();
Chris@101 904 }
Chris@16 905 #endif
Chris@16 906
Chris@16 907 // Indices
Chris@16 908 BOOST_UBLAS_INLINE
Chris@16 909 size_type index1 () const {
Chris@16 910 const self_type &m = (*this) ();
Chris@16 911 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@16 912 }
Chris@16 913 BOOST_UBLAS_INLINE
Chris@16 914 size_type index2 () const {
Chris@16 915 const self_type &m = (*this) ();
Chris@16 916 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@16 917 }
Chris@16 918
Chris@16 919 // Assignment
Chris@16 920 BOOST_UBLAS_INLINE
Chris@16 921 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 922 container_const_reference<self_type>::assign (&it ());
Chris@16 923 it_ = it.it_;
Chris@16 924 return *this;
Chris@16 925 }
Chris@16 926
Chris@16 927 // Comparison
Chris@16 928 BOOST_UBLAS_INLINE
Chris@16 929 bool operator == (const const_iterator2 &it) const {
Chris@16 930 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 931 return it_ == it.it_;
Chris@16 932 }
Chris@16 933 BOOST_UBLAS_INLINE
Chris@16 934 bool operator < (const const_iterator2 &it) const {
Chris@16 935 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 936 return it_ < it.it_;
Chris@16 937 }
Chris@16 938
Chris@16 939 private:
Chris@16 940 const_subiterator_type it_;
Chris@16 941
Chris@16 942 friend class iterator2;
Chris@16 943 };
Chris@16 944 #endif
Chris@16 945
Chris@16 946 BOOST_UBLAS_INLINE
Chris@16 947 const_iterator2 begin2 () const {
Chris@16 948 return find2 (0, 0, 0);
Chris@16 949 }
Chris@16 950 BOOST_UBLAS_INLINE
Chris@101 951 const_iterator2 cbegin2 () const {
Chris@101 952 return begin2 ();
Chris@101 953 }
Chris@101 954 BOOST_UBLAS_INLINE
Chris@16 955 const_iterator2 end2 () const {
Chris@16 956 return find2 (0, 0, size2_);
Chris@16 957 }
Chris@101 958 BOOST_UBLAS_INLINE
Chris@101 959 const_iterator2 cend2 () const {
Chris@101 960 return end2 ();
Chris@101 961 }
Chris@16 962
Chris@16 963 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 964 class iterator2:
Chris@16 965 public container_reference<matrix>,
Chris@16 966 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 967 iterator2, value_type> {
Chris@16 968 public:
Chris@16 969 typedef typename matrix::value_type value_type;
Chris@16 970 typedef typename matrix::difference_type difference_type;
Chris@16 971 typedef typename matrix::reference reference;
Chris@16 972 typedef typename matrix::pointer pointer;
Chris@16 973
Chris@16 974 typedef iterator1 dual_iterator_type;
Chris@16 975 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 976
Chris@16 977 // Construction and destruction
Chris@16 978 BOOST_UBLAS_INLINE
Chris@16 979 iterator2 ():
Chris@16 980 container_reference<self_type> (), it_ () {}
Chris@16 981 BOOST_UBLAS_INLINE
Chris@16 982 iterator2 (self_type &m, const subiterator_type &it):
Chris@16 983 container_reference<self_type> (m), it_ (it) {}
Chris@16 984
Chris@16 985 // Arithmetic
Chris@16 986 BOOST_UBLAS_INLINE
Chris@16 987 iterator2 &operator ++ () {
Chris@16 988 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 989 return *this;
Chris@16 990 }
Chris@16 991 BOOST_UBLAS_INLINE
Chris@16 992 iterator2 &operator -- () {
Chris@16 993 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 994 return *this;
Chris@16 995 }
Chris@16 996 BOOST_UBLAS_INLINE
Chris@16 997 iterator2 &operator += (difference_type n) {
Chris@16 998 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 999 return *this;
Chris@16 1000 }
Chris@16 1001 BOOST_UBLAS_INLINE
Chris@16 1002 iterator2 &operator -= (difference_type n) {
Chris@16 1003 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 1004 return *this;
Chris@16 1005 }
Chris@16 1006 BOOST_UBLAS_INLINE
Chris@16 1007 difference_type operator - (const iterator2 &it) const {
Chris@16 1008 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1009 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@16 1010 }
Chris@16 1011
Chris@16 1012 // Dereference
Chris@16 1013 BOOST_UBLAS_INLINE
Chris@16 1014 reference operator * () const {
Chris@16 1015 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 1016 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 1017 return *it_;
Chris@16 1018 }
Chris@16 1019 BOOST_UBLAS_INLINE
Chris@16 1020 reference operator [] (difference_type n) const {
Chris@16 1021 return *(*this + n);
Chris@16 1022 }
Chris@16 1023
Chris@16 1024 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1025 BOOST_UBLAS_INLINE
Chris@16 1026 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1027 typename self_type::
Chris@16 1028 #endif
Chris@16 1029 iterator1 begin () const {
Chris@16 1030 self_type &m = (*this) ();
Chris@16 1031 return m.find1 (1, 0, index2 ());
Chris@16 1032 }
Chris@16 1033 BOOST_UBLAS_INLINE
Chris@16 1034 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1035 typename self_type::
Chris@16 1036 #endif
Chris@16 1037 iterator1 end () const {
Chris@16 1038 self_type &m = (*this) ();
Chris@16 1039 return m.find1 (1, m.size1 (), index2 ());
Chris@16 1040 }
Chris@16 1041 BOOST_UBLAS_INLINE
Chris@16 1042 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1043 typename self_type::
Chris@16 1044 #endif
Chris@16 1045 reverse_iterator1 rbegin () const {
Chris@16 1046 return reverse_iterator1 (end ());
Chris@16 1047 }
Chris@16 1048 BOOST_UBLAS_INLINE
Chris@16 1049 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1050 typename self_type::
Chris@16 1051 #endif
Chris@16 1052 reverse_iterator1 rend () const {
Chris@16 1053 return reverse_iterator1 (begin ());
Chris@16 1054 }
Chris@16 1055 #endif
Chris@16 1056
Chris@16 1057 // Indices
Chris@16 1058 BOOST_UBLAS_INLINE
Chris@16 1059 size_type index1 () const {
Chris@16 1060 self_type &m = (*this) ();
Chris@16 1061 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@16 1062 }
Chris@16 1063 BOOST_UBLAS_INLINE
Chris@16 1064 size_type index2 () const {
Chris@16 1065 self_type &m = (*this) ();
Chris@16 1066 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@16 1067 }
Chris@16 1068
Chris@16 1069 // Assignment
Chris@16 1070 BOOST_UBLAS_INLINE
Chris@16 1071 iterator2 &operator = (const iterator2 &it) {
Chris@16 1072 container_reference<self_type>::assign (&it ());
Chris@16 1073 it_ = it.it_;
Chris@16 1074 return *this;
Chris@16 1075 }
Chris@16 1076
Chris@16 1077 // Comparison
Chris@16 1078 BOOST_UBLAS_INLINE
Chris@16 1079 bool operator == (const iterator2 &it) const {
Chris@16 1080 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1081 return it_ == it.it_;
Chris@16 1082 }
Chris@16 1083 BOOST_UBLAS_INLINE
Chris@16 1084 bool operator < (const iterator2 &it) const {
Chris@16 1085 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1086 return it_ < it.it_;
Chris@16 1087 }
Chris@16 1088
Chris@16 1089 private:
Chris@16 1090 subiterator_type it_;
Chris@16 1091
Chris@16 1092 friend class const_iterator2;
Chris@16 1093 };
Chris@16 1094 #endif
Chris@16 1095
Chris@16 1096 BOOST_UBLAS_INLINE
Chris@16 1097 iterator2 begin2 () {
Chris@16 1098 return find2 (0, 0, 0);
Chris@16 1099 }
Chris@16 1100 BOOST_UBLAS_INLINE
Chris@16 1101 iterator2 end2 () {
Chris@16 1102 return find2 (0, 0, size2_);
Chris@16 1103 }
Chris@16 1104
Chris@16 1105 // Reverse iterators
Chris@16 1106
Chris@16 1107 BOOST_UBLAS_INLINE
Chris@16 1108 const_reverse_iterator1 rbegin1 () const {
Chris@16 1109 return const_reverse_iterator1 (end1 ());
Chris@16 1110 }
Chris@16 1111 BOOST_UBLAS_INLINE
Chris@101 1112 const_reverse_iterator1 crbegin1 () const {
Chris@101 1113 return rbegin1 ();
Chris@101 1114 }
Chris@101 1115 BOOST_UBLAS_INLINE
Chris@16 1116 const_reverse_iterator1 rend1 () const {
Chris@16 1117 return const_reverse_iterator1 (begin1 ());
Chris@16 1118 }
Chris@101 1119 BOOST_UBLAS_INLINE
Chris@101 1120 const_reverse_iterator1 crend1 () const {
Chris@101 1121 return rend1 ();
Chris@101 1122 }
Chris@16 1123
Chris@16 1124 BOOST_UBLAS_INLINE
Chris@16 1125 reverse_iterator1 rbegin1 () {
Chris@16 1126 return reverse_iterator1 (end1 ());
Chris@16 1127 }
Chris@16 1128 BOOST_UBLAS_INLINE
Chris@16 1129 reverse_iterator1 rend1 () {
Chris@16 1130 return reverse_iterator1 (begin1 ());
Chris@16 1131 }
Chris@16 1132
Chris@16 1133 BOOST_UBLAS_INLINE
Chris@16 1134 const_reverse_iterator2 rbegin2 () const {
Chris@16 1135 return const_reverse_iterator2 (end2 ());
Chris@16 1136 }
Chris@16 1137 BOOST_UBLAS_INLINE
Chris@101 1138 const_reverse_iterator2 crbegin2 () const {
Chris@101 1139 return rbegin2 ();
Chris@101 1140 }
Chris@101 1141 BOOST_UBLAS_INLINE
Chris@16 1142 const_reverse_iterator2 rend2 () const {
Chris@16 1143 return const_reverse_iterator2 (begin2 ());
Chris@16 1144 }
Chris@101 1145 BOOST_UBLAS_INLINE
Chris@101 1146 const_reverse_iterator2 crend2 () const {
Chris@101 1147 return rend2 ();
Chris@101 1148 }
Chris@16 1149
Chris@16 1150 BOOST_UBLAS_INLINE
Chris@16 1151 reverse_iterator2 rbegin2 () {
Chris@16 1152 return reverse_iterator2 (end2 ());
Chris@16 1153 }
Chris@16 1154 BOOST_UBLAS_INLINE
Chris@16 1155 reverse_iterator2 rend2 () {
Chris@16 1156 return reverse_iterator2 (begin2 ());
Chris@16 1157 }
Chris@16 1158
Chris@16 1159 // Serialization
Chris@16 1160 template<class Archive>
Chris@16 1161 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 1162
Chris@16 1163 // we need to copy to a collection_size_type to get a portable
Chris@16 1164 // and efficient serialization
Chris@16 1165 serialization::collection_size_type s1 (size1_);
Chris@16 1166 serialization::collection_size_type s2 (size2_);
Chris@16 1167
Chris@16 1168 // serialize the sizes
Chris@16 1169 ar & serialization::make_nvp("size1",s1)
Chris@16 1170 & serialization::make_nvp("size2",s2);
Chris@16 1171
Chris@16 1172 // copy the values back if loading
Chris@16 1173 if (Archive::is_loading::value) {
Chris@16 1174 size1_ = s1;
Chris@16 1175 size2_ = s2;
Chris@16 1176 }
Chris@16 1177 ar & serialization::make_nvp("data",data_);
Chris@16 1178 }
Chris@16 1179
Chris@16 1180 private:
Chris@16 1181 size_type size1_;
Chris@16 1182 size_type size2_;
Chris@16 1183 array_type data_;
Chris@16 1184 };
Chris@16 1185
Chris@101 1186
Chris@101 1187 #ifdef BOOST_UBLAS_CPP_GE_2011
Chris@101 1188 /** \brief A fixed size dense matrix of values of type \c T. Equivalent to a c-style 2 dimensional array.
Chris@101 1189 *
Chris@101 1190 * For a \f$(m \times n)\f$-dimensional fixed_matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$ m_{i,j} \f$ is mapped to
Chris@101 1191 * 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@101 1192 * the container for column major orientation. In a dense matrix all elements are represented in memory in a
Chris@101 1193 * contiguous chunk of memory by definition.
Chris@101 1194 *
Chris@101 1195 * Orientation and storage can also be specified, otherwise \c row_major and \c std::array are used. It is \b not
Chris@101 1196 * required by the storage container to initialize elements of the matrix.
Chris@101 1197 *
Chris@101 1198 * \tparam T the type of object stored in the matrix (like double, float, std::complex<double>, etc...)
Chris@101 1199 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
Chris@101 1200 * \tparam A the type of Storage array. Default is \c std::array<T, M*N>
Chris@101 1201 */
Chris@101 1202 template<class T, std::size_t M, std::size_t N, class L, class A>
Chris@101 1203 class fixed_matrix:
Chris@101 1204 public matrix_container<fixed_matrix<T, M, N, L, A> > {
Chris@101 1205
Chris@101 1206 typedef T *pointer;
Chris@101 1207 typedef L layout_type;
Chris@101 1208 typedef fixed_matrix<T, M, N, L, A> self_type;
Chris@101 1209 public:
Chris@101 1210 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@101 1211 using matrix_container<self_type>::operator ();
Chris@101 1212 #endif
Chris@101 1213 typedef typename A::size_type size_type;
Chris@101 1214 typedef typename A::difference_type difference_type;
Chris@101 1215 typedef T value_type;
Chris@101 1216 typedef const T &const_reference;
Chris@101 1217 typedef T &reference;
Chris@101 1218 typedef A array_type;
Chris@101 1219 typedef const matrix_reference<const self_type> const_closure_type;
Chris@101 1220 typedef matrix_reference<self_type> closure_type;
Chris@101 1221 typedef vector<T, A> vector_temporary_type;
Chris@101 1222 typedef self_type matrix_temporary_type;
Chris@101 1223 typedef dense_tag storage_category;
Chris@101 1224 // This could be better for performance,
Chris@101 1225 // typedef typename unknown_orientation_tag orientation_category;
Chris@101 1226 // but others depend on the orientation information...
Chris@101 1227 typedef typename L::orientation_category orientation_category;
Chris@101 1228
Chris@101 1229 // Construction and destruction
Chris@101 1230
Chris@101 1231 /// Default dense fixed_matrix constructor. Make a dense fixed_matrix of size M x N
Chris@101 1232 BOOST_UBLAS_INLINE
Chris@101 1233 fixed_matrix ():
Chris@101 1234 matrix_container<self_type> (),
Chris@101 1235 data_ () {}
Chris@101 1236
Chris@101 1237 /// \brief Construct a fixed_matrix from a list of values
Chris@101 1238 /// The list may be included in curly braces. Typical syntax is choices are :
Chris@101 1239 /// fixed_matrix<double, 2,2> v = { 1, 2, 3, 4 } or fixed_matrix<double,4> v( {1, 2, 3, 4} ) or fixed_matrix<double,2,2> v( 1, 2, 3, 4 )
Chris@101 1240 template <typename... Types>
Chris@101 1241 fixed_matrix(value_type v0, Types... vrest) :
Chris@101 1242 matrix_container<self_type> (),
Chris@101 1243 data_{ { v0, vrest... } } {}
Chris@101 1244
Chris@101 1245 /** Dense fixed_matrix constructor with defined initial value for all the matrix elements
Chris@101 1246 * \param init initial value assigned to all elements
Chris@101 1247 */
Chris@101 1248 fixed_matrix (const value_type &init):
Chris@101 1249 matrix_container<self_type> (),
Chris@101 1250 data_ ( ) {
Chris@101 1251 data_.fill(init);
Chris@101 1252 }
Chris@101 1253
Chris@101 1254 /** Dense matrix constructor with defined initial data array
Chris@101 1255 * \param data array to copy into the matrix. Must have the same dimension as the matrix
Chris@101 1256 */
Chris@101 1257 BOOST_UBLAS_INLINE
Chris@101 1258 fixed_matrix (const array_type &data):
Chris@101 1259 matrix_container<self_type> (),
Chris@101 1260 data_ (data) {}
Chris@101 1261
Chris@101 1262 /** Copy-constructor of a dense fixed_matrix
Chris@101 1263 * \param m is a dense fixed_matrix
Chris@101 1264 */
Chris@101 1265 BOOST_UBLAS_INLINE
Chris@101 1266 fixed_matrix (const fixed_matrix &m):
Chris@101 1267 matrix_container<self_type> (),
Chris@101 1268 data_ (m.data_) {}
Chris@101 1269
Chris@101 1270 /** Copy-constructor of a dense matrix from a matrix expression
Chris@101 1271 * \param ae is a matrix expression
Chris@101 1272 */
Chris@101 1273 template<class AE>
Chris@101 1274 BOOST_UBLAS_INLINE
Chris@101 1275 fixed_matrix (const matrix_expression<AE> &ae):
Chris@101 1276 matrix_container<self_type> (),
Chris@101 1277 data_ () {
Chris@101 1278 matrix_assign<scalar_assign> (*this, ae);
Chris@101 1279 }
Chris@101 1280
Chris@101 1281 // Accessors
Chris@101 1282 /** Return the number of rows of the fixed_matrix
Chris@101 1283 * You can also use the free size<>() function in operation/size.hpp as size<1>(m) where m is a fixed_matrix
Chris@101 1284 */
Chris@101 1285 BOOST_UBLAS_INLINE
Chris@101 1286 BOOST_CONSTEXPR size_type size1 () const {
Chris@101 1287 return M;
Chris@101 1288 }
Chris@101 1289
Chris@101 1290 /** Return the number of colums of the fixed_matrix
Chris@101 1291 * You can also use the free size<>() function in operation/size.hpp as size<2>(m) where m is a fixed_matrix
Chris@101 1292 */
Chris@101 1293 BOOST_UBLAS_INLINE
Chris@101 1294 BOOST_CONSTEXPR size_type size2 () const {
Chris@101 1295 return N;
Chris@101 1296 }
Chris@101 1297
Chris@101 1298 // Storage accessors
Chris@101 1299 /** Return a constant reference to the internal storage of a dense matrix, i.e. the raw data
Chris@101 1300 * It's type depends on the type used by the matrix to store its data
Chris@101 1301 */
Chris@101 1302 BOOST_UBLAS_INLINE
Chris@101 1303 const array_type &data () const {
Chris@101 1304 return data_;
Chris@101 1305 }
Chris@101 1306 /** Return a reference to the internal storage of a dense fixed_matrix, i.e. the raw data
Chris@101 1307 * It's type depends on the type used by the fixed_matrix to store its data
Chris@101 1308 */
Chris@101 1309 BOOST_UBLAS_INLINE
Chris@101 1310 array_type &data () {
Chris@101 1311 return data_;
Chris@101 1312 }
Chris@101 1313
Chris@101 1314
Chris@101 1315 // Element access
Chris@101 1316
Chris@101 1317 /** Access a fixed_matrix element. Here we return a const reference
Chris@101 1318 * \param i the first coordinate of the element. By default it's the row
Chris@101 1319 * \param j the second coordinate of the element. By default it's the column
Chris@101 1320 * \return a const reference to the element
Chris@101 1321 */
Chris@101 1322 BOOST_UBLAS_INLINE
Chris@101 1323 const_reference operator () (size_type i, size_type j) const {
Chris@101 1324 return data () [layout_type::element (i, M, j, N)]; // Fixme: add static lookup for element(...) i.e.: element<M, N>(i,j)
Chris@101 1325 }
Chris@101 1326
Chris@101 1327 /** Access a fixed_matrix element. Here we return a reference
Chris@101 1328 * \param i the first coordinate of the element. By default it's the row
Chris@101 1329 * \param j the second coordinate of the element. By default it's the column
Chris@101 1330 * \return a reference to the element
Chris@101 1331 */
Chris@101 1332 BOOST_UBLAS_INLINE
Chris@101 1333 reference at_element (size_type i, size_type j) {
Chris@101 1334 return data () [layout_type::element (i, M, j, N)];
Chris@101 1335 }
Chris@101 1336
Chris@101 1337 /** Access a fixed_matrix element. Here we return a reference
Chris@101 1338 * \param i the first coordinate of the element. By default it's the row
Chris@101 1339 * \param j the second coordinate of the element. By default it's the column
Chris@101 1340 * \return a reference to the element
Chris@101 1341 */
Chris@101 1342 BOOST_UBLAS_INLINE
Chris@101 1343 reference operator () (size_type i, size_type j) {
Chris@101 1344 return at_element (i, j);
Chris@101 1345 }
Chris@101 1346
Chris@101 1347 // Element assignment
Chris@101 1348
Chris@101 1349 /** Change the value of a fixed_matrix element. Return back a reference to it
Chris@101 1350 * \param i the first coordinate of the element. By default it's the row
Chris@101 1351 * \param j the second coordinate of the element. By default it's the column
Chris@101 1352 * \param t the new value of the element
Chris@101 1353 * \return a reference to the newly changed element
Chris@101 1354 */
Chris@101 1355 BOOST_UBLAS_INLINE
Chris@101 1356 reference insert_element (size_type i, size_type j, const_reference t) {
Chris@101 1357 return (at_element (i, j) = t);
Chris@101 1358 }
Chris@101 1359
Chris@101 1360 /** Erase the element
Chris@101 1361 * For most types (int, double, etc...) it means setting 0 (zero) the element at zero in fact.
Chris@101 1362 * For user-defined types, it could be another value if you decided it. Your type in that case must
Chris@101 1363 * contain a default null value.
Chris@101 1364 * \param i the first coordinate of the element. By default it's the row
Chris@101 1365 * \param j the second coordinate of the element. By default it's the column
Chris@101 1366 */
Chris@101 1367 void erase_element (size_type i, size_type j) {
Chris@101 1368 at_element (i, j) = value_type/*zero*/();
Chris@101 1369 }
Chris@101 1370
Chris@101 1371 // Zeroing
Chris@101 1372 /** Erase all elements in the fixed_matrix
Chris@101 1373 * For most types (int, double, etc...) it means writing 0 (zero) everywhere.
Chris@101 1374 * For user-defined types, it could be another value if you decided it. Your type in that case must
Chris@101 1375 * contain a default null value.
Chris@101 1376 */
Chris@101 1377 BOOST_UBLAS_INLINE
Chris@101 1378 void clear () {
Chris@101 1379 std::fill (data ().begin (), data ().end (), value_type/*zero*/());
Chris@101 1380 }
Chris@101 1381
Chris@101 1382 // Assignment
Chris@101 1383 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
Chris@101 1384
Chris@101 1385 /*! @note "pass by value" the key idea to enable move semantics */
Chris@101 1386 BOOST_UBLAS_INLINE
Chris@101 1387 fixed_matrix &operator = (matrix m) {
Chris@101 1388 assign_temporary(m);
Chris@101 1389 return *this;
Chris@101 1390 }
Chris@101 1391 #else
Chris@101 1392 BOOST_UBLAS_INLINE
Chris@101 1393 fixed_matrix &operator = (const fixed_matrix &m) {
Chris@101 1394 data () = m.data ();
Chris@101 1395 return *this;
Chris@101 1396 }
Chris@101 1397 #endif
Chris@101 1398 template<class C> // Container assignment without temporary
Chris@101 1399 BOOST_UBLAS_INLINE
Chris@101 1400 fixed_matrix &operator = (const matrix_container<C> &m) {
Chris@101 1401 resize (m ().size1 (), m ().size2 (), false);
Chris@101 1402 assign (m);
Chris@101 1403 return *this;
Chris@101 1404 }
Chris@101 1405 BOOST_UBLAS_INLINE
Chris@101 1406 fixed_matrix &assign_temporary (fixed_matrix &m) {
Chris@101 1407 swap (m);
Chris@101 1408 return *this;
Chris@101 1409 }
Chris@101 1410 template<class AE>
Chris@101 1411 BOOST_UBLAS_INLINE
Chris@101 1412 fixed_matrix &operator = (const matrix_expression<AE> &ae) {
Chris@101 1413 self_type temporary (ae);
Chris@101 1414 return assign_temporary (temporary);
Chris@101 1415 }
Chris@101 1416 template<class AE>
Chris@101 1417 BOOST_UBLAS_INLINE
Chris@101 1418 fixed_matrix &assign (const matrix_expression<AE> &ae) {
Chris@101 1419 matrix_assign<scalar_assign> (*this, ae);
Chris@101 1420 return *this;
Chris@101 1421 }
Chris@101 1422 template<class AE>
Chris@101 1423 BOOST_UBLAS_INLINE
Chris@101 1424 fixed_matrix& operator += (const matrix_expression<AE> &ae) {
Chris@101 1425 self_type temporary (*this + ae);
Chris@101 1426 return assign_temporary (temporary);
Chris@101 1427 }
Chris@101 1428 template<class C> // Container assignment without temporary
Chris@101 1429 BOOST_UBLAS_INLINE
Chris@101 1430 fixed_matrix &operator += (const matrix_container<C> &m) {
Chris@101 1431 plus_assign (m);
Chris@101 1432 return *this;
Chris@101 1433 }
Chris@101 1434 template<class AE>
Chris@101 1435 BOOST_UBLAS_INLINE
Chris@101 1436 fixed_matrix &plus_assign (const matrix_expression<AE> &ae) {
Chris@101 1437 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@101 1438 return *this;
Chris@101 1439 }
Chris@101 1440 template<class AE>
Chris@101 1441 BOOST_UBLAS_INLINE
Chris@101 1442 fixed_matrix& operator -= (const matrix_expression<AE> &ae) {
Chris@101 1443 self_type temporary (*this - ae);
Chris@101 1444 return assign_temporary (temporary);
Chris@101 1445 }
Chris@101 1446 template<class C> // Container assignment without temporary
Chris@101 1447 BOOST_UBLAS_INLINE
Chris@101 1448 fixed_matrix &operator -= (const matrix_container<C> &m) {
Chris@101 1449 minus_assign (m);
Chris@101 1450 return *this;
Chris@101 1451 }
Chris@101 1452 template<class AE>
Chris@101 1453 BOOST_UBLAS_INLINE
Chris@101 1454 fixed_matrix &minus_assign (const matrix_expression<AE> &ae) {
Chris@101 1455 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@101 1456 return *this;
Chris@101 1457 }
Chris@101 1458 template<class AT>
Chris@101 1459 BOOST_UBLAS_INLINE
Chris@101 1460 fixed_matrix& operator *= (const AT &at) {
Chris@101 1461 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@101 1462 return *this;
Chris@101 1463 }
Chris@101 1464 template<class AT>
Chris@101 1465 BOOST_UBLAS_INLINE
Chris@101 1466 fixed_matrix& operator /= (const AT &at) {
Chris@101 1467 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@101 1468 return *this;
Chris@101 1469 }
Chris@101 1470
Chris@101 1471 // Swapping
Chris@101 1472 BOOST_UBLAS_INLINE
Chris@101 1473 void swap (fixed_matrix &m) {
Chris@101 1474 if (this != &m) {
Chris@101 1475 data ().swap (m.data ());
Chris@101 1476 }
Chris@101 1477 }
Chris@101 1478 BOOST_UBLAS_INLINE
Chris@101 1479 friend void swap (fixed_matrix &m1, fixed_matrix &m2) {
Chris@101 1480 m1.swap (m2);
Chris@101 1481 }
Chris@101 1482
Chris@101 1483 // Iterator types
Chris@101 1484 private:
Chris@101 1485 // Use the storage array iterator
Chris@101 1486 typedef typename A::const_iterator const_subiterator_type;
Chris@101 1487 typedef typename A::iterator subiterator_type;
Chris@101 1488
Chris@101 1489 public:
Chris@101 1490 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 1491 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@101 1492 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@101 1493 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@101 1494 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@101 1495 #else
Chris@101 1496 class const_iterator1;
Chris@101 1497 class iterator1;
Chris@101 1498 class const_iterator2;
Chris@101 1499 class iterator2;
Chris@101 1500 #endif
Chris@101 1501 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@101 1502 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@101 1503 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@101 1504 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@101 1505
Chris@101 1506 // Element lookup
Chris@101 1507 BOOST_UBLAS_INLINE
Chris@101 1508 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
Chris@101 1509 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 1510 return const_iterator1 (*this, i, j);
Chris@101 1511 #else
Chris@101 1512 return const_iterator1 (*this, data ().begin () + layout_type::address (i, M, j, N));
Chris@101 1513 #endif
Chris@101 1514 }
Chris@101 1515 BOOST_UBLAS_INLINE
Chris@101 1516 iterator1 find1 (int /* rank */, size_type i, size_type j) {
Chris@101 1517 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 1518 return iterator1 (*this, i, j);
Chris@101 1519 #else
Chris@101 1520 return iterator1 (*this, data ().begin () + layout_type::address (i, M, j, N));
Chris@101 1521 #endif
Chris@101 1522 }
Chris@101 1523 BOOST_UBLAS_INLINE
Chris@101 1524 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
Chris@101 1525 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 1526 return const_iterator2 (*this, i, j);
Chris@101 1527 #else
Chris@101 1528 return const_iterator2 (*this, data ().begin () + layout_type::address (i, M, j, N));
Chris@101 1529 #endif
Chris@101 1530 }
Chris@101 1531 BOOST_UBLAS_INLINE
Chris@101 1532 iterator2 find2 (int /* rank */, size_type i, size_type j) {
Chris@101 1533 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 1534 return iterator2 (*this, i, j);
Chris@101 1535 #else
Chris@101 1536 return iterator2 (*this, data ().begin () + layout_type::address (i, M, j, N));
Chris@101 1537 #endif
Chris@101 1538 }
Chris@101 1539
Chris@101 1540
Chris@101 1541 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 1542 class const_iterator1:
Chris@101 1543 public container_const_reference<fixed_matrix>,
Chris@101 1544 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@101 1545 const_iterator1, value_type> {
Chris@101 1546 public:
Chris@101 1547 typedef typename fixed_matrix::value_type value_type;
Chris@101 1548 typedef typename fixed_matrix::difference_type difference_type;
Chris@101 1549 typedef typename fixed_matrix::const_reference reference;
Chris@101 1550 typedef const typename fixed_matrix::pointer pointer;
Chris@101 1551
Chris@101 1552 typedef const_iterator2 dual_iterator_type;
Chris@101 1553 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@101 1554
Chris@101 1555 // Construction and destruction
Chris@101 1556 BOOST_UBLAS_INLINE
Chris@101 1557 const_iterator1 ():
Chris@101 1558 container_const_reference<self_type> (), it_ () {}
Chris@101 1559 BOOST_UBLAS_INLINE
Chris@101 1560 const_iterator1 (const self_type &m, const const_subiterator_type &it):
Chris@101 1561 container_const_reference<self_type> (m), it_ (it) {}
Chris@101 1562 BOOST_UBLAS_INLINE
Chris@101 1563 const_iterator1 (const iterator1 &it):
Chris@101 1564 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@101 1565
Chris@101 1566 // Arithmetic
Chris@101 1567 BOOST_UBLAS_INLINE
Chris@101 1568 const_iterator1 &operator ++ () {
Chris@101 1569 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1570 return *this;
Chris@101 1571 }
Chris@101 1572 BOOST_UBLAS_INLINE
Chris@101 1573 const_iterator1 &operator -- () {
Chris@101 1574 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1575 return *this;
Chris@101 1576 }
Chris@101 1577 BOOST_UBLAS_INLINE
Chris@101 1578 const_iterator1 &operator += (difference_type n) {
Chris@101 1579 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1580 return *this;
Chris@101 1581 }
Chris@101 1582 BOOST_UBLAS_INLINE
Chris@101 1583 const_iterator1 &operator -= (difference_type n) {
Chris@101 1584 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1585 return *this;
Chris@101 1586 }
Chris@101 1587 BOOST_UBLAS_INLINE
Chris@101 1588 difference_type operator - (const const_iterator1 &it) const {
Chris@101 1589 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 1590 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1591 }
Chris@101 1592
Chris@101 1593 // Dereference
Chris@101 1594 BOOST_UBLAS_INLINE
Chris@101 1595 const_reference operator * () const {
Chris@101 1596 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@101 1597 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@101 1598 return *it_;
Chris@101 1599 }
Chris@101 1600 BOOST_UBLAS_INLINE
Chris@101 1601 const_reference operator [] (difference_type n) const {
Chris@101 1602 return *(*this + n);
Chris@101 1603 }
Chris@101 1604
Chris@101 1605 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@101 1606 BOOST_UBLAS_INLINE
Chris@101 1607 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1608 typename self_type::
Chris@101 1609 #endif
Chris@101 1610 const_iterator2 begin () const {
Chris@101 1611 const self_type &m = (*this) ();
Chris@101 1612 return m.find2 (1, index1 (), 0);
Chris@101 1613 }
Chris@101 1614 BOOST_UBLAS_INLINE
Chris@101 1615 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1616 typename self_type::
Chris@101 1617 #endif
Chris@101 1618 const_iterator2 cbegin () const {
Chris@101 1619 return begin ();
Chris@101 1620 }
Chris@101 1621 BOOST_UBLAS_INLINE
Chris@101 1622 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1623 typename self_type::
Chris@101 1624 #endif
Chris@101 1625 const_iterator2 end () const {
Chris@101 1626 const self_type &m = (*this) ();
Chris@101 1627 return m.find2 (1, index1 (), m.size2 ());
Chris@101 1628 }
Chris@101 1629 BOOST_UBLAS_INLINE
Chris@101 1630 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1631 typename self_type::
Chris@101 1632 #endif
Chris@101 1633 const_iterator2 cend () const {
Chris@101 1634 return end ();
Chris@101 1635 }
Chris@101 1636 BOOST_UBLAS_INLINE
Chris@101 1637 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1638 typename self_type::
Chris@101 1639 #endif
Chris@101 1640 const_reverse_iterator2 rbegin () const {
Chris@101 1641 return const_reverse_iterator2 (end ());
Chris@101 1642 }
Chris@101 1643 BOOST_UBLAS_INLINE
Chris@101 1644 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1645 typename self_type::
Chris@101 1646 #endif
Chris@101 1647 const_reverse_iterator2 crbegin () const {
Chris@101 1648 return rbegin ();
Chris@101 1649 }
Chris@101 1650 BOOST_UBLAS_INLINE
Chris@101 1651 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1652 typename self_type::
Chris@101 1653 #endif
Chris@101 1654 const_reverse_iterator2 rend () const {
Chris@101 1655 return const_reverse_iterator2 (begin ());
Chris@101 1656 }
Chris@101 1657 BOOST_UBLAS_INLINE
Chris@101 1658 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1659 typename self_type::
Chris@101 1660 #endif
Chris@101 1661 const_reverse_iterator2 crend () const {
Chris@101 1662 return rend ();
Chris@101 1663 }
Chris@101 1664 #endif
Chris@101 1665
Chris@101 1666 // Indices
Chris@101 1667 BOOST_UBLAS_INLINE
Chris@101 1668 size_type index1 () const {
Chris@101 1669 const self_type &m = (*this) ();
Chris@101 1670 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@101 1671 }
Chris@101 1672 BOOST_UBLAS_INLINE
Chris@101 1673 size_type index2 () const {
Chris@101 1674 const self_type &m = (*this) ();
Chris@101 1675 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@101 1676 }
Chris@101 1677
Chris@101 1678 // Assignment
Chris@101 1679 BOOST_UBLAS_INLINE
Chris@101 1680 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@101 1681 container_const_reference<self_type>::assign (&it ());
Chris@101 1682 it_ = it.it_;
Chris@101 1683 return *this;
Chris@101 1684 }
Chris@101 1685
Chris@101 1686 // Comparison
Chris@101 1687 BOOST_UBLAS_INLINE
Chris@101 1688 bool operator == (const const_iterator1 &it) const {
Chris@101 1689 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 1690 return it_ == it.it_;
Chris@101 1691 }
Chris@101 1692 BOOST_UBLAS_INLINE
Chris@101 1693 bool operator < (const const_iterator1 &it) const {
Chris@101 1694 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 1695 return it_ < it.it_;
Chris@101 1696 }
Chris@101 1697
Chris@101 1698 private:
Chris@101 1699 const_subiterator_type it_;
Chris@101 1700
Chris@101 1701 friend class iterator1;
Chris@101 1702 };
Chris@101 1703 #endif
Chris@101 1704
Chris@101 1705 BOOST_UBLAS_INLINE
Chris@101 1706 const_iterator1 begin1 () const {
Chris@101 1707 return find1 (0, 0, 0);
Chris@101 1708 }
Chris@101 1709 BOOST_UBLAS_INLINE
Chris@101 1710 const_iterator1 cbegin1 () const {
Chris@101 1711 return begin1 ();
Chris@101 1712 }
Chris@101 1713 BOOST_UBLAS_INLINE
Chris@101 1714 const_iterator1 end1 () const {
Chris@101 1715 return find1 (0, M, 0);
Chris@101 1716 }
Chris@101 1717 BOOST_UBLAS_INLINE
Chris@101 1718 const_iterator1 cend1 () const {
Chris@101 1719 return end1 ();
Chris@101 1720 }
Chris@101 1721
Chris@101 1722 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 1723 class iterator1:
Chris@101 1724 public container_reference<fixed_matrix>,
Chris@101 1725 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@101 1726 iterator1, value_type> {
Chris@101 1727 public:
Chris@101 1728 typedef typename fixed_matrix::value_type value_type;
Chris@101 1729 typedef typename fixed_matrix::difference_type difference_type;
Chris@101 1730 typedef typename fixed_matrix::reference reference;
Chris@101 1731 typedef typename fixed_matrix::pointer pointer;
Chris@101 1732
Chris@101 1733 typedef iterator2 dual_iterator_type;
Chris@101 1734 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@101 1735
Chris@101 1736 // Construction and destruction
Chris@101 1737 BOOST_UBLAS_INLINE
Chris@101 1738 iterator1 ():
Chris@101 1739 container_reference<self_type> (), it_ () {}
Chris@101 1740 BOOST_UBLAS_INLINE
Chris@101 1741 iterator1 (self_type &m, const subiterator_type &it):
Chris@101 1742 container_reference<self_type> (m), it_ (it) {}
Chris@101 1743
Chris@101 1744 // Arithmetic
Chris@101 1745 BOOST_UBLAS_INLINE
Chris@101 1746 iterator1 &operator ++ () {
Chris@101 1747 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1748 return *this;
Chris@101 1749 }
Chris@101 1750 BOOST_UBLAS_INLINE
Chris@101 1751 iterator1 &operator -- () {
Chris@101 1752 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1753 return *this;
Chris@101 1754 }
Chris@101 1755 BOOST_UBLAS_INLINE
Chris@101 1756 iterator1 &operator += (difference_type n) {
Chris@101 1757 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1758 return *this;
Chris@101 1759 }
Chris@101 1760 BOOST_UBLAS_INLINE
Chris@101 1761 iterator1 &operator -= (difference_type n) {
Chris@101 1762 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1763 return *this;
Chris@101 1764 }
Chris@101 1765 BOOST_UBLAS_INLINE
Chris@101 1766 difference_type operator - (const iterator1 &it) const {
Chris@101 1767 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 1768 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1769 }
Chris@101 1770
Chris@101 1771 // Dereference
Chris@101 1772 BOOST_UBLAS_INLINE
Chris@101 1773 reference operator * () const {
Chris@101 1774 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@101 1775 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@101 1776 return *it_;
Chris@101 1777 }
Chris@101 1778 BOOST_UBLAS_INLINE
Chris@101 1779 reference operator [] (difference_type n) const {
Chris@101 1780 return *(*this + n);
Chris@101 1781 }
Chris@101 1782
Chris@101 1783 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@101 1784 BOOST_UBLAS_INLINE
Chris@101 1785 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1786 typename self_type::
Chris@101 1787 #endif
Chris@101 1788 iterator2 begin () const {
Chris@101 1789 self_type &m = (*this) ();
Chris@101 1790 return m.find2 (1, index1 (), 0);
Chris@101 1791 }
Chris@101 1792 BOOST_UBLAS_INLINE
Chris@101 1793 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1794 typename self_type::
Chris@101 1795 #endif
Chris@101 1796 iterator2 end () const {
Chris@101 1797 self_type &m = (*this) ();
Chris@101 1798 return m.find2 (1, index1 (), m.size2 ());
Chris@101 1799 }
Chris@101 1800 BOOST_UBLAS_INLINE
Chris@101 1801 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1802 typename self_type::
Chris@101 1803 #endif
Chris@101 1804 reverse_iterator2 rbegin () const {
Chris@101 1805 return reverse_iterator2 (end ());
Chris@101 1806 }
Chris@101 1807 BOOST_UBLAS_INLINE
Chris@101 1808 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1809 typename self_type::
Chris@101 1810 #endif
Chris@101 1811 reverse_iterator2 rend () const {
Chris@101 1812 return reverse_iterator2 (begin ());
Chris@101 1813 }
Chris@101 1814 #endif
Chris@101 1815
Chris@101 1816 // Indices
Chris@101 1817 BOOST_UBLAS_INLINE
Chris@101 1818 size_type index1 () const {
Chris@101 1819 self_type &m = (*this) ();
Chris@101 1820 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@101 1821 }
Chris@101 1822 BOOST_UBLAS_INLINE
Chris@101 1823 size_type index2 () const {
Chris@101 1824 self_type &m = (*this) ();
Chris@101 1825 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
Chris@101 1826 }
Chris@101 1827
Chris@101 1828 // Assignment
Chris@101 1829 BOOST_UBLAS_INLINE
Chris@101 1830 iterator1 &operator = (const iterator1 &it) {
Chris@101 1831 container_reference<self_type>::assign (&it ());
Chris@101 1832 it_ = it.it_;
Chris@101 1833 return *this;
Chris@101 1834 }
Chris@101 1835
Chris@101 1836 // Comparison
Chris@101 1837 BOOST_UBLAS_INLINE
Chris@101 1838 bool operator == (const iterator1 &it) const {
Chris@101 1839 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 1840 return it_ == it.it_;
Chris@101 1841 }
Chris@101 1842 BOOST_UBLAS_INLINE
Chris@101 1843 bool operator < (const iterator1 &it) const {
Chris@101 1844 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 1845 return it_ < it.it_;
Chris@101 1846 }
Chris@101 1847
Chris@101 1848 private:
Chris@101 1849 subiterator_type it_;
Chris@101 1850
Chris@101 1851 friend class const_iterator1;
Chris@101 1852 };
Chris@101 1853 #endif
Chris@101 1854
Chris@101 1855 BOOST_UBLAS_INLINE
Chris@101 1856 iterator1 begin1 () {
Chris@101 1857 return find1 (0, 0, 0);
Chris@101 1858 }
Chris@101 1859 BOOST_UBLAS_INLINE
Chris@101 1860 iterator1 end1 () {
Chris@101 1861 return find1 (0, M, 0);
Chris@101 1862 }
Chris@101 1863
Chris@101 1864 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 1865 class const_iterator2:
Chris@101 1866 public container_const_reference<fixed_matrix>,
Chris@101 1867 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@101 1868 const_iterator2, value_type> {
Chris@101 1869 public:
Chris@101 1870 typedef typename fixed_matrix::value_type value_type;
Chris@101 1871 typedef typename fixed_matrix::difference_type difference_type;
Chris@101 1872 typedef typename fixed_matrix::const_reference reference;
Chris@101 1873 typedef const typename fixed_matrix::pointer pointer;
Chris@101 1874
Chris@101 1875 typedef const_iterator1 dual_iterator_type;
Chris@101 1876 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@101 1877
Chris@101 1878 // Construction and destruction
Chris@101 1879 BOOST_UBLAS_INLINE
Chris@101 1880 const_iterator2 ():
Chris@101 1881 container_const_reference<self_type> (), it_ () {}
Chris@101 1882 BOOST_UBLAS_INLINE
Chris@101 1883 const_iterator2 (const self_type &m, const const_subiterator_type &it):
Chris@101 1884 container_const_reference<self_type> (m), it_ (it) {}
Chris@101 1885 BOOST_UBLAS_INLINE
Chris@101 1886 const_iterator2 (const iterator2 &it):
Chris@101 1887 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@101 1888
Chris@101 1889 // Arithmetic
Chris@101 1890 BOOST_UBLAS_INLINE
Chris@101 1891 const_iterator2 &operator ++ () {
Chris@101 1892 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1893 return *this;
Chris@101 1894 }
Chris@101 1895 BOOST_UBLAS_INLINE
Chris@101 1896 const_iterator2 &operator -- () {
Chris@101 1897 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1898 return *this;
Chris@101 1899 }
Chris@101 1900 BOOST_UBLAS_INLINE
Chris@101 1901 const_iterator2 &operator += (difference_type n) {
Chris@101 1902 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1903 return *this;
Chris@101 1904 }
Chris@101 1905 BOOST_UBLAS_INLINE
Chris@101 1906 const_iterator2 &operator -= (difference_type n) {
Chris@101 1907 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1908 return *this;
Chris@101 1909 }
Chris@101 1910 BOOST_UBLAS_INLINE
Chris@101 1911 difference_type operator - (const const_iterator2 &it) const {
Chris@101 1912 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 1913 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 1914 }
Chris@101 1915
Chris@101 1916 // Dereference
Chris@101 1917 BOOST_UBLAS_INLINE
Chris@101 1918 const_reference operator * () const {
Chris@101 1919 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@101 1920 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@101 1921 return *it_;
Chris@101 1922 }
Chris@101 1923 BOOST_UBLAS_INLINE
Chris@101 1924 const_reference operator [] (difference_type n) const {
Chris@101 1925 return *(*this + n);
Chris@101 1926 }
Chris@101 1927
Chris@101 1928 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@101 1929 BOOST_UBLAS_INLINE
Chris@101 1930 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1931 typename self_type::
Chris@101 1932 #endif
Chris@101 1933 const_iterator1 begin () const {
Chris@101 1934 const self_type &m = (*this) ();
Chris@101 1935 return m.find1 (1, 0, index2 ());
Chris@101 1936 }
Chris@101 1937 BOOST_UBLAS_INLINE
Chris@101 1938 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1939 typename self_type::
Chris@101 1940 #endif
Chris@101 1941 const_iterator1 cbegin () const {
Chris@101 1942 return begin ();
Chris@101 1943 }
Chris@101 1944 BOOST_UBLAS_INLINE
Chris@101 1945 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1946 typename self_type::
Chris@101 1947 #endif
Chris@101 1948 const_iterator1 end () const {
Chris@101 1949 const self_type &m = (*this) ();
Chris@101 1950 return m.find1 (1, m.size1 (), index2 ());
Chris@101 1951 }
Chris@101 1952 BOOST_UBLAS_INLINE
Chris@101 1953 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1954 typename self_type::
Chris@101 1955 #endif
Chris@101 1956 const_iterator1 cend () const {
Chris@101 1957 return end ();
Chris@101 1958 }
Chris@101 1959 BOOST_UBLAS_INLINE
Chris@101 1960 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1961 typename self_type::
Chris@101 1962 #endif
Chris@101 1963 const_reverse_iterator1 rbegin () const {
Chris@101 1964 return const_reverse_iterator1 (end ());
Chris@101 1965 }
Chris@101 1966 BOOST_UBLAS_INLINE
Chris@101 1967 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1968 typename self_type::
Chris@101 1969 #endif
Chris@101 1970 const_reverse_iterator1 crbegin () const {
Chris@101 1971 return rbegin ();
Chris@101 1972 }
Chris@101 1973 BOOST_UBLAS_INLINE
Chris@101 1974 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1975 typename self_type::
Chris@101 1976 #endif
Chris@101 1977 const_reverse_iterator1 rend () const {
Chris@101 1978 return const_reverse_iterator1 (begin ());
Chris@101 1979 }
Chris@101 1980 BOOST_UBLAS_INLINE
Chris@101 1981 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1982 typename self_type::
Chris@101 1983 #endif
Chris@101 1984 const_reverse_iterator1 crend () const {
Chris@101 1985 return rend ();
Chris@101 1986 }
Chris@101 1987 #endif
Chris@101 1988
Chris@101 1989 // Indices
Chris@101 1990 BOOST_UBLAS_INLINE
Chris@101 1991 size_type index1 () const {
Chris@101 1992 const self_type &m = (*this) ();
Chris@101 1993 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@101 1994 }
Chris@101 1995 BOOST_UBLAS_INLINE
Chris@101 1996 size_type index2 () const {
Chris@101 1997 const self_type &m = (*this) ();
Chris@101 1998 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@101 1999 }
Chris@101 2000
Chris@101 2001 // Assignment
Chris@101 2002 BOOST_UBLAS_INLINE
Chris@101 2003 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@101 2004 container_const_reference<self_type>::assign (&it ());
Chris@101 2005 it_ = it.it_;
Chris@101 2006 return *this;
Chris@101 2007 }
Chris@101 2008
Chris@101 2009 // Comparison
Chris@101 2010 BOOST_UBLAS_INLINE
Chris@101 2011 bool operator == (const const_iterator2 &it) const {
Chris@101 2012 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 2013 return it_ == it.it_;
Chris@101 2014 }
Chris@101 2015 BOOST_UBLAS_INLINE
Chris@101 2016 bool operator < (const const_iterator2 &it) const {
Chris@101 2017 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 2018 return it_ < it.it_;
Chris@101 2019 }
Chris@101 2020
Chris@101 2021 private:
Chris@101 2022 const_subiterator_type it_;
Chris@101 2023
Chris@101 2024 friend class iterator2;
Chris@101 2025 };
Chris@101 2026 #endif
Chris@101 2027
Chris@101 2028 BOOST_UBLAS_INLINE
Chris@101 2029 const_iterator2 begin2 () const {
Chris@101 2030 return find2 (0, 0, 0);
Chris@101 2031 }
Chris@101 2032 BOOST_UBLAS_INLINE
Chris@101 2033 const_iterator2 cbegin2 () const {
Chris@101 2034 return begin2 ();
Chris@101 2035 }
Chris@101 2036 BOOST_UBLAS_INLINE
Chris@101 2037 const_iterator2 end2 () const {
Chris@101 2038 return find2 (0, 0, N);
Chris@101 2039 }
Chris@101 2040 BOOST_UBLAS_INLINE
Chris@101 2041 const_iterator2 cend2 () const {
Chris@101 2042 return end2 ();
Chris@101 2043 }
Chris@101 2044
Chris@101 2045 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@101 2046 class iterator2:
Chris@101 2047 public container_reference<fixed_matrix>,
Chris@101 2048 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@101 2049 iterator2, value_type> {
Chris@101 2050 public:
Chris@101 2051 typedef typename fixed_matrix::value_type value_type;
Chris@101 2052 typedef typename fixed_matrix::difference_type difference_type;
Chris@101 2053 typedef typename fixed_matrix::reference reference;
Chris@101 2054 typedef typename fixed_matrix::pointer pointer;
Chris@101 2055
Chris@101 2056 typedef iterator1 dual_iterator_type;
Chris@101 2057 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@101 2058
Chris@101 2059 // Construction and destruction
Chris@101 2060 BOOST_UBLAS_INLINE
Chris@101 2061 iterator2 ():
Chris@101 2062 container_reference<self_type> (), it_ () {}
Chris@101 2063 BOOST_UBLAS_INLINE
Chris@101 2064 iterator2 (self_type &m, const subiterator_type &it):
Chris@101 2065 container_reference<self_type> (m), it_ (it) {}
Chris@101 2066
Chris@101 2067 // Arithmetic
Chris@101 2068 BOOST_UBLAS_INLINE
Chris@101 2069 iterator2 &operator ++ () {
Chris@101 2070 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 2071 return *this;
Chris@101 2072 }
Chris@101 2073 BOOST_UBLAS_INLINE
Chris@101 2074 iterator2 &operator -- () {
Chris@101 2075 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 2076 return *this;
Chris@101 2077 }
Chris@101 2078 BOOST_UBLAS_INLINE
Chris@101 2079 iterator2 &operator += (difference_type n) {
Chris@101 2080 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 2081 return *this;
Chris@101 2082 }
Chris@101 2083 BOOST_UBLAS_INLINE
Chris@101 2084 iterator2 &operator -= (difference_type n) {
Chris@101 2085 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 2086 return *this;
Chris@101 2087 }
Chris@101 2088 BOOST_UBLAS_INLINE
Chris@101 2089 difference_type operator - (const iterator2 &it) const {
Chris@101 2090 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 2091 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
Chris@101 2092 }
Chris@101 2093
Chris@101 2094 // Dereference
Chris@101 2095 BOOST_UBLAS_INLINE
Chris@101 2096 reference operator * () const {
Chris@101 2097 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@101 2098 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@101 2099 return *it_;
Chris@101 2100 }
Chris@101 2101 BOOST_UBLAS_INLINE
Chris@101 2102 reference operator [] (difference_type n) const {
Chris@101 2103 return *(*this + n);
Chris@101 2104 }
Chris@101 2105
Chris@101 2106 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@101 2107 BOOST_UBLAS_INLINE
Chris@101 2108 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2109 typename self_type::
Chris@101 2110 #endif
Chris@101 2111 iterator1 begin () const {
Chris@101 2112 self_type &m = (*this) ();
Chris@101 2113 return m.find1 (1, 0, index2 ());
Chris@101 2114 }
Chris@101 2115 BOOST_UBLAS_INLINE
Chris@101 2116 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2117 typename self_type::
Chris@101 2118 #endif
Chris@101 2119 iterator1 end () const {
Chris@101 2120 self_type &m = (*this) ();
Chris@101 2121 return m.find1 (1, m.size1 (), index2 ());
Chris@101 2122 }
Chris@101 2123 BOOST_UBLAS_INLINE
Chris@101 2124 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2125 typename self_type::
Chris@101 2126 #endif
Chris@101 2127 reverse_iterator1 rbegin () const {
Chris@101 2128 return reverse_iterator1 (end ());
Chris@101 2129 }
Chris@101 2130 BOOST_UBLAS_INLINE
Chris@101 2131 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2132 typename self_type::
Chris@101 2133 #endif
Chris@101 2134 reverse_iterator1 rend () const {
Chris@101 2135 return reverse_iterator1 (begin ());
Chris@101 2136 }
Chris@101 2137 #endif
Chris@101 2138
Chris@101 2139 // Indices
Chris@101 2140 BOOST_UBLAS_INLINE
Chris@101 2141 size_type index1 () const {
Chris@101 2142 self_type &m = (*this) ();
Chris@101 2143 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@101 2144 }
Chris@101 2145 BOOST_UBLAS_INLINE
Chris@101 2146 size_type index2 () const {
Chris@101 2147 self_type &m = (*this) ();
Chris@101 2148 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
Chris@101 2149 }
Chris@101 2150
Chris@101 2151 // Assignment
Chris@101 2152 BOOST_UBLAS_INLINE
Chris@101 2153 iterator2 &operator = (const iterator2 &it) {
Chris@101 2154 container_reference<self_type>::assign (&it ());
Chris@101 2155 it_ = it.it_;
Chris@101 2156 return *this;
Chris@101 2157 }
Chris@101 2158
Chris@101 2159 // Comparison
Chris@101 2160 BOOST_UBLAS_INLINE
Chris@101 2161 bool operator == (const iterator2 &it) const {
Chris@101 2162 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 2163 return it_ == it.it_;
Chris@101 2164 }
Chris@101 2165 BOOST_UBLAS_INLINE
Chris@101 2166 bool operator < (const iterator2 &it) const {
Chris@101 2167 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@101 2168 return it_ < it.it_;
Chris@101 2169 }
Chris@101 2170
Chris@101 2171 private:
Chris@101 2172 subiterator_type it_;
Chris@101 2173
Chris@101 2174 friend class const_iterator2;
Chris@101 2175 };
Chris@101 2176 #endif
Chris@101 2177
Chris@101 2178 BOOST_UBLAS_INLINE
Chris@101 2179 iterator2 begin2 () {
Chris@101 2180 return find2 (0, 0, 0);
Chris@101 2181 }
Chris@101 2182 BOOST_UBLAS_INLINE
Chris@101 2183 iterator2 end2 () {
Chris@101 2184 return find2 (0, 0, N);
Chris@101 2185 }
Chris@101 2186
Chris@101 2187 // Reverse iterators
Chris@101 2188
Chris@101 2189 BOOST_UBLAS_INLINE
Chris@101 2190 const_reverse_iterator1 rbegin1 () const {
Chris@101 2191 return const_reverse_iterator1 (end1 ());
Chris@101 2192 }
Chris@101 2193 BOOST_UBLAS_INLINE
Chris@101 2194 const_reverse_iterator1 crbegin1 () const {
Chris@101 2195 return rbegin1 ();
Chris@101 2196 }
Chris@101 2197 BOOST_UBLAS_INLINE
Chris@101 2198 const_reverse_iterator1 rend1 () const {
Chris@101 2199 return const_reverse_iterator1 (begin1 ());
Chris@101 2200 }
Chris@101 2201 BOOST_UBLAS_INLINE
Chris@101 2202 const_reverse_iterator1 crend1 () const {
Chris@101 2203 return rend1 ();
Chris@101 2204 }
Chris@101 2205
Chris@101 2206 BOOST_UBLAS_INLINE
Chris@101 2207 reverse_iterator1 rbegin1 () {
Chris@101 2208 return reverse_iterator1 (end1 ());
Chris@101 2209 }
Chris@101 2210 BOOST_UBLAS_INLINE
Chris@101 2211 reverse_iterator1 rend1 () {
Chris@101 2212 return reverse_iterator1 (begin1 ());
Chris@101 2213 }
Chris@101 2214
Chris@101 2215 BOOST_UBLAS_INLINE
Chris@101 2216 const_reverse_iterator2 rbegin2 () const {
Chris@101 2217 return const_reverse_iterator2 (end2 ());
Chris@101 2218 }
Chris@101 2219 BOOST_UBLAS_INLINE
Chris@101 2220 const_reverse_iterator2 crbegin2 () const {
Chris@101 2221 return rbegin2 ();
Chris@101 2222 }
Chris@101 2223 BOOST_UBLAS_INLINE
Chris@101 2224 const_reverse_iterator2 rend2 () const {
Chris@101 2225 return const_reverse_iterator2 (begin2 ());
Chris@101 2226 }
Chris@101 2227 BOOST_UBLAS_INLINE
Chris@101 2228 const_reverse_iterator2 crend2 () const {
Chris@101 2229 return rend2 ();
Chris@101 2230 }
Chris@101 2231
Chris@101 2232 BOOST_UBLAS_INLINE
Chris@101 2233 reverse_iterator2 rbegin2 () {
Chris@101 2234 return reverse_iterator2 (end2 ());
Chris@101 2235 }
Chris@101 2236 BOOST_UBLAS_INLINE
Chris@101 2237 reverse_iterator2 rend2 () {
Chris@101 2238 return reverse_iterator2 (begin2 ());
Chris@101 2239 }
Chris@101 2240
Chris@101 2241 // Serialization
Chris@101 2242 template<class Archive>
Chris@101 2243 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@101 2244 ar & serialization::make_nvp("data",data_);
Chris@101 2245 }
Chris@101 2246
Chris@101 2247 private:
Chris@101 2248 array_type data_;
Chris@101 2249 };
Chris@101 2250
Chris@101 2251 #endif // BOOST_UBLAS_CPP_GE_2011
Chris@101 2252
Chris@16 2253 /** \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 2254 *
Chris@16 2255 * 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 2256 * 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 2257 * of the container for column major orientation. Finally in a dense matrix all elements are represented in memory
Chris@16 2258 * in a contiguous chunk of memory.
Chris@16 2259 *
Chris@16 2260 * Orientation can be specified. Default is \c row_major
Chris@16 2261 * The default constructor creates the matrix with size \f$M\f$ by \f$N\f$. Elements are constructed by the storage
Chris@16 2262 * type \c bounded_array, which need not initialise their value.
Chris@16 2263 *
Chris@16 2264 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 2265 * \tparam M maximum and default number of rows (if not specified at construction)
Chris@16 2266 * \tparam N maximum and default number of columns (if not specified at construction)
Chris@16 2267 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
Chris@16 2268 */
Chris@16 2269 template<class T, std::size_t M, std::size_t N, class L>
Chris@16 2270 class bounded_matrix:
Chris@16 2271 public matrix<T, L, bounded_array<T, M * N> > {
Chris@16 2272
Chris@16 2273 typedef matrix<T, L, bounded_array<T, M * N> > matrix_type;
Chris@16 2274 public:
Chris@16 2275 typedef typename matrix_type::size_type size_type;
Chris@16 2276 static const size_type max_size1 = M;
Chris@16 2277 static const size_type max_size2 = N;
Chris@16 2278
Chris@16 2279 // Construction and destruction
Chris@16 2280 BOOST_UBLAS_INLINE
Chris@16 2281 bounded_matrix ():
Chris@16 2282 matrix_type (M, N) {}
Chris@16 2283 BOOST_UBLAS_INLINE
Chris@16 2284 bounded_matrix (size_type size1, size_type size2):
Chris@16 2285 matrix_type (size1, size2) {}
Chris@16 2286 BOOST_UBLAS_INLINE
Chris@16 2287 bounded_matrix (const bounded_matrix &m):
Chris@16 2288 matrix_type (m) {}
Chris@16 2289 template<class A2> // Allow matrix<T, L, bounded_array<M,N> > construction
Chris@16 2290 BOOST_UBLAS_INLINE
Chris@16 2291 bounded_matrix (const matrix<T, L, A2> &m):
Chris@16 2292 matrix_type (m) {}
Chris@16 2293 template<class AE>
Chris@16 2294 BOOST_UBLAS_INLINE
Chris@16 2295 bounded_matrix (const matrix_expression<AE> &ae):
Chris@16 2296 matrix_type (ae) {}
Chris@16 2297 BOOST_UBLAS_INLINE
Chris@16 2298 ~bounded_matrix () {}
Chris@16 2299
Chris@16 2300 // Assignment
Chris@16 2301 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
Chris@16 2302
Chris@16 2303 /*! @note "pass by value" the key idea to enable move semantics */
Chris@16 2304 BOOST_UBLAS_INLINE
Chris@16 2305 bounded_matrix &operator = (bounded_matrix m) {
Chris@16 2306 matrix_type::operator = (m);
Chris@16 2307 return *this;
Chris@16 2308 }
Chris@16 2309 #else
Chris@16 2310 BOOST_UBLAS_INLINE
Chris@16 2311 bounded_matrix &operator = (const bounded_matrix &m) {
Chris@16 2312 matrix_type::operator = (m);
Chris@16 2313 return *this;
Chris@16 2314 }
Chris@16 2315 #endif
Chris@16 2316 template<class L2, class A2> // Generic matrix assignment
Chris@16 2317 BOOST_UBLAS_INLINE
Chris@16 2318 bounded_matrix &operator = (const matrix<T, L2, A2> &m) {
Chris@16 2319 matrix_type::operator = (m);
Chris@16 2320 return *this;
Chris@16 2321 }
Chris@16 2322 template<class C> // Container assignment without temporary
Chris@16 2323 BOOST_UBLAS_INLINE
Chris@16 2324 bounded_matrix &operator = (const matrix_container<C> &m) {
Chris@16 2325 matrix_type::operator = (m);
Chris@16 2326 return *this;
Chris@16 2327 }
Chris@16 2328 template<class AE>
Chris@16 2329 BOOST_UBLAS_INLINE
Chris@16 2330 bounded_matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 2331 matrix_type::operator = (ae);
Chris@16 2332 return *this;
Chris@16 2333 }
Chris@16 2334 };
Chris@16 2335
Chris@101 2336
Chris@16 2337 /** \brief A dense matrix of values of type \c T stored as a vector of vectors.
Chris@16 2338 *
Chris@16 2339 * Rows or columns are not stored into contiguous chunks of memory but data inside rows (or columns) are.
Chris@16 2340 * Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used.
Chris@16 2341 * The data is stored as a vector of vectors, meaning that rows or columns might not be stored into contiguous chunks
Chris@16 2342 * of memory. Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used.
Chris@16 2343 * The storage type defaults to \c unbounded_array<unbounded_array<T>> and orientation is \c row_major. It is \b not
Chris@16 2344 * required by the storage to initialize elements of the matrix. For a \f$(m \times n)\f$-dimensional matrix and
Chris@16 2345 * \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 2346 * container for row major orientation or the \f$(i + j.m)\f$-th element of the container for column major orientation.
Chris@16 2347 *
Chris@16 2348 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 2349 * \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 2350 * \tparam A the type of Storage array. By default, it is an \unbounded_array<unbounder_array<T>>
Chris@16 2351 */
Chris@16 2352 template<class T, class L, class A>
Chris@16 2353 class vector_of_vector:
Chris@16 2354 public matrix_container<vector_of_vector<T, L, A> > {
Chris@16 2355
Chris@16 2356 typedef T *pointer;
Chris@16 2357 typedef L layout_type;
Chris@16 2358 typedef vector_of_vector<T, L, A> self_type;
Chris@16 2359 public:
Chris@16 2360 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 2361 using matrix_container<self_type>::operator ();
Chris@16 2362 #endif
Chris@16 2363 typedef typename A::size_type size_type;
Chris@16 2364 typedef typename A::difference_type difference_type;
Chris@16 2365 typedef T value_type;
Chris@16 2366 typedef const T &const_reference;
Chris@16 2367 typedef T &reference;
Chris@16 2368 typedef A array_type;
Chris@16 2369 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 2370 typedef matrix_reference<self_type> closure_type;
Chris@16 2371 typedef vector<T, typename A::value_type> vector_temporary_type;
Chris@16 2372 typedef self_type matrix_temporary_type;
Chris@16 2373 typedef dense_tag storage_category;
Chris@16 2374 // This could be better for performance,
Chris@16 2375 // typedef typename unknown_orientation_tag orientation_category;
Chris@16 2376 // but others depend on the orientation information...
Chris@16 2377 typedef typename L::orientation_category orientation_category;
Chris@16 2378
Chris@16 2379 // Construction and destruction
Chris@16 2380 BOOST_UBLAS_INLINE
Chris@16 2381 vector_of_vector ():
Chris@16 2382 matrix_container<self_type> (),
Chris@16 2383 size1_ (0), size2_ (0), data_ (1) {}
Chris@16 2384 BOOST_UBLAS_INLINE
Chris@16 2385 vector_of_vector (size_type size1, size_type size2):
Chris@16 2386 matrix_container<self_type> (),
Chris@16 2387 size1_ (size1), size2_ (size2), data_ (1) {
Chris@16 2388 resize (size1, size2, true);
Chris@16 2389 }
Chris@16 2390 BOOST_UBLAS_INLINE
Chris@16 2391 vector_of_vector (const vector_of_vector &m):
Chris@16 2392 matrix_container<self_type> (),
Chris@16 2393 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
Chris@16 2394 template<class AE>
Chris@16 2395 BOOST_UBLAS_INLINE
Chris@16 2396 vector_of_vector (const matrix_expression<AE> &ae):
Chris@16 2397 matrix_container<self_type> (),
Chris@16 2398 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) {
Chris@16 2399 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
Chris@16 2400 data ()[k].resize (layout_type::size_m (size1_, size2_));
Chris@16 2401 matrix_assign<scalar_assign> (*this, ae);
Chris@16 2402 }
Chris@16 2403
Chris@16 2404 // Accessors
Chris@16 2405 BOOST_UBLAS_INLINE
Chris@16 2406 size_type size1 () const {
Chris@16 2407 return size1_;
Chris@16 2408 }
Chris@16 2409 BOOST_UBLAS_INLINE
Chris@16 2410 size_type size2 () const {
Chris@16 2411 return size2_;
Chris@16 2412 }
Chris@16 2413
Chris@16 2414 // Storage accessors
Chris@16 2415 BOOST_UBLAS_INLINE
Chris@16 2416 const array_type &data () const {
Chris@16 2417 return data_;
Chris@16 2418 }
Chris@16 2419 BOOST_UBLAS_INLINE
Chris@16 2420 array_type &data () {
Chris@16 2421 return data_;
Chris@16 2422 }
Chris@16 2423
Chris@16 2424 // Resizing
Chris@16 2425 BOOST_UBLAS_INLINE
Chris@16 2426 void resize (size_type size1, size_type size2, bool preserve = true) {
Chris@16 2427 size1_ = size1;
Chris@16 2428 size2_ = size2;
Chris@16 2429 if (preserve)
Chris@16 2430 data ().resize (layout_type::size_M (size1, size2) + 1, typename array_type::value_type ());
Chris@16 2431 else
Chris@16 2432 data ().resize (layout_type::size_M (size1, size2) + 1);
Chris@16 2433 for (size_type k = 0; k < layout_type::size_M (size1, size2); ++ k) {
Chris@16 2434 if (preserve)
Chris@16 2435 data () [k].resize (layout_type::size_m (size1, size2), value_type ());
Chris@16 2436 else
Chris@16 2437 data () [k].resize (layout_type::size_m (size1, size2));
Chris@16 2438 }
Chris@16 2439 }
Chris@16 2440
Chris@16 2441 // Element access
Chris@16 2442 BOOST_UBLAS_INLINE
Chris@16 2443 const_reference operator () (size_type i, size_type j) const {
Chris@16 2444 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
Chris@16 2445 }
Chris@16 2446 BOOST_UBLAS_INLINE
Chris@16 2447 reference at_element (size_type i, size_type j) {
Chris@16 2448 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
Chris@16 2449 }
Chris@16 2450 BOOST_UBLAS_INLINE
Chris@16 2451 reference operator () (size_type i, size_type j) {
Chris@16 2452 return at_element (i, j);
Chris@16 2453 }
Chris@16 2454
Chris@16 2455 // Element assignment
Chris@16 2456 BOOST_UBLAS_INLINE
Chris@16 2457 reference insert_element (size_type i, size_type j, const_reference t) {
Chris@16 2458 return (at_element (i, j) = t);
Chris@16 2459 }
Chris@16 2460 BOOST_UBLAS_INLINE
Chris@16 2461 void erase_element (size_type i, size_type j) {
Chris@16 2462 at_element (i, j) = value_type/*zero*/();
Chris@16 2463 }
Chris@16 2464
Chris@16 2465 // Zeroing
Chris@16 2466 BOOST_UBLAS_INLINE
Chris@16 2467 void clear () {
Chris@16 2468 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
Chris@16 2469 std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/());
Chris@16 2470 }
Chris@16 2471
Chris@16 2472 // Assignment
Chris@16 2473 BOOST_UBLAS_INLINE
Chris@16 2474 vector_of_vector &operator = (const vector_of_vector &m) {
Chris@16 2475 size1_ = m.size1_;
Chris@16 2476 size2_ = m.size2_;
Chris@16 2477 data () = m.data ();
Chris@16 2478 return *this;
Chris@16 2479 }
Chris@16 2480 BOOST_UBLAS_INLINE
Chris@16 2481 vector_of_vector &assign_temporary (vector_of_vector &m) {
Chris@16 2482 swap (m);
Chris@16 2483 return *this;
Chris@16 2484 }
Chris@16 2485 template<class AE>
Chris@16 2486 BOOST_UBLAS_INLINE
Chris@16 2487 vector_of_vector &operator = (const matrix_expression<AE> &ae) {
Chris@16 2488 self_type temporary (ae);
Chris@16 2489 return assign_temporary (temporary);
Chris@16 2490 }
Chris@16 2491 template<class C> // Container assignment without temporary
Chris@16 2492 BOOST_UBLAS_INLINE
Chris@16 2493 vector_of_vector &operator = (const matrix_container<C> &m) {
Chris@16 2494 resize (m ().size1 (), m ().size2 (), false);
Chris@16 2495 assign (m);
Chris@16 2496 return *this;
Chris@16 2497 }
Chris@16 2498 template<class AE>
Chris@16 2499 BOOST_UBLAS_INLINE
Chris@16 2500 vector_of_vector &assign (const matrix_expression<AE> &ae) {
Chris@16 2501 matrix_assign<scalar_assign> (*this, ae);
Chris@16 2502 return *this;
Chris@16 2503 }
Chris@16 2504 template<class AE>
Chris@16 2505 BOOST_UBLAS_INLINE
Chris@16 2506 vector_of_vector& operator += (const matrix_expression<AE> &ae) {
Chris@16 2507 self_type temporary (*this + ae);
Chris@16 2508 return assign_temporary (temporary);
Chris@16 2509 }
Chris@16 2510 template<class C> // Container assignment without temporary
Chris@16 2511 BOOST_UBLAS_INLINE
Chris@16 2512 vector_of_vector &operator += (const matrix_container<C> &m) {
Chris@16 2513 plus_assign (m);
Chris@16 2514 return *this;
Chris@16 2515 }
Chris@16 2516 template<class AE>
Chris@16 2517 BOOST_UBLAS_INLINE
Chris@16 2518 vector_of_vector &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 2519 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 2520 return *this;
Chris@16 2521 }
Chris@16 2522 template<class AE>
Chris@16 2523 BOOST_UBLAS_INLINE
Chris@16 2524 vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
Chris@16 2525 self_type temporary (*this - ae);
Chris@16 2526 return assign_temporary (temporary);
Chris@16 2527 }
Chris@16 2528 template<class C> // Container assignment without temporary
Chris@16 2529 BOOST_UBLAS_INLINE
Chris@16 2530 vector_of_vector &operator -= (const matrix_container<C> &m) {
Chris@16 2531 minus_assign (m);
Chris@16 2532 return *this;
Chris@16 2533 }
Chris@16 2534 template<class AE>
Chris@16 2535 BOOST_UBLAS_INLINE
Chris@16 2536 vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 2537 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 2538 return *this;
Chris@16 2539 }
Chris@16 2540 template<class AT>
Chris@16 2541 BOOST_UBLAS_INLINE
Chris@16 2542 vector_of_vector& operator *= (const AT &at) {
Chris@16 2543 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 2544 return *this;
Chris@16 2545 }
Chris@16 2546 template<class AT>
Chris@16 2547 BOOST_UBLAS_INLINE
Chris@16 2548 vector_of_vector& operator /= (const AT &at) {
Chris@16 2549 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 2550 return *this;
Chris@16 2551 }
Chris@16 2552
Chris@16 2553 // Swapping
Chris@16 2554 BOOST_UBLAS_INLINE
Chris@16 2555 void swap (vector_of_vector &m) {
Chris@16 2556 if (this != &m) {
Chris@16 2557 std::swap (size1_, m.size1_);
Chris@16 2558 std::swap (size2_, m.size2_);
Chris@16 2559 data ().swap (m.data ());
Chris@16 2560 }
Chris@16 2561 }
Chris@16 2562 BOOST_UBLAS_INLINE
Chris@16 2563 friend void swap (vector_of_vector &m1, vector_of_vector &m2) {
Chris@16 2564 m1.swap (m2);
Chris@16 2565 }
Chris@16 2566
Chris@16 2567 // Iterator types
Chris@16 2568 private:
Chris@16 2569 // Use the vector iterator
Chris@16 2570 typedef typename A::value_type::const_iterator const_subiterator_type;
Chris@16 2571 typedef typename A::value_type::iterator subiterator_type;
Chris@16 2572 public:
Chris@16 2573 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2574 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@16 2575 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@16 2576 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 2577 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 2578 #else
Chris@16 2579 class const_iterator1;
Chris@16 2580 class iterator1;
Chris@16 2581 class const_iterator2;
Chris@16 2582 class iterator2;
Chris@16 2583 #endif
Chris@16 2584 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 2585 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 2586 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 2587 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 2588
Chris@16 2589 // Element lookup
Chris@16 2590 BOOST_UBLAS_INLINE
Chris@16 2591 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
Chris@16 2592 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2593 return const_iterator1 (*this, i, j);
Chris@16 2594 #else
Chris@16 2595 return const_iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
Chris@16 2596 #endif
Chris@16 2597 }
Chris@16 2598 BOOST_UBLAS_INLINE
Chris@16 2599 iterator1 find1 (int /*rank*/, size_type i, size_type j) {
Chris@16 2600 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2601 return iterator1 (*this, i, j);
Chris@16 2602 #else
Chris@16 2603 return iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
Chris@16 2604 #endif
Chris@16 2605 }
Chris@16 2606 BOOST_UBLAS_INLINE
Chris@16 2607 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
Chris@16 2608 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2609 return const_iterator2 (*this, i, j);
Chris@16 2610 #else
Chris@16 2611 return const_iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
Chris@16 2612 #endif
Chris@16 2613 }
Chris@16 2614 BOOST_UBLAS_INLINE
Chris@16 2615 iterator2 find2 (int /*rank*/, size_type i, size_type j) {
Chris@16 2616 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2617 return iterator2 (*this, i, j);
Chris@16 2618 #else
Chris@16 2619 return iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
Chris@16 2620 #endif
Chris@16 2621 }
Chris@16 2622
Chris@16 2623
Chris@16 2624 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2625 class const_iterator1:
Chris@16 2626 public container_const_reference<vector_of_vector>,
Chris@16 2627 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 2628 const_iterator1, value_type> {
Chris@16 2629 public:
Chris@16 2630 typedef typename vector_of_vector::value_type value_type;
Chris@16 2631 typedef typename vector_of_vector::difference_type difference_type;
Chris@16 2632 typedef typename vector_of_vector::const_reference reference;
Chris@16 2633 typedef const typename vector_of_vector::pointer pointer;
Chris@16 2634
Chris@16 2635 typedef const_iterator2 dual_iterator_type;
Chris@16 2636 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 2637
Chris@16 2638 // Construction and destruction
Chris@16 2639 BOOST_UBLAS_INLINE
Chris@16 2640 const_iterator1 ():
Chris@16 2641 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
Chris@16 2642 BOOST_UBLAS_INLINE
Chris@16 2643 const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
Chris@16 2644 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
Chris@16 2645 BOOST_UBLAS_INLINE
Chris@16 2646 const_iterator1 (const iterator1 &it):
Chris@16 2647 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
Chris@16 2648
Chris@16 2649 // Arithmetic
Chris@16 2650 BOOST_UBLAS_INLINE
Chris@16 2651 const_iterator1 &operator ++ () {
Chris@16 2652 ++ i_;
Chris@16 2653 const self_type &m = (*this) ();
Chris@16 2654 if (layout_type::fast_i ())
Chris@16 2655 ++ it_;
Chris@16 2656 else
Chris@16 2657 it_ = m.find1 (1, i_, j_).it_;
Chris@16 2658 return *this;
Chris@16 2659 }
Chris@16 2660 BOOST_UBLAS_INLINE
Chris@16 2661 const_iterator1 &operator -- () {
Chris@16 2662 -- i_;
Chris@16 2663 const self_type &m = (*this) ();
Chris@16 2664 if (layout_type::fast_i ())
Chris@16 2665 -- it_;
Chris@16 2666 else
Chris@16 2667 it_ = m.find1 (1, i_, j_).it_;
Chris@16 2668 return *this;
Chris@16 2669 }
Chris@16 2670 BOOST_UBLAS_INLINE
Chris@16 2671 const_iterator1 &operator += (difference_type n) {
Chris@16 2672 i_ += n;
Chris@16 2673 const self_type &m = (*this) ();
Chris@16 2674 it_ = m.find1 (1, i_, j_).it_;
Chris@16 2675 return *this;
Chris@16 2676 }
Chris@16 2677 BOOST_UBLAS_INLINE
Chris@16 2678 const_iterator1 &operator -= (difference_type n) {
Chris@16 2679 i_ -= n;
Chris@16 2680 const self_type &m = (*this) ();
Chris@16 2681 it_ = m.find1 (1, i_, j_).it_;
Chris@16 2682 return *this;
Chris@16 2683 }
Chris@16 2684 BOOST_UBLAS_INLINE
Chris@16 2685 difference_type operator - (const const_iterator1 &it) const {
Chris@16 2686 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2687 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 2688 return index1 () - it.index1 ();
Chris@16 2689 }
Chris@16 2690
Chris@16 2691 // Dereference
Chris@16 2692 BOOST_UBLAS_INLINE
Chris@16 2693 const_reference operator * () const {
Chris@16 2694 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 2695 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 2696 return *it_;
Chris@16 2697 }
Chris@16 2698 BOOST_UBLAS_INLINE
Chris@16 2699 const_reference operator [] (difference_type n) const {
Chris@16 2700 return *(*this + n);
Chris@16 2701 }
Chris@16 2702
Chris@16 2703 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2704 BOOST_UBLAS_INLINE
Chris@16 2705 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2706 typename self_type::
Chris@16 2707 #endif
Chris@16 2708 const_iterator2 begin () const {
Chris@16 2709 const self_type &m = (*this) ();
Chris@16 2710 return m.find2 (1, index1 (), 0);
Chris@16 2711 }
Chris@16 2712 BOOST_UBLAS_INLINE
Chris@16 2713 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2714 typename self_type::
Chris@16 2715 #endif
Chris@101 2716 const_iterator2 cbegin () const {
Chris@101 2717 return begin ();
Chris@101 2718 }
Chris@101 2719 BOOST_UBLAS_INLINE
Chris@101 2720 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2721 typename self_type::
Chris@101 2722 #endif
Chris@16 2723 const_iterator2 end () const {
Chris@16 2724 const self_type &m = (*this) ();
Chris@16 2725 return m.find2 (1, index1 (), m.size2 ());
Chris@16 2726 }
Chris@16 2727 BOOST_UBLAS_INLINE
Chris@16 2728 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2729 typename self_type::
Chris@16 2730 #endif
Chris@101 2731 const_iterator2 cend () const {
Chris@101 2732 return end ();
Chris@101 2733 }
Chris@101 2734 BOOST_UBLAS_INLINE
Chris@101 2735 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2736 typename self_type::
Chris@101 2737 #endif
Chris@16 2738 const_reverse_iterator2 rbegin () const {
Chris@16 2739 return const_reverse_iterator2 (end ());
Chris@16 2740 }
Chris@16 2741 BOOST_UBLAS_INLINE
Chris@16 2742 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2743 typename self_type::
Chris@16 2744 #endif
Chris@101 2745 const_reverse_iterator2 crbegin () const {
Chris@101 2746 return rbegin ();
Chris@101 2747 }
Chris@101 2748 BOOST_UBLAS_INLINE
Chris@101 2749 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2750 typename self_type::
Chris@101 2751 #endif
Chris@16 2752 const_reverse_iterator2 rend () const {
Chris@16 2753 return const_reverse_iterator2 (begin ());
Chris@16 2754 }
Chris@101 2755 BOOST_UBLAS_INLINE
Chris@101 2756 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2757 typename self_type::
Chris@101 2758 #endif
Chris@101 2759 const_reverse_iterator2 crend () const {
Chris@101 2760 return rend ();
Chris@101 2761 }
Chris@16 2762 #endif
Chris@16 2763
Chris@16 2764 // Indices
Chris@16 2765 BOOST_UBLAS_INLINE
Chris@16 2766 size_type index1 () const {
Chris@16 2767 return i_;
Chris@16 2768 }
Chris@16 2769 BOOST_UBLAS_INLINE
Chris@16 2770 size_type index2 () const {
Chris@16 2771 return j_;
Chris@16 2772 }
Chris@16 2773
Chris@16 2774 // Assignment
Chris@16 2775 BOOST_UBLAS_INLINE
Chris@16 2776 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 2777 container_const_reference<self_type>::assign (&it ());
Chris@16 2778 it_ = it.it_;
Chris@16 2779 return *this;
Chris@16 2780 }
Chris@16 2781
Chris@16 2782 // Comparison
Chris@16 2783 BOOST_UBLAS_INLINE
Chris@16 2784 bool operator == (const const_iterator1 &it) const {
Chris@16 2785 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2786 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 2787 return it_ == it.it_;
Chris@16 2788 }
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 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 2793 return it_ < it.it_;
Chris@16 2794 }
Chris@16 2795
Chris@16 2796 private:
Chris@16 2797 size_type i_;
Chris@16 2798 size_type j_;
Chris@16 2799 const_subiterator_type it_;
Chris@16 2800
Chris@16 2801 friend class iterator1;
Chris@16 2802 };
Chris@16 2803 #endif
Chris@16 2804
Chris@16 2805 BOOST_UBLAS_INLINE
Chris@16 2806 const_iterator1 begin1 () const {
Chris@16 2807 return find1 (0, 0, 0);
Chris@16 2808 }
Chris@16 2809 BOOST_UBLAS_INLINE
Chris@101 2810 const_iterator1 cbegin1 () const {
Chris@101 2811 return begin1 ();
Chris@101 2812 }
Chris@101 2813 BOOST_UBLAS_INLINE
Chris@16 2814 const_iterator1 end1 () const {
Chris@16 2815 return find1 (0, size1_, 0);
Chris@16 2816 }
Chris@101 2817 BOOST_UBLAS_INLINE
Chris@101 2818 const_iterator1 cend1 () const {
Chris@101 2819 return end1 ();
Chris@101 2820 }
Chris@16 2821
Chris@16 2822 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2823 class iterator1:
Chris@16 2824 public container_reference<vector_of_vector>,
Chris@16 2825 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 2826 iterator1, value_type> {
Chris@16 2827 public:
Chris@16 2828 typedef typename vector_of_vector::value_type value_type;
Chris@16 2829 typedef typename vector_of_vector::difference_type difference_type;
Chris@16 2830 typedef typename vector_of_vector::reference reference;
Chris@16 2831 typedef typename vector_of_vector::pointer pointer;
Chris@16 2832
Chris@16 2833 typedef iterator2 dual_iterator_type;
Chris@16 2834 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 2835
Chris@16 2836 // Construction and destruction
Chris@16 2837 BOOST_UBLAS_INLINE
Chris@16 2838 iterator1 ():
Chris@16 2839 container_reference<self_type> (), i_ (), j_ (), it_ () {}
Chris@16 2840 BOOST_UBLAS_INLINE
Chris@16 2841 iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it):
Chris@16 2842 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
Chris@16 2843
Chris@16 2844 // Arithmetic
Chris@16 2845 BOOST_UBLAS_INLINE
Chris@16 2846 iterator1 &operator ++ () {
Chris@16 2847 ++ i_;
Chris@16 2848 self_type &m = (*this) ();
Chris@16 2849 if (layout_type::fast_i ())
Chris@16 2850 ++ it_;
Chris@16 2851 else
Chris@16 2852 it_ = m.find1 (1, i_, j_).it_;
Chris@16 2853 return *this;
Chris@16 2854 }
Chris@16 2855 BOOST_UBLAS_INLINE
Chris@16 2856 iterator1 &operator -- () {
Chris@16 2857 -- i_;
Chris@16 2858 self_type &m = (*this) ();
Chris@16 2859 if (layout_type::fast_i ())
Chris@16 2860 -- it_;
Chris@16 2861 else
Chris@16 2862 it_ = m.find1 (1, i_, j_).it_;
Chris@16 2863 return *this;
Chris@16 2864 }
Chris@16 2865 BOOST_UBLAS_INLINE
Chris@16 2866 iterator1 &operator += (difference_type n) {
Chris@16 2867 i_ += n;
Chris@16 2868 self_type &m = (*this) ();
Chris@16 2869 it_ = m.find1 (1, i_, j_).it_;
Chris@16 2870 return *this;
Chris@16 2871 }
Chris@16 2872 BOOST_UBLAS_INLINE
Chris@16 2873 iterator1 &operator -= (difference_type n) {
Chris@16 2874 i_ -= n;
Chris@16 2875 self_type &m = (*this) ();
Chris@16 2876 it_ = m.find1 (1, i_, j_).it_;
Chris@16 2877 return *this;
Chris@16 2878 }
Chris@16 2879 BOOST_UBLAS_INLINE
Chris@16 2880 difference_type operator - (const iterator1 &it) const {
Chris@16 2881 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2882 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 2883 return index1 () - it.index1 ();
Chris@16 2884 }
Chris@16 2885
Chris@16 2886 // Dereference
Chris@16 2887 BOOST_UBLAS_INLINE
Chris@16 2888 reference operator * () const {
Chris@16 2889 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 2890 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 2891 return *it_;
Chris@16 2892 }
Chris@16 2893 BOOST_UBLAS_INLINE
Chris@16 2894 reference operator [] (difference_type n) const {
Chris@16 2895 return *(*this + n);
Chris@16 2896 }
Chris@16 2897
Chris@16 2898 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2899 BOOST_UBLAS_INLINE
Chris@16 2900 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2901 typename self_type::
Chris@16 2902 #endif
Chris@16 2903 iterator2 begin () const {
Chris@16 2904 self_type &m = (*this) ();
Chris@16 2905 return m.find2 (1, index1 (), 0);
Chris@16 2906 }
Chris@16 2907 BOOST_UBLAS_INLINE
Chris@16 2908 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2909 typename self_type::
Chris@16 2910 #endif
Chris@16 2911 iterator2 end () const {
Chris@16 2912 self_type &m = (*this) ();
Chris@16 2913 return m.find2 (1, index1 (), m.size2 ());
Chris@16 2914 }
Chris@16 2915 BOOST_UBLAS_INLINE
Chris@16 2916 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2917 typename self_type::
Chris@16 2918 #endif
Chris@16 2919 reverse_iterator2 rbegin () const {
Chris@16 2920 return reverse_iterator2 (end ());
Chris@16 2921 }
Chris@16 2922 BOOST_UBLAS_INLINE
Chris@16 2923 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2924 typename self_type::
Chris@16 2925 #endif
Chris@16 2926 reverse_iterator2 rend () const {
Chris@16 2927 return reverse_iterator2 (begin ());
Chris@16 2928 }
Chris@16 2929 #endif
Chris@16 2930
Chris@16 2931 // Indices
Chris@16 2932 BOOST_UBLAS_INLINE
Chris@16 2933 size_type index1 () const {
Chris@16 2934 return i_;
Chris@16 2935 }
Chris@16 2936 BOOST_UBLAS_INLINE
Chris@16 2937 size_type index2 () const {
Chris@16 2938 return j_;
Chris@16 2939 }
Chris@16 2940
Chris@16 2941 // Assignment
Chris@16 2942 BOOST_UBLAS_INLINE
Chris@16 2943 iterator1 &operator = (const iterator1 &it) {
Chris@16 2944 container_reference<self_type>::assign (&it ());
Chris@16 2945 it_ = it.it_;
Chris@16 2946 return *this;
Chris@16 2947 }
Chris@16 2948
Chris@16 2949 // Comparison
Chris@16 2950 BOOST_UBLAS_INLINE
Chris@16 2951 bool operator == (const iterator1 &it) const {
Chris@16 2952 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2953 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 2954 return it_ == it.it_;
Chris@16 2955 }
Chris@16 2956 BOOST_UBLAS_INLINE
Chris@16 2957 bool operator < (const iterator1 &it) const {
Chris@16 2958 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2959 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
Chris@16 2960 return it_ < it.it_;
Chris@16 2961 }
Chris@16 2962
Chris@16 2963 private:
Chris@16 2964 size_type i_;
Chris@16 2965 size_type j_;
Chris@16 2966 subiterator_type it_;
Chris@16 2967
Chris@16 2968 friend class const_iterator1;
Chris@16 2969 };
Chris@16 2970 #endif
Chris@16 2971
Chris@16 2972 BOOST_UBLAS_INLINE
Chris@16 2973 iterator1 begin1 () {
Chris@16 2974 return find1 (0, 0, 0);
Chris@16 2975 }
Chris@16 2976 BOOST_UBLAS_INLINE
Chris@16 2977 iterator1 end1 () {
Chris@16 2978 return find1 (0, size1_, 0);
Chris@16 2979 }
Chris@16 2980
Chris@16 2981 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2982 class const_iterator2:
Chris@16 2983 public container_const_reference<vector_of_vector>,
Chris@16 2984 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 2985 const_iterator2, value_type> {
Chris@16 2986 public:
Chris@16 2987 typedef typename vector_of_vector::value_type value_type;
Chris@16 2988 typedef typename vector_of_vector::difference_type difference_type;
Chris@16 2989 typedef typename vector_of_vector::const_reference reference;
Chris@16 2990 typedef const typename vector_of_vector::pointer pointer;
Chris@16 2991
Chris@16 2992 typedef const_iterator1 dual_iterator_type;
Chris@16 2993 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 2994
Chris@16 2995 // Construction and destruction
Chris@16 2996 BOOST_UBLAS_INLINE
Chris@16 2997 const_iterator2 ():
Chris@16 2998 container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
Chris@16 2999 BOOST_UBLAS_INLINE
Chris@16 3000 const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
Chris@16 3001 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
Chris@16 3002 BOOST_UBLAS_INLINE
Chris@16 3003 const_iterator2 (const iterator2 &it):
Chris@16 3004 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
Chris@16 3005
Chris@16 3006 // Arithmetic
Chris@16 3007 BOOST_UBLAS_INLINE
Chris@16 3008 const_iterator2 &operator ++ () {
Chris@16 3009 ++ j_;
Chris@16 3010 const self_type &m = (*this) ();
Chris@16 3011 if (layout_type::fast_j ())
Chris@16 3012 ++ it_;
Chris@16 3013 else
Chris@16 3014 it_ = m.find2 (1, i_, j_).it_;
Chris@16 3015 return *this;
Chris@16 3016 }
Chris@16 3017 BOOST_UBLAS_INLINE
Chris@16 3018 const_iterator2 &operator -- () {
Chris@16 3019 -- j_;
Chris@16 3020 const self_type &m = (*this) ();
Chris@16 3021 if (layout_type::fast_j ())
Chris@16 3022 -- it_;
Chris@16 3023 else
Chris@16 3024 it_ = m.find2 (1, i_, j_).it_;
Chris@16 3025 return *this;
Chris@16 3026 }
Chris@16 3027 BOOST_UBLAS_INLINE
Chris@16 3028 const_iterator2 &operator += (difference_type n) {
Chris@16 3029 j_ += n;
Chris@16 3030 const self_type &m = (*this) ();
Chris@16 3031 it_ = m.find2 (1, i_, j_).it_;
Chris@16 3032 return *this;
Chris@16 3033 }
Chris@16 3034 BOOST_UBLAS_INLINE
Chris@16 3035 const_iterator2 &operator -= (difference_type n) {
Chris@16 3036 j_ -= n;
Chris@16 3037 const self_type &m = (*this) ();
Chris@16 3038 it_ = m.find2 (1, i_, j_).it_;
Chris@16 3039 return *this;
Chris@16 3040 }
Chris@16 3041 BOOST_UBLAS_INLINE
Chris@16 3042 difference_type operator - (const const_iterator2 &it) const {
Chris@16 3043 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3044 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 3045 return index2 () - it.index2 ();
Chris@16 3046 }
Chris@16 3047
Chris@16 3048 // Dereference
Chris@16 3049 BOOST_UBLAS_INLINE
Chris@16 3050 const_reference operator * () const {
Chris@16 3051 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 3052 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 3053 return *it_;
Chris@16 3054 }
Chris@16 3055 BOOST_UBLAS_INLINE
Chris@16 3056 const_reference operator [] (difference_type n) const {
Chris@16 3057 return *(*this + n);
Chris@16 3058 }
Chris@16 3059
Chris@16 3060 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 3061 BOOST_UBLAS_INLINE
Chris@16 3062 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3063 typename self_type::
Chris@16 3064 #endif
Chris@16 3065 const_iterator1 begin () const {
Chris@16 3066 const self_type &m = (*this) ();
Chris@16 3067 return m.find1 (1, 0, index2 ());
Chris@16 3068 }
Chris@16 3069 BOOST_UBLAS_INLINE
Chris@16 3070 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3071 typename self_type::
Chris@16 3072 #endif
Chris@101 3073 const_iterator1 cbegin () const {
Chris@101 3074 return begin ();
Chris@101 3075 }
Chris@101 3076 BOOST_UBLAS_INLINE
Chris@101 3077 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3078 typename self_type::
Chris@101 3079 #endif
Chris@16 3080 const_iterator1 end () const {
Chris@16 3081 const self_type &m = (*this) ();
Chris@16 3082 return m.find1 (1, m.size1 (), index2 ());
Chris@16 3083 }
Chris@16 3084 BOOST_UBLAS_INLINE
Chris@16 3085 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3086 typename self_type::
Chris@16 3087 #endif
Chris@101 3088 const_iterator1 cend () const {
Chris@101 3089 return end ();
Chris@101 3090 }
Chris@101 3091 BOOST_UBLAS_INLINE
Chris@101 3092 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3093 typename self_type::
Chris@101 3094 #endif
Chris@16 3095 const_reverse_iterator1 rbegin () const {
Chris@16 3096 return const_reverse_iterator1 (end ());
Chris@16 3097 }
Chris@16 3098 BOOST_UBLAS_INLINE
Chris@16 3099 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3100 typename self_type::
Chris@16 3101 #endif
Chris@101 3102 const_reverse_iterator1 crbegin () const {
Chris@101 3103 return rbegin ();
Chris@101 3104 }
Chris@101 3105 BOOST_UBLAS_INLINE
Chris@101 3106 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3107 typename self_type::
Chris@101 3108 #endif
Chris@16 3109 const_reverse_iterator1 rend () const {
Chris@16 3110 return const_reverse_iterator1 (begin ());
Chris@16 3111 }
Chris@101 3112 BOOST_UBLAS_INLINE
Chris@101 3113 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3114 typename self_type::
Chris@101 3115 #endif
Chris@101 3116 const_reverse_iterator2 crend () const {
Chris@101 3117 return rend ();
Chris@101 3118 }
Chris@16 3119 #endif
Chris@16 3120
Chris@16 3121 // Indices
Chris@16 3122 BOOST_UBLAS_INLINE
Chris@16 3123 size_type index1 () const {
Chris@16 3124 return i_;
Chris@16 3125 }
Chris@16 3126 BOOST_UBLAS_INLINE
Chris@16 3127 size_type index2 () const {
Chris@16 3128 return j_;
Chris@16 3129 }
Chris@16 3130
Chris@16 3131 // Assignment
Chris@16 3132 BOOST_UBLAS_INLINE
Chris@16 3133 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 3134 container_const_reference<self_type>::assign (&it ());
Chris@16 3135 it_ = it.it_;
Chris@16 3136 return *this;
Chris@16 3137 }
Chris@16 3138
Chris@16 3139 // Comparison
Chris@16 3140 BOOST_UBLAS_INLINE
Chris@16 3141 bool operator == (const const_iterator2 &it) const {
Chris@16 3142 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3143 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 3144 return it_ == it.it_;
Chris@16 3145 }
Chris@16 3146 BOOST_UBLAS_INLINE
Chris@16 3147 bool operator < (const const_iterator2 &it) const {
Chris@16 3148 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3149 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 3150 return it_ < it.it_;
Chris@16 3151 }
Chris@16 3152
Chris@16 3153 private:
Chris@16 3154 size_type i_;
Chris@16 3155 size_type j_;
Chris@16 3156 const_subiterator_type it_;
Chris@16 3157
Chris@16 3158 friend class iterator2;
Chris@16 3159 };
Chris@16 3160 #endif
Chris@16 3161
Chris@16 3162 BOOST_UBLAS_INLINE
Chris@16 3163 const_iterator2 begin2 () const {
Chris@16 3164 return find2 (0, 0, 0);
Chris@16 3165 }
Chris@16 3166 BOOST_UBLAS_INLINE
Chris@101 3167 const_iterator2 cbegin2 () const {
Chris@101 3168 return begin2 ();
Chris@101 3169 }
Chris@101 3170 BOOST_UBLAS_INLINE
Chris@16 3171 const_iterator2 end2 () const {
Chris@16 3172 return find2 (0, 0, size2_);
Chris@16 3173 }
Chris@101 3174 BOOST_UBLAS_INLINE
Chris@101 3175 const_iterator2 cend2 () const {
Chris@101 3176 return end2 ();
Chris@101 3177 }
Chris@16 3178
Chris@16 3179 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 3180 class iterator2:
Chris@16 3181 public container_reference<vector_of_vector>,
Chris@16 3182 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 3183 iterator2, value_type> {
Chris@16 3184 public:
Chris@16 3185 typedef typename vector_of_vector::value_type value_type;
Chris@16 3186 typedef typename vector_of_vector::difference_type difference_type;
Chris@16 3187 typedef typename vector_of_vector::reference reference;
Chris@16 3188 typedef typename vector_of_vector::pointer pointer;
Chris@16 3189
Chris@16 3190 typedef iterator1 dual_iterator_type;
Chris@16 3191 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 3192
Chris@16 3193 // Construction and destruction
Chris@16 3194 BOOST_UBLAS_INLINE
Chris@16 3195 iterator2 ():
Chris@16 3196 container_reference<self_type> (), i_ (), j_ (), it_ () {}
Chris@16 3197 BOOST_UBLAS_INLINE
Chris@16 3198 iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it):
Chris@16 3199 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
Chris@16 3200
Chris@16 3201 // Arithmetic
Chris@16 3202 BOOST_UBLAS_INLINE
Chris@16 3203 iterator2 &operator ++ () {
Chris@16 3204 ++ j_;
Chris@16 3205 self_type &m = (*this) ();
Chris@16 3206 if (layout_type::fast_j ())
Chris@16 3207 ++ it_;
Chris@16 3208 else
Chris@16 3209 it_ = m.find2 (1, i_, j_).it_;
Chris@16 3210 return *this;
Chris@16 3211 }
Chris@16 3212 BOOST_UBLAS_INLINE
Chris@16 3213 iterator2 &operator -- () {
Chris@16 3214 -- j_;
Chris@16 3215 self_type &m = (*this) ();
Chris@16 3216 if (layout_type::fast_j ())
Chris@16 3217 -- it_;
Chris@16 3218 else
Chris@16 3219 it_ = m.find2 (1, i_, j_).it_;
Chris@16 3220 return *this;
Chris@16 3221 }
Chris@16 3222 BOOST_UBLAS_INLINE
Chris@16 3223 iterator2 &operator += (difference_type n) {
Chris@16 3224 j_ += n;
Chris@16 3225 self_type &m = (*this) ();
Chris@16 3226 it_ = m.find2 (1, i_, j_).it_;
Chris@16 3227 return *this;
Chris@16 3228 }
Chris@16 3229 BOOST_UBLAS_INLINE
Chris@16 3230 iterator2 &operator -= (difference_type n) {
Chris@16 3231 j_ -= n;
Chris@16 3232 self_type &m = (*this) ();
Chris@16 3233 it_ = m.find2 (1, i_, j_).it_;
Chris@16 3234 return *this;
Chris@16 3235 }
Chris@16 3236 BOOST_UBLAS_INLINE
Chris@16 3237 difference_type operator - (const iterator2 &it) const {
Chris@16 3238 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3239 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 3240 return index2 () - it.index2 ();
Chris@16 3241 }
Chris@16 3242
Chris@16 3243 // Dereference
Chris@16 3244 BOOST_UBLAS_INLINE
Chris@16 3245 reference operator * () const {
Chris@16 3246 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 3247 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 3248 return *it_;
Chris@16 3249 }
Chris@16 3250 BOOST_UBLAS_INLINE
Chris@16 3251 reference operator [] (difference_type n) const {
Chris@16 3252 return *(*this + n);
Chris@16 3253 }
Chris@16 3254
Chris@16 3255 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 3256 BOOST_UBLAS_INLINE
Chris@16 3257 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3258 typename self_type::
Chris@16 3259 #endif
Chris@16 3260 iterator1 begin () const {
Chris@16 3261 self_type &m = (*this) ();
Chris@16 3262 return m.find1 (1, 0, index2 ());
Chris@16 3263 }
Chris@16 3264 BOOST_UBLAS_INLINE
Chris@16 3265 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3266 typename self_type::
Chris@16 3267 #endif
Chris@16 3268 iterator1 end () const {
Chris@16 3269 self_type &m = (*this) ();
Chris@16 3270 return m.find1 (1, m.size1 (), index2 ());
Chris@16 3271 }
Chris@16 3272 BOOST_UBLAS_INLINE
Chris@16 3273 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3274 typename self_type::
Chris@16 3275 #endif
Chris@16 3276 reverse_iterator1 rbegin () const {
Chris@16 3277 return reverse_iterator1 (end ());
Chris@16 3278 }
Chris@16 3279 BOOST_UBLAS_INLINE
Chris@16 3280 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3281 typename self_type::
Chris@16 3282 #endif
Chris@16 3283 reverse_iterator1 rend () const {
Chris@16 3284 return reverse_iterator1 (begin ());
Chris@16 3285 }
Chris@16 3286 #endif
Chris@16 3287
Chris@16 3288 // Indices
Chris@16 3289 BOOST_UBLAS_INLINE
Chris@16 3290 size_type index1 () const {
Chris@16 3291 return i_;
Chris@16 3292 }
Chris@16 3293 BOOST_UBLAS_INLINE
Chris@16 3294 size_type index2 () const {
Chris@16 3295 return j_;
Chris@16 3296 }
Chris@16 3297
Chris@16 3298 // Assignment
Chris@16 3299 BOOST_UBLAS_INLINE
Chris@16 3300 iterator2 &operator = (const iterator2 &it) {
Chris@16 3301 container_reference<self_type>::assign (&it ());
Chris@16 3302 it_ = it.it_;
Chris@16 3303 return *this;
Chris@16 3304 }
Chris@16 3305
Chris@16 3306 // Comparison
Chris@16 3307 BOOST_UBLAS_INLINE
Chris@16 3308 bool operator == (const iterator2 &it) const {
Chris@16 3309 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3310 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 3311 return it_ == it.it_;
Chris@16 3312 }
Chris@16 3313 BOOST_UBLAS_INLINE
Chris@16 3314 bool operator < (const iterator2 &it) const {
Chris@16 3315 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3316 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
Chris@16 3317 return it_ < it.it_;
Chris@16 3318 }
Chris@16 3319
Chris@16 3320 private:
Chris@16 3321 size_type i_;
Chris@16 3322 size_type j_;
Chris@16 3323 subiterator_type it_;
Chris@16 3324
Chris@16 3325 friend class const_iterator2;
Chris@16 3326 };
Chris@16 3327 #endif
Chris@16 3328
Chris@16 3329 BOOST_UBLAS_INLINE
Chris@16 3330 iterator2 begin2 () {
Chris@16 3331 return find2 (0, 0, 0);
Chris@16 3332 }
Chris@16 3333 BOOST_UBLAS_INLINE
Chris@16 3334 iterator2 end2 () {
Chris@16 3335 return find2 (0, 0, size2_);
Chris@16 3336 }
Chris@16 3337
Chris@16 3338 // Reverse iterators
Chris@16 3339
Chris@16 3340 BOOST_UBLAS_INLINE
Chris@16 3341 const_reverse_iterator1 rbegin1 () const {
Chris@16 3342 return const_reverse_iterator1 (end1 ());
Chris@16 3343 }
Chris@16 3344 BOOST_UBLAS_INLINE
Chris@101 3345 const_reverse_iterator1 crbegin1 () const {
Chris@101 3346 return rbegin1 ();
Chris@101 3347 }
Chris@101 3348 BOOST_UBLAS_INLINE
Chris@16 3349 const_reverse_iterator1 rend1 () const {
Chris@16 3350 return const_reverse_iterator1 (begin1 ());
Chris@16 3351 }
Chris@101 3352 BOOST_UBLAS_INLINE
Chris@101 3353 const_reverse_iterator1 crend1 () const {
Chris@101 3354 return rend1 ();
Chris@101 3355 }
Chris@16 3356
Chris@16 3357 BOOST_UBLAS_INLINE
Chris@16 3358 reverse_iterator1 rbegin1 () {
Chris@16 3359 return reverse_iterator1 (end1 ());
Chris@16 3360 }
Chris@16 3361 BOOST_UBLAS_INLINE
Chris@16 3362 reverse_iterator1 rend1 () {
Chris@16 3363 return reverse_iterator1 (begin1 ());
Chris@16 3364 }
Chris@16 3365
Chris@16 3366 BOOST_UBLAS_INLINE
Chris@16 3367 const_reverse_iterator2 rbegin2 () const {
Chris@16 3368 return const_reverse_iterator2 (end2 ());
Chris@16 3369 }
Chris@16 3370 BOOST_UBLAS_INLINE
Chris@101 3371 const_reverse_iterator2 crbegin2 () const {
Chris@101 3372 return rbegin2 ();
Chris@101 3373 }
Chris@101 3374 BOOST_UBLAS_INLINE
Chris@16 3375 const_reverse_iterator2 rend2 () const {
Chris@16 3376 return const_reverse_iterator2 (begin2 ());
Chris@16 3377 }
Chris@101 3378 BOOST_UBLAS_INLINE
Chris@101 3379 const_reverse_iterator2 crend2 () const {
Chris@101 3380 return rend2 ();
Chris@101 3381 }
Chris@16 3382
Chris@16 3383 BOOST_UBLAS_INLINE
Chris@16 3384 reverse_iterator2 rbegin2 () {
Chris@16 3385 return reverse_iterator2 (end2 ());
Chris@16 3386 }
Chris@16 3387 BOOST_UBLAS_INLINE
Chris@16 3388 reverse_iterator2 rend2 () {
Chris@16 3389 return reverse_iterator2 (begin2 ());
Chris@16 3390 }
Chris@16 3391
Chris@16 3392 // Serialization
Chris@16 3393 template<class Archive>
Chris@16 3394 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 3395
Chris@16 3396 // we need to copy to a collection_size_type to get a portable
Chris@16 3397 // and efficient serialization
Chris@16 3398 serialization::collection_size_type s1 (size1_);
Chris@16 3399 serialization::collection_size_type s2 (size2_);
Chris@16 3400
Chris@16 3401 // serialize the sizes
Chris@16 3402 ar & serialization::make_nvp("size1",s1)
Chris@16 3403 & serialization::make_nvp("size2",s2);
Chris@16 3404
Chris@16 3405 // copy the values back if loading
Chris@16 3406 if (Archive::is_loading::value) {
Chris@16 3407 size1_ = s1;
Chris@16 3408 size2_ = s2;
Chris@16 3409 }
Chris@16 3410 ar & serialization::make_nvp("data",data_);
Chris@16 3411 }
Chris@16 3412
Chris@16 3413 private:
Chris@16 3414 size_type size1_;
Chris@16 3415 size_type size2_;
Chris@16 3416 array_type data_;
Chris@16 3417 };
Chris@16 3418
Chris@16 3419
Chris@16 3420 /** \brief A matrix with all values of type \c T equal to zero
Chris@16 3421 *
Chris@16 3422 * Changing values does not affect the matrix, however assigning it to a normal matrix will put zero
Chris@16 3423 * everywhere in the target matrix. All accesses are constant time, due to the trivial value.
Chris@16 3424 *
Chris@16 3425 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 3426 * \tparam ALLOC an allocator for storing the zero element. By default, a standar allocator is used.
Chris@16 3427 */
Chris@16 3428 template<class T, class ALLOC>
Chris@16 3429 class zero_matrix:
Chris@16 3430 public matrix_container<zero_matrix<T, ALLOC> > {
Chris@16 3431
Chris@16 3432 typedef const T *const_pointer;
Chris@16 3433 typedef zero_matrix<T, ALLOC> self_type;
Chris@16 3434 public:
Chris@16 3435 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 3436 using matrix_container<self_type>::operator ();
Chris@16 3437 #endif
Chris@16 3438 typedef typename ALLOC::size_type size_type;
Chris@16 3439 typedef typename ALLOC::difference_type difference_type;
Chris@16 3440 typedef T value_type;
Chris@16 3441 typedef const T &const_reference;
Chris@16 3442 typedef T &reference;
Chris@16 3443 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 3444 typedef matrix_reference<self_type> closure_type;
Chris@16 3445 typedef sparse_tag storage_category;
Chris@16 3446 typedef unknown_orientation_tag orientation_category;
Chris@16 3447
Chris@16 3448 // Construction and destruction
Chris@16 3449 BOOST_UBLAS_INLINE
Chris@16 3450 zero_matrix ():
Chris@16 3451 matrix_container<self_type> (),
Chris@16 3452 size1_ (0), size2_ (0) {}
Chris@16 3453 BOOST_UBLAS_INLINE
Chris@16 3454 zero_matrix (size_type size):
Chris@16 3455 matrix_container<self_type> (),
Chris@16 3456 size1_ (size), size2_ (size) {}
Chris@16 3457 BOOST_UBLAS_INLINE
Chris@16 3458 zero_matrix (size_type size1, size_type size2):
Chris@16 3459 matrix_container<self_type> (),
Chris@16 3460 size1_ (size1), size2_ (size2) {}
Chris@16 3461 BOOST_UBLAS_INLINE
Chris@16 3462 zero_matrix (const zero_matrix &m):
Chris@16 3463 matrix_container<self_type> (),
Chris@16 3464 size1_ (m.size1_), size2_ (m.size2_) {}
Chris@16 3465
Chris@16 3466 // Accessors
Chris@16 3467 BOOST_UBLAS_INLINE
Chris@16 3468 size_type size1 () const {
Chris@16 3469 return size1_;
Chris@16 3470 }
Chris@16 3471 BOOST_UBLAS_INLINE
Chris@16 3472 size_type size2 () const {
Chris@16 3473 return size2_;
Chris@16 3474 }
Chris@16 3475
Chris@16 3476 // Resizing
Chris@16 3477 BOOST_UBLAS_INLINE
Chris@101 3478 void resize (size_type size, bool /*preserve*/ = true) {
Chris@16 3479 size1_ = size;
Chris@16 3480 size2_ = size;
Chris@16 3481 }
Chris@16 3482 BOOST_UBLAS_INLINE
Chris@16 3483 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
Chris@16 3484 size1_ = size1;
Chris@16 3485 size2_ = size2;
Chris@16 3486 }
Chris@16 3487
Chris@16 3488 // Element access
Chris@16 3489 BOOST_UBLAS_INLINE
Chris@16 3490 const_reference operator () (size_type /* i */, size_type /* j */) const {
Chris@16 3491 return zero_;
Chris@16 3492 }
Chris@16 3493
Chris@16 3494 // Assignment
Chris@16 3495 BOOST_UBLAS_INLINE
Chris@16 3496 zero_matrix &operator = (const zero_matrix &m) {
Chris@16 3497 size1_ = m.size1_;
Chris@16 3498 size2_ = m.size2_;
Chris@16 3499 return *this;
Chris@16 3500 }
Chris@16 3501 BOOST_UBLAS_INLINE
Chris@16 3502 zero_matrix &assign_temporary (zero_matrix &m) {
Chris@16 3503 swap (m);
Chris@16 3504 return *this;
Chris@16 3505 }
Chris@16 3506
Chris@16 3507 // Swapping
Chris@16 3508 BOOST_UBLAS_INLINE
Chris@16 3509 void swap (zero_matrix &m) {
Chris@16 3510 if (this != &m) {
Chris@16 3511 std::swap (size1_, m.size1_);
Chris@16 3512 std::swap (size2_, m.size2_);
Chris@16 3513 }
Chris@16 3514 }
Chris@16 3515 BOOST_UBLAS_INLINE
Chris@16 3516 friend void swap (zero_matrix &m1, zero_matrix &m2) {
Chris@16 3517 m1.swap (m2);
Chris@16 3518 }
Chris@16 3519
Chris@16 3520 // Iterator types
Chris@16 3521 public:
Chris@16 3522 class const_iterator1;
Chris@16 3523 class const_iterator2;
Chris@16 3524 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 3525 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 3526
Chris@16 3527 // Element lookup
Chris@16 3528 BOOST_UBLAS_INLINE
Chris@16 3529 const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
Chris@16 3530 return const_iterator1 (*this);
Chris@16 3531 }
Chris@16 3532 BOOST_UBLAS_INLINE
Chris@16 3533 const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
Chris@16 3534 return const_iterator2 (*this);
Chris@16 3535 }
Chris@16 3536
Chris@16 3537 class const_iterator1:
Chris@16 3538 public container_const_reference<zero_matrix>,
Chris@16 3539 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
Chris@16 3540 const_iterator1, value_type> {
Chris@16 3541 public:
Chris@16 3542 typedef typename zero_matrix::value_type value_type;
Chris@16 3543 typedef typename zero_matrix::difference_type difference_type;
Chris@16 3544 typedef typename zero_matrix::const_reference reference;
Chris@16 3545 typedef typename zero_matrix::const_pointer pointer;
Chris@16 3546
Chris@16 3547 typedef const_iterator2 dual_iterator_type;
Chris@16 3548 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 3549
Chris@16 3550 // Construction and destruction
Chris@16 3551 BOOST_UBLAS_INLINE
Chris@16 3552 const_iterator1 ():
Chris@16 3553 container_const_reference<self_type> () {}
Chris@16 3554 BOOST_UBLAS_INLINE
Chris@16 3555 const_iterator1 (const self_type &m):
Chris@16 3556 container_const_reference<self_type> (m) {}
Chris@16 3557
Chris@16 3558 // Arithmetic
Chris@16 3559 BOOST_UBLAS_INLINE
Chris@16 3560 const_iterator1 &operator ++ () {
Chris@16 3561 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3562 return *this;
Chris@16 3563 }
Chris@16 3564 BOOST_UBLAS_INLINE
Chris@16 3565 const_iterator1 &operator -- () {
Chris@16 3566 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3567 return *this;
Chris@16 3568 }
Chris@16 3569
Chris@16 3570 // Dereference
Chris@16 3571 BOOST_UBLAS_INLINE
Chris@16 3572 const_reference operator * () const {
Chris@16 3573 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3574 return zero_; // arbitary return value
Chris@16 3575 }
Chris@16 3576
Chris@16 3577 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 3578 BOOST_UBLAS_INLINE
Chris@16 3579 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3580 typename self_type::
Chris@16 3581 #endif
Chris@16 3582 const_iterator2 begin () const {
Chris@16 3583 return const_iterator2 ((*this) ());
Chris@16 3584 }
Chris@16 3585 BOOST_UBLAS_INLINE
Chris@16 3586 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3587 typename self_type::
Chris@16 3588 #endif
Chris@101 3589 const_iterator2 cbegin () const {
Chris@101 3590 return begin ();
Chris@101 3591 }
Chris@101 3592 BOOST_UBLAS_INLINE
Chris@101 3593 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3594 typename self_type::
Chris@101 3595 #endif
Chris@16 3596 const_iterator2 end () const {
Chris@16 3597 return const_iterator2 ((*this) ());
Chris@16 3598 }
Chris@16 3599 BOOST_UBLAS_INLINE
Chris@16 3600 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3601 typename self_type::
Chris@16 3602 #endif
Chris@101 3603 const_iterator2 cend () const {
Chris@101 3604 return end ();
Chris@101 3605 }
Chris@101 3606 BOOST_UBLAS_INLINE
Chris@101 3607 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3608 typename self_type::
Chris@101 3609 #endif
Chris@16 3610 const_reverse_iterator2 rbegin () const {
Chris@16 3611 return const_reverse_iterator2 (end ());
Chris@16 3612 }
Chris@16 3613 BOOST_UBLAS_INLINE
Chris@16 3614 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3615 typename self_type::
Chris@16 3616 #endif
Chris@101 3617 const_reverse_iterator2 crbegin () const {
Chris@101 3618 return rbegin ();
Chris@101 3619 }
Chris@101 3620 BOOST_UBLAS_INLINE
Chris@101 3621 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3622 typename self_type::
Chris@101 3623 #endif
Chris@16 3624 const_reverse_iterator2 rend () const {
Chris@16 3625 return const_reverse_iterator2 (begin ());
Chris@16 3626 }
Chris@101 3627 BOOST_UBLAS_INLINE
Chris@101 3628 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3629 typename self_type::
Chris@101 3630 #endif
Chris@101 3631 const_reverse_iterator2 crend () const {
Chris@101 3632 return rend ();
Chris@101 3633 }
Chris@16 3634 #endif
Chris@16 3635
Chris@16 3636 // Indices
Chris@16 3637 BOOST_UBLAS_INLINE
Chris@16 3638 size_type index1 () const {
Chris@16 3639 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3640 return 0; // arbitary return value
Chris@16 3641 }
Chris@16 3642 BOOST_UBLAS_INLINE
Chris@16 3643 size_type index2 () const {
Chris@16 3644 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3645 return 0; // arbitary return value
Chris@16 3646 }
Chris@16 3647
Chris@16 3648 // Assignment
Chris@16 3649 BOOST_UBLAS_INLINE
Chris@16 3650 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 3651 container_const_reference<self_type>::assign (&it ());
Chris@16 3652 return *this;
Chris@16 3653 }
Chris@16 3654
Chris@16 3655 // Comparison
Chris@16 3656 BOOST_UBLAS_INLINE
Chris@16 3657 bool operator == (const const_iterator1 &it) const {
Chris@16 3658 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3659 detail::ignore_unused_variable_warning(it);
Chris@16 3660 return true;
Chris@16 3661 }
Chris@16 3662 };
Chris@16 3663
Chris@16 3664 typedef const_iterator1 iterator1;
Chris@16 3665
Chris@16 3666 BOOST_UBLAS_INLINE
Chris@16 3667 const_iterator1 begin1 () const {
Chris@16 3668 return const_iterator1 (*this);
Chris@16 3669 }
Chris@16 3670 BOOST_UBLAS_INLINE
Chris@101 3671 const_iterator1 cbegin1 () const {
Chris@101 3672 return begin1 ();
Chris@101 3673 }
Chris@101 3674 BOOST_UBLAS_INLINE
Chris@16 3675 const_iterator1 end1 () const {
Chris@16 3676 return const_iterator1 (*this);
Chris@16 3677 }
Chris@101 3678 BOOST_UBLAS_INLINE
Chris@101 3679 const_iterator1 cend1 () const {
Chris@101 3680 return end1 ();
Chris@101 3681 }
Chris@16 3682
Chris@16 3683 class const_iterator2:
Chris@16 3684 public container_const_reference<zero_matrix>,
Chris@16 3685 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
Chris@16 3686 const_iterator2, value_type> {
Chris@16 3687 public:
Chris@16 3688 typedef typename zero_matrix::value_type value_type;
Chris@16 3689 typedef typename zero_matrix::difference_type difference_type;
Chris@16 3690 typedef typename zero_matrix::const_reference reference;
Chris@16 3691 typedef typename zero_matrix::const_pointer pointer;
Chris@16 3692
Chris@16 3693 typedef const_iterator1 dual_iterator_type;
Chris@16 3694 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 3695
Chris@16 3696 // Construction and destruction
Chris@16 3697 BOOST_UBLAS_INLINE
Chris@16 3698 const_iterator2 ():
Chris@16 3699 container_const_reference<self_type> () {}
Chris@16 3700 BOOST_UBLAS_INLINE
Chris@16 3701 const_iterator2 (const self_type &m):
Chris@16 3702 container_const_reference<self_type> (m) {}
Chris@16 3703
Chris@16 3704 // Arithmetic
Chris@16 3705 BOOST_UBLAS_INLINE
Chris@16 3706 const_iterator2 &operator ++ () {
Chris@16 3707 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3708 return *this;
Chris@16 3709 }
Chris@16 3710 BOOST_UBLAS_INLINE
Chris@16 3711 const_iterator2 &operator -- () {
Chris@16 3712 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3713 return *this;
Chris@16 3714 }
Chris@16 3715
Chris@16 3716 // Dereference
Chris@16 3717 BOOST_UBLAS_INLINE
Chris@16 3718 const_reference operator * () const {
Chris@16 3719 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3720 return zero_; // arbitary return value
Chris@16 3721 }
Chris@16 3722
Chris@16 3723 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 3724 BOOST_UBLAS_INLINE
Chris@16 3725 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3726 typename self_type::
Chris@16 3727 #endif
Chris@16 3728 const_iterator1 begin () const {
Chris@16 3729 return const_iterator1 ((*this) ());
Chris@16 3730 }
Chris@16 3731 BOOST_UBLAS_INLINE
Chris@16 3732 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3733 typename self_type::
Chris@16 3734 #endif
Chris@101 3735 const_iterator1 cbegin () const {
Chris@101 3736 return begin ();
Chris@101 3737 }
Chris@101 3738 BOOST_UBLAS_INLINE
Chris@101 3739 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3740 typename self_type::
Chris@101 3741 #endif
Chris@16 3742 const_iterator1 end () const {
Chris@16 3743 return const_iterator1 ((*this) ());
Chris@16 3744 }
Chris@16 3745 BOOST_UBLAS_INLINE
Chris@16 3746 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3747 typename self_type::
Chris@16 3748 #endif
Chris@101 3749 const_iterator1 cend () const {
Chris@101 3750 return end ();
Chris@101 3751 }
Chris@101 3752 BOOST_UBLAS_INLINE
Chris@101 3753 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3754 typename self_type::
Chris@101 3755 #endif
Chris@16 3756 const_reverse_iterator1 rbegin () const {
Chris@16 3757 return const_reverse_iterator1 (end ());
Chris@16 3758 }
Chris@16 3759 BOOST_UBLAS_INLINE
Chris@16 3760 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 3761 typename self_type::
Chris@16 3762 #endif
Chris@101 3763 const_reverse_iterator1 crbegin () const {
Chris@101 3764 return rbegin ();
Chris@101 3765 }
Chris@101 3766 BOOST_UBLAS_INLINE
Chris@101 3767 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3768 typename self_type::
Chris@101 3769 #endif
Chris@16 3770 const_reverse_iterator1 rend () const {
Chris@16 3771 return const_reverse_iterator1 (begin ());
Chris@16 3772 }
Chris@101 3773 BOOST_UBLAS_INLINE
Chris@101 3774 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 3775 typename self_type::
Chris@101 3776 #endif
Chris@101 3777 const_reverse_iterator1 crend () const {
Chris@101 3778 return rend ();
Chris@101 3779 }
Chris@16 3780 #endif
Chris@16 3781
Chris@16 3782 // Indices
Chris@16 3783 BOOST_UBLAS_INLINE
Chris@16 3784 size_type index1 () const {
Chris@16 3785 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3786 return 0; // arbitary return value
Chris@16 3787 }
Chris@16 3788 BOOST_UBLAS_INLINE
Chris@16 3789 size_type index2 () const {
Chris@16 3790 BOOST_UBLAS_CHECK_FALSE (bad_index ());
Chris@16 3791 return 0; // arbitary return value
Chris@16 3792 }
Chris@16 3793
Chris@16 3794 // Assignment
Chris@16 3795 BOOST_UBLAS_INLINE
Chris@16 3796 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 3797 container_const_reference<self_type>::assign (&it ());
Chris@16 3798 return *this;
Chris@16 3799 }
Chris@16 3800
Chris@16 3801 // Comparison
Chris@16 3802 BOOST_UBLAS_INLINE
Chris@16 3803 bool operator == (const const_iterator2 &it) const {
Chris@16 3804 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 3805 detail::ignore_unused_variable_warning(it);
Chris@16 3806 return true;
Chris@16 3807 }
Chris@16 3808 };
Chris@16 3809
Chris@16 3810 typedef const_iterator2 iterator2;
Chris@16 3811
Chris@16 3812 BOOST_UBLAS_INLINE
Chris@16 3813 const_iterator2 begin2 () const {
Chris@16 3814 return find2 (0, 0, 0);
Chris@16 3815 }
Chris@16 3816 BOOST_UBLAS_INLINE
Chris@101 3817 const_iterator2 cbegin2 () const {
Chris@101 3818 return begin2 ();
Chris@101 3819 }
Chris@101 3820 BOOST_UBLAS_INLINE
Chris@16 3821 const_iterator2 end2 () const {
Chris@16 3822 return find2 (0, 0, size2_);
Chris@16 3823 }
Chris@101 3824 BOOST_UBLAS_INLINE
Chris@101 3825 const_iterator2 cend2 () const {
Chris@101 3826 return end2 ();
Chris@101 3827 }
Chris@16 3828
Chris@16 3829 // Reverse iterators
Chris@16 3830
Chris@16 3831 BOOST_UBLAS_INLINE
Chris@16 3832 const_reverse_iterator1 rbegin1 () const {
Chris@16 3833 return const_reverse_iterator1 (end1 ());
Chris@16 3834 }
Chris@16 3835 BOOST_UBLAS_INLINE
Chris@101 3836 const_reverse_iterator1 crbegin1 () const {
Chris@101 3837 return rbegin1 ();
Chris@101 3838 }
Chris@101 3839 BOOST_UBLAS_INLINE
Chris@16 3840 const_reverse_iterator1 rend1 () const {
Chris@16 3841 return const_reverse_iterator1 (begin1 ());
Chris@16 3842 }
Chris@101 3843 BOOST_UBLAS_INLINE
Chris@101 3844 const_reverse_iterator1 crend1 () const {
Chris@101 3845 return rend1 ();
Chris@101 3846 }
Chris@16 3847
Chris@16 3848 BOOST_UBLAS_INLINE
Chris@16 3849 const_reverse_iterator2 rbegin2 () const {
Chris@16 3850 return const_reverse_iterator2 (end2 ());
Chris@16 3851 }
Chris@16 3852 BOOST_UBLAS_INLINE
Chris@101 3853 const_reverse_iterator2 crbegin2 () const {
Chris@101 3854 return rbegin2 ();
Chris@101 3855 }
Chris@101 3856 BOOST_UBLAS_INLINE
Chris@16 3857 const_reverse_iterator2 rend2 () const {
Chris@16 3858 return const_reverse_iterator2 (begin2 ());
Chris@16 3859 }
Chris@101 3860 BOOST_UBLAS_INLINE
Chris@101 3861 const_reverse_iterator2 crend2 () const {
Chris@101 3862 return rend2 ();
Chris@101 3863 }
Chris@16 3864
Chris@16 3865 // Serialization
Chris@16 3866 template<class Archive>
Chris@16 3867 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 3868
Chris@16 3869 // we need to copy to a collection_size_type to get a portable
Chris@16 3870 // and efficient serialization
Chris@16 3871 serialization::collection_size_type s1 (size1_);
Chris@16 3872 serialization::collection_size_type s2 (size2_);
Chris@16 3873
Chris@16 3874 // serialize the sizes
Chris@16 3875 ar & serialization::make_nvp("size1",s1)
Chris@16 3876 & serialization::make_nvp("size2",s2);
Chris@16 3877
Chris@16 3878 // copy the values back if loading
Chris@16 3879 if (Archive::is_loading::value) {
Chris@16 3880 size1_ = s1;
Chris@16 3881 size2_ = s2;
Chris@16 3882 }
Chris@16 3883 }
Chris@16 3884
Chris@16 3885 private:
Chris@16 3886 size_type size1_;
Chris@16 3887 size_type size2_;
Chris@16 3888 static const value_type zero_;
Chris@16 3889 };
Chris@16 3890
Chris@16 3891 template<class T, class ALLOC>
Chris@16 3892 const typename zero_matrix<T, ALLOC>::value_type zero_matrix<T, ALLOC>::zero_ = T(/*zero*/);
Chris@16 3893
Chris@16 3894 /** \brief An identity matrix with values of type \c T
Chris@16 3895 *
Chris@16 3896 * Elements or cordinates \f$(i,i)\f$ are equal to 1 (one) and all others to 0 (zero).
Chris@16 3897 * Changing values does not affect the matrix, however assigning it to a normal matrix will
Chris@16 3898 * make the matrix equal to an identity matrix. All accesses are constant du to the trivial values.
Chris@16 3899 *
Chris@16 3900 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 3901 * \tparam ALLOC an allocator for storing the zeros and one elements. By default, a standar allocator is used.
Chris@16 3902 */
Chris@16 3903 template<class T, class ALLOC>
Chris@16 3904 class identity_matrix:
Chris@16 3905 public matrix_container<identity_matrix<T, ALLOC> > {
Chris@16 3906
Chris@16 3907 typedef const T *const_pointer;
Chris@16 3908 typedef identity_matrix<T, ALLOC> self_type;
Chris@16 3909 public:
Chris@16 3910 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 3911 using matrix_container<self_type>::operator ();
Chris@16 3912 #endif
Chris@16 3913 typedef typename ALLOC::size_type size_type;
Chris@16 3914 typedef typename ALLOC::difference_type difference_type;
Chris@16 3915 typedef T value_type;
Chris@16 3916 typedef const T &const_reference;
Chris@16 3917 typedef T &reference;
Chris@16 3918 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 3919 typedef matrix_reference<self_type> closure_type;
Chris@16 3920 typedef sparse_tag storage_category;
Chris@16 3921 typedef unknown_orientation_tag orientation_category;
Chris@16 3922
Chris@16 3923 // Construction and destruction
Chris@16 3924 BOOST_UBLAS_INLINE
Chris@16 3925 identity_matrix ():
Chris@16 3926 matrix_container<self_type> (),
Chris@16 3927 size1_ (0), size2_ (0), size_common_ (0) {}
Chris@16 3928 BOOST_UBLAS_INLINE
Chris@16 3929 identity_matrix (size_type size):
Chris@16 3930 matrix_container<self_type> (),
Chris@16 3931 size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {}
Chris@16 3932 BOOST_UBLAS_INLINE
Chris@16 3933 identity_matrix (size_type size1, size_type size2):
Chris@16 3934 matrix_container<self_type> (),
Chris@16 3935 size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {}
Chris@16 3936 BOOST_UBLAS_INLINE
Chris@16 3937 identity_matrix (const identity_matrix &m):
Chris@16 3938 matrix_container<self_type> (),
Chris@16 3939 size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {}
Chris@16 3940
Chris@16 3941 // Accessors
Chris@16 3942 BOOST_UBLAS_INLINE
Chris@16 3943 size_type size1 () const {
Chris@16 3944 return size1_;
Chris@16 3945 }
Chris@16 3946 BOOST_UBLAS_INLINE
Chris@16 3947 size_type size2 () const {
Chris@16 3948 return size2_;
Chris@16 3949 }
Chris@16 3950
Chris@16 3951 // Resizing
Chris@16 3952 BOOST_UBLAS_INLINE
Chris@101 3953 void resize (size_type size, bool /*preserve*/ = true) {
Chris@16 3954 size1_ = size;
Chris@16 3955 size2_ = size;
Chris@16 3956 size_common_ = ((std::min)(size1_, size2_));
Chris@16 3957 }
Chris@16 3958 BOOST_UBLAS_INLINE
Chris@16 3959 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
Chris@16 3960 size1_ = size1;
Chris@16 3961 size2_ = size2;
Chris@16 3962 size_common_ = ((std::min)(size1_, size2_));
Chris@16 3963 }
Chris@16 3964
Chris@16 3965 // Element access
Chris@16 3966 BOOST_UBLAS_INLINE
Chris@16 3967 const_reference operator () (size_type i, size_type j) const {
Chris@16 3968 if (i == j)
Chris@16 3969 return one_;
Chris@16 3970 else
Chris@16 3971 return zero_;
Chris@16 3972 }
Chris@16 3973
Chris@16 3974 // Assignment
Chris@16 3975 BOOST_UBLAS_INLINE
Chris@16 3976 identity_matrix &operator = (const identity_matrix &m) {
Chris@16 3977 size1_ = m.size1_;
Chris@16 3978 size2_ = m.size2_;
Chris@16 3979 size_common_ = m.size_common_;
Chris@16 3980 return *this;
Chris@16 3981 }
Chris@16 3982 BOOST_UBLAS_INLINE
Chris@16 3983 identity_matrix &assign_temporary (identity_matrix &m) {
Chris@16 3984 swap (m);
Chris@16 3985 return *this;
Chris@16 3986 }
Chris@16 3987
Chris@16 3988 // Swapping
Chris@16 3989 BOOST_UBLAS_INLINE
Chris@16 3990 void swap (identity_matrix &m) {
Chris@16 3991 if (this != &m) {
Chris@16 3992 std::swap (size1_, m.size1_);
Chris@16 3993 std::swap (size2_, m.size2_);
Chris@16 3994 std::swap (size_common_, m.size_common_);
Chris@16 3995 }
Chris@16 3996 }
Chris@16 3997 BOOST_UBLAS_INLINE
Chris@16 3998 friend void swap (identity_matrix &m1, identity_matrix &m2) {
Chris@16 3999 m1.swap (m2);
Chris@16 4000 }
Chris@16 4001
Chris@16 4002 // Iterator types
Chris@16 4003 private:
Chris@16 4004 // Use an index
Chris@16 4005 typedef size_type const_subiterator_type;
Chris@16 4006
Chris@16 4007 public:
Chris@16 4008 class const_iterator1;
Chris@16 4009 class const_iterator2;
Chris@16 4010 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 4011 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 4012
Chris@16 4013 // Element lookup
Chris@16 4014 BOOST_UBLAS_INLINE
Chris@16 4015 const_iterator1 find1 (int rank, size_type i, size_type j) const {
Chris@16 4016 if (rank == 1) {
Chris@16 4017 i = (std::max) (i, j);
Chris@16 4018 i = (std::min) (i, j + 1);
Chris@16 4019 }
Chris@16 4020 return const_iterator1 (*this, i);
Chris@16 4021 }
Chris@16 4022 BOOST_UBLAS_INLINE
Chris@16 4023 const_iterator2 find2 (int rank, size_type i, size_type j) const {
Chris@16 4024 if (rank == 1) {
Chris@16 4025 j = (std::max) (j, i);
Chris@16 4026 j = (std::min) (j, i + 1);
Chris@16 4027 }
Chris@16 4028 return const_iterator2 (*this, j);
Chris@16 4029 }
Chris@16 4030
Chris@16 4031
Chris@16 4032 class const_iterator1:
Chris@16 4033 public container_const_reference<identity_matrix>,
Chris@16 4034 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
Chris@16 4035 const_iterator1, value_type> {
Chris@16 4036 public:
Chris@16 4037 typedef typename identity_matrix::value_type value_type;
Chris@16 4038 typedef typename identity_matrix::difference_type difference_type;
Chris@16 4039 typedef typename identity_matrix::const_reference reference;
Chris@16 4040 typedef typename identity_matrix::const_pointer pointer;
Chris@16 4041
Chris@16 4042 typedef const_iterator2 dual_iterator_type;
Chris@16 4043 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 4044
Chris@16 4045 // Construction and destruction
Chris@16 4046 BOOST_UBLAS_INLINE
Chris@16 4047 const_iterator1 ():
Chris@16 4048 container_const_reference<self_type> (), it_ () {}
Chris@16 4049 BOOST_UBLAS_INLINE
Chris@16 4050 const_iterator1 (const self_type &m, const const_subiterator_type &it):
Chris@16 4051 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 4052
Chris@16 4053 // Arithmetic
Chris@16 4054 BOOST_UBLAS_INLINE
Chris@16 4055 const_iterator1 &operator ++ () {
Chris@16 4056 BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ());
Chris@16 4057 ++it_;
Chris@16 4058 return *this;
Chris@16 4059 }
Chris@16 4060 BOOST_UBLAS_INLINE
Chris@16 4061 const_iterator1 &operator -- () {
Chris@16 4062 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
Chris@16 4063 --it_;
Chris@16 4064 return *this;
Chris@16 4065 }
Chris@16 4066
Chris@16 4067 // Dereference
Chris@16 4068 BOOST_UBLAS_INLINE
Chris@16 4069 const_reference operator * () const {
Chris@16 4070 return one_;
Chris@16 4071 }
Chris@16 4072
Chris@16 4073 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 4074 BOOST_UBLAS_INLINE
Chris@16 4075 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4076 typename self_type::
Chris@16 4077 #endif
Chris@16 4078 const_iterator2 begin () const {
Chris@16 4079 return const_iterator2 ((*this) (), it_);
Chris@16 4080 }
Chris@16 4081 BOOST_UBLAS_INLINE
Chris@16 4082 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4083 typename self_type::
Chris@16 4084 #endif
Chris@101 4085 const_iterator2 cbegin () const {
Chris@101 4086 return begin ();
Chris@101 4087 }
Chris@101 4088 BOOST_UBLAS_INLINE
Chris@101 4089 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4090 typename self_type::
Chris@101 4091 #endif
Chris@16 4092 const_iterator2 end () const {
Chris@16 4093 return const_iterator2 ((*this) (), it_ + 1);
Chris@16 4094 }
Chris@16 4095 BOOST_UBLAS_INLINE
Chris@16 4096 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4097 typename self_type::
Chris@16 4098 #endif
Chris@101 4099 const_iterator2 cend () const {
Chris@101 4100 return end ();
Chris@101 4101 }
Chris@101 4102 BOOST_UBLAS_INLINE
Chris@101 4103 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4104 typename self_type::
Chris@101 4105 #endif
Chris@16 4106 const_reverse_iterator2 rbegin () const {
Chris@16 4107 return const_reverse_iterator2 (end ());
Chris@16 4108 }
Chris@16 4109 BOOST_UBLAS_INLINE
Chris@16 4110 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4111 typename self_type::
Chris@16 4112 #endif
Chris@101 4113 const_reverse_iterator2 crbegin () const {
Chris@101 4114 return rbegin ();
Chris@101 4115 }
Chris@101 4116 BOOST_UBLAS_INLINE
Chris@101 4117 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4118 typename self_type::
Chris@101 4119 #endif
Chris@16 4120 const_reverse_iterator2 rend () const {
Chris@16 4121 return const_reverse_iterator2 (begin ());
Chris@16 4122 }
Chris@101 4123 BOOST_UBLAS_INLINE
Chris@101 4124 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4125 typename self_type::
Chris@101 4126 #endif
Chris@101 4127 const_reverse_iterator2 crend () const {
Chris@101 4128 return rend ();
Chris@101 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 return it_;
Chris@16 4136 }
Chris@16 4137 BOOST_UBLAS_INLINE
Chris@16 4138 size_type index2 () const {
Chris@16 4139 return it_;
Chris@16 4140 }
Chris@16 4141
Chris@16 4142 // Assignment
Chris@16 4143 BOOST_UBLAS_INLINE
Chris@16 4144 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 4145 container_const_reference<self_type>::assign (&it ());
Chris@16 4146 it_ = it.it_;
Chris@16 4147 return *this;
Chris@16 4148 }
Chris@16 4149
Chris@16 4150 // Comparison
Chris@16 4151 BOOST_UBLAS_INLINE
Chris@16 4152 bool operator == (const const_iterator1 &it) const {
Chris@16 4153 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4154 return it_ == it.it_;
Chris@16 4155 }
Chris@16 4156
Chris@16 4157 private:
Chris@16 4158 const_subiterator_type it_;
Chris@16 4159 };
Chris@16 4160
Chris@16 4161 typedef const_iterator1 iterator1;
Chris@16 4162
Chris@16 4163 BOOST_UBLAS_INLINE
Chris@16 4164 const_iterator1 begin1 () const {
Chris@16 4165 return const_iterator1 (*this, 0);
Chris@16 4166 }
Chris@16 4167 BOOST_UBLAS_INLINE
Chris@101 4168 const_iterator1 cbegin1 () const {
Chris@101 4169 return begin1 ();
Chris@101 4170 }
Chris@101 4171 BOOST_UBLAS_INLINE
Chris@16 4172 const_iterator1 end1 () const {
Chris@16 4173 return const_iterator1 (*this, size_common_);
Chris@16 4174 }
Chris@101 4175 BOOST_UBLAS_INLINE
Chris@101 4176 const_iterator1 cend1 () const {
Chris@101 4177 return end1 ();
Chris@101 4178 }
Chris@16 4179
Chris@16 4180 class const_iterator2:
Chris@16 4181 public container_const_reference<identity_matrix>,
Chris@16 4182 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
Chris@16 4183 const_iterator2, value_type> {
Chris@16 4184 public:
Chris@16 4185 typedef typename identity_matrix::value_type value_type;
Chris@16 4186 typedef typename identity_matrix::difference_type difference_type;
Chris@16 4187 typedef typename identity_matrix::const_reference reference;
Chris@16 4188 typedef typename identity_matrix::const_pointer pointer;
Chris@16 4189
Chris@16 4190 typedef const_iterator1 dual_iterator_type;
Chris@16 4191 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 4192
Chris@16 4193 // Construction and destruction
Chris@16 4194 BOOST_UBLAS_INLINE
Chris@16 4195 const_iterator2 ():
Chris@16 4196 container_const_reference<self_type> (), it_ () {}
Chris@16 4197 BOOST_UBLAS_INLINE
Chris@16 4198 const_iterator2 (const self_type &m, const const_subiterator_type &it):
Chris@16 4199 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 4200
Chris@16 4201 // Arithmetic
Chris@16 4202 BOOST_UBLAS_INLINE
Chris@16 4203 const_iterator2 &operator ++ () {
Chris@16 4204 BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ());
Chris@16 4205 ++it_;
Chris@16 4206 return *this;
Chris@16 4207 }
Chris@16 4208 BOOST_UBLAS_INLINE
Chris@16 4209 const_iterator2 &operator -- () {
Chris@16 4210 BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
Chris@16 4211 --it_;
Chris@16 4212 return *this;
Chris@16 4213 }
Chris@16 4214
Chris@16 4215 // Dereference
Chris@16 4216 BOOST_UBLAS_INLINE
Chris@16 4217 const_reference operator * () const {
Chris@16 4218 return one_;
Chris@16 4219 }
Chris@16 4220
Chris@16 4221 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 4222 BOOST_UBLAS_INLINE
Chris@16 4223 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4224 typename self_type::
Chris@16 4225 #endif
Chris@16 4226 const_iterator1 begin () const {
Chris@16 4227 return const_iterator1 ((*this) (), it_);
Chris@16 4228 }
Chris@16 4229 BOOST_UBLAS_INLINE
Chris@16 4230 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4231 typename self_type::
Chris@16 4232 #endif
Chris@101 4233 const_iterator1 cbegin () const {
Chris@101 4234 return begin ();
Chris@101 4235 }
Chris@101 4236 BOOST_UBLAS_INLINE
Chris@101 4237 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4238 typename self_type::
Chris@101 4239 #endif
Chris@16 4240 const_iterator1 end () const {
Chris@16 4241 return const_iterator1 ((*this) (), it_ + 1);
Chris@16 4242 }
Chris@16 4243 BOOST_UBLAS_INLINE
Chris@16 4244 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4245 typename self_type::
Chris@16 4246 #endif
Chris@101 4247 const_iterator1 cend () const {
Chris@101 4248 return end ();
Chris@101 4249 }
Chris@101 4250 BOOST_UBLAS_INLINE
Chris@101 4251 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4252 typename self_type::
Chris@101 4253 #endif
Chris@16 4254 const_reverse_iterator1 rbegin () const {
Chris@16 4255 return const_reverse_iterator1 (end ());
Chris@16 4256 }
Chris@16 4257 BOOST_UBLAS_INLINE
Chris@16 4258 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4259 typename self_type::
Chris@16 4260 #endif
Chris@101 4261 const_reverse_iterator1 crbegin () const {
Chris@101 4262 return rbegin ();
Chris@101 4263 }
Chris@101 4264 BOOST_UBLAS_INLINE
Chris@101 4265 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4266 typename self_type::
Chris@101 4267 #endif
Chris@16 4268 const_reverse_iterator1 rend () const {
Chris@16 4269 return const_reverse_iterator1 (begin ());
Chris@16 4270 }
Chris@101 4271 BOOST_UBLAS_INLINE
Chris@101 4272 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4273 typename self_type::
Chris@101 4274 #endif
Chris@101 4275 const_reverse_iterator1 crend () const {
Chris@101 4276 return rend ();
Chris@101 4277 }
Chris@16 4278 #endif
Chris@16 4279
Chris@16 4280 // Indices
Chris@16 4281 BOOST_UBLAS_INLINE
Chris@16 4282 size_type index1 () const {
Chris@16 4283 return it_;
Chris@16 4284 }
Chris@16 4285 BOOST_UBLAS_INLINE
Chris@16 4286 size_type index2 () const {
Chris@16 4287 return it_;
Chris@16 4288 }
Chris@16 4289
Chris@16 4290 // Assignment
Chris@16 4291 BOOST_UBLAS_INLINE
Chris@16 4292 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 4293 container_const_reference<self_type>::assign (&it ());
Chris@16 4294 it_ = it.it_;
Chris@16 4295 return *this;
Chris@16 4296 }
Chris@16 4297
Chris@16 4298 // Comparison
Chris@16 4299 BOOST_UBLAS_INLINE
Chris@16 4300 bool operator == (const const_iterator2 &it) const {
Chris@16 4301 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4302 return it_ == it.it_;
Chris@16 4303 }
Chris@16 4304
Chris@16 4305 private:
Chris@16 4306 const_subiterator_type it_;
Chris@16 4307 };
Chris@16 4308
Chris@16 4309 typedef const_iterator2 iterator2;
Chris@16 4310
Chris@16 4311 BOOST_UBLAS_INLINE
Chris@16 4312 const_iterator2 begin2 () const {
Chris@16 4313 return const_iterator2 (*this, 0);
Chris@16 4314 }
Chris@16 4315 BOOST_UBLAS_INLINE
Chris@101 4316 const_iterator2 cbegin2 () const {
Chris@101 4317 return begin2 ();
Chris@101 4318 }
Chris@101 4319 BOOST_UBLAS_INLINE
Chris@16 4320 const_iterator2 end2 () const {
Chris@16 4321 return const_iterator2 (*this, size_common_);
Chris@16 4322 }
Chris@101 4323 BOOST_UBLAS_INLINE
Chris@101 4324 const_iterator2 cend2 () const {
Chris@101 4325 return end2 ();
Chris@101 4326 }
Chris@16 4327
Chris@16 4328 // Reverse iterators
Chris@16 4329
Chris@16 4330 BOOST_UBLAS_INLINE
Chris@16 4331 const_reverse_iterator1 rbegin1 () const {
Chris@16 4332 return const_reverse_iterator1 (end1 ());
Chris@16 4333 }
Chris@16 4334 BOOST_UBLAS_INLINE
Chris@101 4335 const_reverse_iterator1 crbegin1 () const {
Chris@101 4336 return rbegin1 ();
Chris@101 4337 }
Chris@101 4338 BOOST_UBLAS_INLINE
Chris@16 4339 const_reverse_iterator1 rend1 () const {
Chris@16 4340 return const_reverse_iterator1 (begin1 ());
Chris@16 4341 }
Chris@101 4342 BOOST_UBLAS_INLINE
Chris@101 4343 const_reverse_iterator1 crend1 () const {
Chris@101 4344 return rend1 ();
Chris@101 4345 }
Chris@16 4346
Chris@16 4347 BOOST_UBLAS_INLINE
Chris@16 4348 const_reverse_iterator2 rbegin2 () const {
Chris@16 4349 return const_reverse_iterator2 (end2 ());
Chris@16 4350 }
Chris@16 4351 BOOST_UBLAS_INLINE
Chris@101 4352 const_reverse_iterator2 crbegin2 () const {
Chris@101 4353 return rbegin2 ();
Chris@101 4354 }
Chris@101 4355 BOOST_UBLAS_INLINE
Chris@16 4356 const_reverse_iterator2 rend2 () const {
Chris@16 4357 return const_reverse_iterator2 (begin2 ());
Chris@16 4358 }
Chris@101 4359 BOOST_UBLAS_INLINE
Chris@101 4360 const_reverse_iterator2 crend2 () const {
Chris@101 4361 return rend2 ();
Chris@101 4362 }
Chris@16 4363
Chris@16 4364 // Serialization
Chris@16 4365 template<class Archive>
Chris@16 4366 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 4367
Chris@16 4368 // we need to copy to a collection_size_type to get a portable
Chris@16 4369 // and efficient serialization
Chris@16 4370 serialization::collection_size_type s1 (size1_);
Chris@16 4371 serialization::collection_size_type s2 (size2_);
Chris@16 4372
Chris@16 4373 // serialize the sizes
Chris@16 4374 ar & serialization::make_nvp("size1",s1)
Chris@16 4375 & serialization::make_nvp("size2",s2);
Chris@16 4376
Chris@16 4377 // copy the values back if loading
Chris@16 4378 if (Archive::is_loading::value) {
Chris@16 4379 size1_ = s1;
Chris@16 4380 size2_ = s2;
Chris@16 4381 size_common_ = ((std::min)(size1_, size2_));
Chris@16 4382 }
Chris@16 4383 }
Chris@16 4384
Chris@16 4385 private:
Chris@16 4386 size_type size1_;
Chris@16 4387 size_type size2_;
Chris@16 4388 size_type size_common_;
Chris@16 4389 static const value_type zero_;
Chris@16 4390 static const value_type one_;
Chris@16 4391 };
Chris@16 4392
Chris@16 4393 template<class T, class ALLOC>
Chris@16 4394 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::zero_ = T(/*zero*/);
Chris@16 4395 template<class T, class ALLOC>
Chris@16 4396 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here
Chris@16 4397
Chris@16 4398
Chris@16 4399 /** \brief A matrix with all values of type \c T equal to the same value
Chris@16 4400 *
Chris@16 4401 * Changing one value has the effect of changing all the values. Assigning it to a normal matrix will copy
Chris@16 4402 * the same value everywhere in this matrix. All accesses are constant time, due to the trivial value.
Chris@16 4403 *
Chris@16 4404 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 4405 * \tparam ALLOC an allocator for storing the unique value. By default, a standar allocator is used.
Chris@16 4406 */
Chris@16 4407 template<class T, class ALLOC>
Chris@16 4408 class scalar_matrix:
Chris@16 4409 public matrix_container<scalar_matrix<T, ALLOC> > {
Chris@16 4410
Chris@16 4411 typedef const T *const_pointer;
Chris@16 4412 typedef scalar_matrix<T, ALLOC> self_type;
Chris@16 4413 public:
Chris@16 4414 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 4415 using matrix_container<self_type>::operator ();
Chris@16 4416 #endif
Chris@16 4417 typedef std::size_t size_type;
Chris@16 4418 typedef std::ptrdiff_t difference_type;
Chris@16 4419 typedef T value_type;
Chris@16 4420 typedef const T &const_reference;
Chris@16 4421 typedef T &reference;
Chris@16 4422 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 4423 typedef matrix_reference<self_type> closure_type;
Chris@16 4424 typedef dense_tag storage_category;
Chris@16 4425 typedef unknown_orientation_tag orientation_category;
Chris@16 4426
Chris@16 4427 // Construction and destruction
Chris@16 4428 BOOST_UBLAS_INLINE
Chris@16 4429 scalar_matrix ():
Chris@16 4430 matrix_container<self_type> (),
Chris@16 4431 size1_ (0), size2_ (0), value_ () {}
Chris@16 4432 BOOST_UBLAS_INLINE
Chris@16 4433 scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)):
Chris@16 4434 matrix_container<self_type> (),
Chris@16 4435 size1_ (size1), size2_ (size2), value_ (value) {}
Chris@16 4436 BOOST_UBLAS_INLINE
Chris@16 4437 scalar_matrix (const scalar_matrix &m):
Chris@16 4438 matrix_container<self_type> (),
Chris@16 4439 size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {}
Chris@16 4440
Chris@16 4441 // Accessors
Chris@16 4442 BOOST_UBLAS_INLINE
Chris@16 4443 size_type size1 () const {
Chris@16 4444 return size1_;
Chris@16 4445 }
Chris@16 4446 BOOST_UBLAS_INLINE
Chris@16 4447 size_type size2 () const {
Chris@16 4448 return size2_;
Chris@16 4449 }
Chris@16 4450
Chris@16 4451 // Resizing
Chris@16 4452 BOOST_UBLAS_INLINE
Chris@16 4453 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
Chris@16 4454 size1_ = size1;
Chris@16 4455 size2_ = size2;
Chris@16 4456 }
Chris@16 4457
Chris@16 4458 // Element access
Chris@16 4459 BOOST_UBLAS_INLINE
Chris@16 4460 const_reference operator () (size_type /*i*/, size_type /*j*/) const {
Chris@16 4461 return value_;
Chris@16 4462 }
Chris@16 4463
Chris@16 4464 // Assignment
Chris@16 4465 BOOST_UBLAS_INLINE
Chris@16 4466 scalar_matrix &operator = (const scalar_matrix &m) {
Chris@16 4467 size1_ = m.size1_;
Chris@16 4468 size2_ = m.size2_;
Chris@16 4469 value_ = m.value_;
Chris@16 4470 return *this;
Chris@16 4471 }
Chris@16 4472 BOOST_UBLAS_INLINE
Chris@16 4473 scalar_matrix &assign_temporary (scalar_matrix &m) {
Chris@16 4474 swap (m);
Chris@16 4475 return *this;
Chris@16 4476 }
Chris@16 4477
Chris@16 4478 // Swapping
Chris@16 4479 BOOST_UBLAS_INLINE
Chris@16 4480 void swap (scalar_matrix &m) {
Chris@16 4481 if (this != &m) {
Chris@16 4482 std::swap (size1_, m.size1_);
Chris@16 4483 std::swap (size2_, m.size2_);
Chris@16 4484 std::swap (value_, m.value_);
Chris@16 4485 }
Chris@16 4486 }
Chris@16 4487 BOOST_UBLAS_INLINE
Chris@16 4488 friend void swap (scalar_matrix &m1, scalar_matrix &m2) {
Chris@16 4489 m1.swap (m2);
Chris@16 4490 }
Chris@16 4491
Chris@16 4492 // Iterator types
Chris@16 4493 private:
Chris@16 4494 // Use an index
Chris@16 4495 typedef size_type const_subiterator_type;
Chris@16 4496
Chris@16 4497 public:
Chris@16 4498 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 4499 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@16 4500 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@16 4501 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 4502 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 4503 #else
Chris@16 4504 class const_iterator1;
Chris@16 4505 class const_iterator2;
Chris@16 4506 #endif
Chris@16 4507 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 4508 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 4509
Chris@16 4510 // Element lookup
Chris@16 4511 BOOST_UBLAS_INLINE
Chris@16 4512 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
Chris@16 4513 return const_iterator1 (*this, i, j);
Chris@16 4514 }
Chris@16 4515 BOOST_UBLAS_INLINE
Chris@16 4516 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
Chris@16 4517 return const_iterator2 (*this, i, j);
Chris@16 4518 }
Chris@16 4519
Chris@16 4520
Chris@16 4521 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 4522 class const_iterator1:
Chris@16 4523 public container_const_reference<scalar_matrix>,
Chris@16 4524 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 4525 const_iterator1, value_type> {
Chris@16 4526 public:
Chris@16 4527 typedef typename scalar_matrix::value_type value_type;
Chris@16 4528 typedef typename scalar_matrix::difference_type difference_type;
Chris@16 4529 typedef typename scalar_matrix::const_reference reference;
Chris@16 4530 typedef typename scalar_matrix::const_pointer pointer;
Chris@16 4531
Chris@16 4532 typedef const_iterator2 dual_iterator_type;
Chris@16 4533 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 4534
Chris@16 4535 // Construction and destruction
Chris@16 4536 BOOST_UBLAS_INLINE
Chris@16 4537 const_iterator1 ():
Chris@16 4538 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
Chris@16 4539 BOOST_UBLAS_INLINE
Chris@16 4540 const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
Chris@16 4541 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
Chris@16 4542
Chris@16 4543 // Arithmetic
Chris@16 4544 BOOST_UBLAS_INLINE
Chris@16 4545 const_iterator1 &operator ++ () {
Chris@16 4546 ++ it1_;
Chris@16 4547 return *this;
Chris@16 4548 }
Chris@16 4549 BOOST_UBLAS_INLINE
Chris@16 4550 const_iterator1 &operator -- () {
Chris@16 4551 -- it1_;
Chris@16 4552 return *this;
Chris@16 4553 }
Chris@16 4554 BOOST_UBLAS_INLINE
Chris@16 4555 const_iterator1 &operator += (difference_type n) {
Chris@16 4556 it1_ += n;
Chris@16 4557 return *this;
Chris@16 4558 }
Chris@16 4559 BOOST_UBLAS_INLINE
Chris@16 4560 const_iterator1 &operator -= (difference_type n) {
Chris@16 4561 it1_ -= n;
Chris@16 4562 return *this;
Chris@16 4563 }
Chris@16 4564 BOOST_UBLAS_INLINE
Chris@16 4565 difference_type operator - (const const_iterator1 &it) const {
Chris@16 4566 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4567 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 4568 return it1_ - it.it1_;
Chris@16 4569 }
Chris@16 4570
Chris@16 4571 // Dereference
Chris@16 4572 BOOST_UBLAS_INLINE
Chris@16 4573 const_reference operator * () const {
Chris@16 4574 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 4575 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 4576 return (*this) () (index1 (), index2 ());
Chris@16 4577 }
Chris@16 4578 BOOST_UBLAS_INLINE
Chris@16 4579 const_reference operator [] (difference_type n) const {
Chris@16 4580 return *(*this + n);
Chris@16 4581 }
Chris@16 4582
Chris@16 4583 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 4584 BOOST_UBLAS_INLINE
Chris@16 4585 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4586 typename self_type::
Chris@16 4587 #endif
Chris@16 4588 const_iterator2 begin () const {
Chris@16 4589 const scalar_matrix &m = (*this) ();
Chris@16 4590 return m.find2 (1, index1 (), 0);
Chris@16 4591 }
Chris@16 4592 BOOST_UBLAS_INLINE
Chris@16 4593 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4594 typename self_type::
Chris@16 4595 #endif
Chris@101 4596 const_iterator2 cbegin () const {
Chris@101 4597 return begin ();
Chris@101 4598 }
Chris@101 4599 BOOST_UBLAS_INLINE
Chris@101 4600 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4601 typename self_type::
Chris@101 4602 #endif
Chris@16 4603 const_iterator2 end () const {
Chris@16 4604 const scalar_matrix &m = (*this) ();
Chris@16 4605 return m.find2 (1, index1 (), m.size2 ());
Chris@16 4606 }
Chris@16 4607 BOOST_UBLAS_INLINE
Chris@16 4608 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4609 typename self_type::
Chris@16 4610 #endif
Chris@101 4611 const_iterator2 cend () const {
Chris@101 4612 return end ();
Chris@101 4613 }
Chris@101 4614 BOOST_UBLAS_INLINE
Chris@101 4615 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4616 typename self_type::
Chris@101 4617 #endif
Chris@16 4618 const_reverse_iterator2 rbegin () const {
Chris@16 4619 return const_reverse_iterator2 (end ());
Chris@16 4620 }
Chris@16 4621 BOOST_UBLAS_INLINE
Chris@16 4622 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4623 typename self_type::
Chris@16 4624 #endif
Chris@101 4625 const_reverse_iterator2 crbegin () const {
Chris@101 4626 return rbegin ();
Chris@101 4627 }
Chris@101 4628 BOOST_UBLAS_INLINE
Chris@101 4629 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4630 typename self_type::
Chris@101 4631 #endif
Chris@16 4632 const_reverse_iterator2 rend () const {
Chris@16 4633 return const_reverse_iterator2 (begin ());
Chris@16 4634 }
Chris@101 4635 BOOST_UBLAS_INLINE
Chris@101 4636 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4637 typename self_type::
Chris@101 4638 #endif
Chris@101 4639 const_reverse_iterator2 crend () const {
Chris@101 4640 return rend ();
Chris@101 4641 }
Chris@16 4642 #endif
Chris@16 4643
Chris@16 4644 // Indices
Chris@16 4645 BOOST_UBLAS_INLINE
Chris@16 4646 size_type index1 () const {
Chris@16 4647 return it1_;
Chris@16 4648 }
Chris@16 4649 BOOST_UBLAS_INLINE
Chris@16 4650 size_type index2 () const {
Chris@16 4651 return it2_;
Chris@16 4652 }
Chris@16 4653
Chris@16 4654 // Assignment
Chris@16 4655 BOOST_UBLAS_INLINE
Chris@16 4656 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 4657 container_const_reference<scalar_matrix>::assign (&it ());
Chris@16 4658 it1_ = it.it1_;
Chris@16 4659 it2_ = it.it2_;
Chris@16 4660 return *this;
Chris@16 4661 }
Chris@16 4662
Chris@16 4663 // Comparison
Chris@16 4664 BOOST_UBLAS_INLINE
Chris@16 4665 bool operator == (const const_iterator1 &it) const {
Chris@16 4666 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4667 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 4668 return it1_ == it.it1_;
Chris@16 4669 }
Chris@16 4670 BOOST_UBLAS_INLINE
Chris@16 4671 bool operator < (const const_iterator1 &it) const {
Chris@16 4672 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4673 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 4674 return it1_ < it.it1_;
Chris@16 4675 }
Chris@16 4676
Chris@16 4677 private:
Chris@16 4678 const_subiterator_type it1_;
Chris@16 4679 const_subiterator_type it2_;
Chris@16 4680 };
Chris@16 4681
Chris@16 4682 typedef const_iterator1 iterator1;
Chris@16 4683 #endif
Chris@16 4684
Chris@16 4685 BOOST_UBLAS_INLINE
Chris@16 4686 const_iterator1 begin1 () const {
Chris@16 4687 return find1 (0, 0, 0);
Chris@16 4688 }
Chris@16 4689 BOOST_UBLAS_INLINE
Chris@101 4690 const_iterator1 cbegin1 () const {
Chris@101 4691 return begin1 ();
Chris@101 4692 }
Chris@101 4693 BOOST_UBLAS_INLINE
Chris@16 4694 const_iterator1 end1 () const {
Chris@16 4695 return find1 (0, size1_, 0);
Chris@16 4696 }
Chris@101 4697 BOOST_UBLAS_INLINE
Chris@101 4698 const_iterator1 cend1 () const {
Chris@101 4699 return end1 ();
Chris@101 4700 }
Chris@16 4701
Chris@16 4702 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 4703 class const_iterator2:
Chris@16 4704 public container_const_reference<scalar_matrix>,
Chris@16 4705 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 4706 const_iterator2, value_type> {
Chris@16 4707 public:
Chris@16 4708 typedef typename scalar_matrix::value_type value_type;
Chris@16 4709 typedef typename scalar_matrix::difference_type difference_type;
Chris@16 4710 typedef typename scalar_matrix::const_reference reference;
Chris@16 4711 typedef typename scalar_matrix::const_pointer pointer;
Chris@16 4712
Chris@16 4713 typedef const_iterator1 dual_iterator_type;
Chris@16 4714 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 4715
Chris@16 4716 // Construction and destruction
Chris@16 4717 BOOST_UBLAS_INLINE
Chris@16 4718 const_iterator2 ():
Chris@16 4719 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
Chris@16 4720 BOOST_UBLAS_INLINE
Chris@16 4721 const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
Chris@16 4722 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
Chris@16 4723
Chris@16 4724 // Arithmetic
Chris@16 4725 BOOST_UBLAS_INLINE
Chris@16 4726 const_iterator2 &operator ++ () {
Chris@16 4727 ++ it2_;
Chris@16 4728 return *this;
Chris@16 4729 }
Chris@16 4730 BOOST_UBLAS_INLINE
Chris@16 4731 const_iterator2 &operator -- () {
Chris@16 4732 -- it2_;
Chris@16 4733 return *this;
Chris@16 4734 }
Chris@16 4735 BOOST_UBLAS_INLINE
Chris@16 4736 const_iterator2 &operator += (difference_type n) {
Chris@16 4737 it2_ += n;
Chris@16 4738 return *this;
Chris@16 4739 }
Chris@16 4740 BOOST_UBLAS_INLINE
Chris@16 4741 const_iterator2 &operator -= (difference_type n) {
Chris@16 4742 it2_ -= n;
Chris@16 4743 return *this;
Chris@16 4744 }
Chris@16 4745 BOOST_UBLAS_INLINE
Chris@16 4746 difference_type operator - (const const_iterator2 &it) const {
Chris@16 4747 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4748 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 4749 return it2_ - it.it2_;
Chris@16 4750 }
Chris@16 4751
Chris@16 4752 // Dereference
Chris@16 4753 BOOST_UBLAS_INLINE
Chris@16 4754 const_reference operator * () const {
Chris@16 4755 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 4756 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 4757 return (*this) () (index1 (), index2 ());
Chris@16 4758 }
Chris@16 4759 BOOST_UBLAS_INLINE
Chris@16 4760 const_reference operator [] (difference_type n) const {
Chris@16 4761 return *(*this + n);
Chris@16 4762 }
Chris@16 4763
Chris@16 4764 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 4765 BOOST_UBLAS_INLINE
Chris@16 4766 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4767 typename self_type::
Chris@16 4768 #endif
Chris@16 4769 const_iterator1 begin () const {
Chris@16 4770 const scalar_matrix &m = (*this) ();
Chris@16 4771 return m.find1 (1, 0, index2 ());
Chris@16 4772 }
Chris@16 4773 BOOST_UBLAS_INLINE
Chris@16 4774 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4775 typename self_type::
Chris@16 4776 #endif
Chris@101 4777 const_iterator1 cbegin () const {
Chris@101 4778 return begin ();
Chris@101 4779 }
Chris@101 4780 BOOST_UBLAS_INLINE
Chris@101 4781 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4782 typename self_type::
Chris@101 4783 #endif
Chris@16 4784 const_iterator1 end () const {
Chris@16 4785 const scalar_matrix &m = (*this) ();
Chris@16 4786 return m.find1 (1, m.size1 (), index2 ());
Chris@16 4787 }
Chris@16 4788 BOOST_UBLAS_INLINE
Chris@16 4789 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4790 typename self_type::
Chris@16 4791 #endif
Chris@101 4792 const_iterator1 cend () const {
Chris@101 4793 return end ();
Chris@101 4794 }
Chris@101 4795 BOOST_UBLAS_INLINE
Chris@101 4796 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4797 typename self_type::
Chris@101 4798 #endif
Chris@16 4799 const_reverse_iterator1 rbegin () const {
Chris@16 4800 return const_reverse_iterator1 (end ());
Chris@16 4801 }
Chris@16 4802 BOOST_UBLAS_INLINE
Chris@16 4803 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 4804 typename self_type::
Chris@16 4805 #endif
Chris@101 4806 const_reverse_iterator1 crbegin () const {
Chris@101 4807 return rbegin ();
Chris@101 4808 }
Chris@101 4809 BOOST_UBLAS_INLINE
Chris@101 4810 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4811 typename self_type::
Chris@101 4812 #endif
Chris@16 4813 const_reverse_iterator1 rend () const {
Chris@16 4814 return const_reverse_iterator1 (begin ());
Chris@16 4815 }
Chris@101 4816 BOOST_UBLAS_INLINE
Chris@101 4817 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 4818 typename self_type::
Chris@101 4819 #endif
Chris@101 4820 const_reverse_iterator1 crend () const {
Chris@101 4821 return rend ();
Chris@101 4822 }
Chris@16 4823 #endif
Chris@16 4824
Chris@16 4825 // Indices
Chris@16 4826 BOOST_UBLAS_INLINE
Chris@16 4827 size_type index1 () const {
Chris@16 4828 return it1_;
Chris@16 4829 }
Chris@16 4830 BOOST_UBLAS_INLINE
Chris@16 4831 size_type index2 () const {
Chris@16 4832 return it2_;
Chris@16 4833 }
Chris@16 4834
Chris@16 4835 // Assignment
Chris@16 4836 BOOST_UBLAS_INLINE
Chris@16 4837 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 4838 container_const_reference<scalar_matrix>::assign (&it ());
Chris@16 4839 it1_ = it.it1_;
Chris@16 4840 it2_ = it.it2_;
Chris@16 4841 return *this;
Chris@16 4842 }
Chris@16 4843
Chris@16 4844 // Comparison
Chris@16 4845 BOOST_UBLAS_INLINE
Chris@16 4846 bool operator == (const const_iterator2 &it) const {
Chris@16 4847 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4848 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 4849 return it2_ == it.it2_;
Chris@16 4850 }
Chris@16 4851 BOOST_UBLAS_INLINE
Chris@16 4852 bool operator < (const const_iterator2 &it) const {
Chris@16 4853 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 4854 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 4855 return it2_ < it.it2_;
Chris@16 4856 }
Chris@16 4857
Chris@16 4858 private:
Chris@16 4859 const_subiterator_type it1_;
Chris@16 4860 const_subiterator_type it2_;
Chris@16 4861 };
Chris@16 4862
Chris@16 4863 typedef const_iterator2 iterator2;
Chris@16 4864 #endif
Chris@16 4865
Chris@16 4866 BOOST_UBLAS_INLINE
Chris@16 4867 const_iterator2 begin2 () const {
Chris@16 4868 return find2 (0, 0, 0);
Chris@16 4869 }
Chris@16 4870 BOOST_UBLAS_INLINE
Chris@101 4871 const_iterator2 cbegin2 () const {
Chris@101 4872 return begin2 ();
Chris@101 4873 }
Chris@101 4874 BOOST_UBLAS_INLINE
Chris@16 4875 const_iterator2 end2 () const {
Chris@16 4876 return find2 (0, 0, size2_);
Chris@16 4877 }
Chris@101 4878 BOOST_UBLAS_INLINE
Chris@101 4879 const_iterator2 cend2 () const {
Chris@101 4880 return end2 ();
Chris@101 4881 }
Chris@16 4882
Chris@16 4883 // Reverse iterators
Chris@16 4884
Chris@16 4885 BOOST_UBLAS_INLINE
Chris@16 4886 const_reverse_iterator1 rbegin1 () const {
Chris@16 4887 return const_reverse_iterator1 (end1 ());
Chris@16 4888 }
Chris@16 4889 BOOST_UBLAS_INLINE
Chris@101 4890 const_reverse_iterator1 crbegin1 () const {
Chris@101 4891 return rbegin1 ();
Chris@101 4892 }
Chris@101 4893 BOOST_UBLAS_INLINE
Chris@16 4894 const_reverse_iterator1 rend1 () const {
Chris@16 4895 return const_reverse_iterator1 (begin1 ());
Chris@16 4896 }
Chris@101 4897 BOOST_UBLAS_INLINE
Chris@101 4898 const_reverse_iterator1 crend1 () const {
Chris@101 4899 return rend1 ();
Chris@101 4900 }
Chris@16 4901
Chris@16 4902 BOOST_UBLAS_INLINE
Chris@16 4903 const_reverse_iterator2 rbegin2 () const {
Chris@16 4904 return const_reverse_iterator2 (end2 ());
Chris@16 4905 }
Chris@16 4906 BOOST_UBLAS_INLINE
Chris@101 4907 const_reverse_iterator2 crbegin2 () const {
Chris@101 4908 return rbegin2 ();
Chris@101 4909 }
Chris@101 4910 BOOST_UBLAS_INLINE
Chris@16 4911 const_reverse_iterator2 rend2 () const {
Chris@16 4912 return const_reverse_iterator2 (begin2 ());
Chris@16 4913 }
Chris@101 4914 BOOST_UBLAS_INLINE
Chris@101 4915 const_reverse_iterator2 crend2 () const {
Chris@101 4916 return rend2 ();
Chris@101 4917 }
Chris@16 4918
Chris@16 4919 // Serialization
Chris@16 4920 template<class Archive>
Chris@16 4921 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 4922
Chris@16 4923 // we need to copy to a collection_size_type to get a portable
Chris@16 4924 // and efficient serialization
Chris@16 4925 serialization::collection_size_type s1 (size1_);
Chris@16 4926 serialization::collection_size_type s2 (size2_);
Chris@16 4927
Chris@16 4928 // serialize the sizes
Chris@16 4929 ar & serialization::make_nvp("size1",s1)
Chris@16 4930 & serialization::make_nvp("size2",s2);
Chris@16 4931
Chris@16 4932 // copy the values back if loading
Chris@16 4933 if (Archive::is_loading::value) {
Chris@16 4934 size1_ = s1;
Chris@16 4935 size2_ = s2;
Chris@16 4936 }
Chris@16 4937
Chris@16 4938 ar & serialization::make_nvp("value", value_);
Chris@16 4939 }
Chris@16 4940
Chris@16 4941 private:
Chris@16 4942 size_type size1_;
Chris@16 4943 size_type size2_;
Chris@16 4944 value_type value_;
Chris@16 4945 };
Chris@16 4946
Chris@16 4947
Chris@16 4948 /** \brief An array based matrix class which size is defined at type specification or object instanciation
Chris@16 4949 *
Chris@16 4950 * This matrix is directly based on a predefined C-style arry of data, thus providing the fastest
Chris@16 4951 * implementation possible. The constraint is that dimensions of the matrix must be specified at
Chris@16 4952 * the instanciation or the type specification.
Chris@16 4953 *
Chris@16 4954 * For instance, \code typedef c_matrix<double,4,4> my_4by4_matrix \endcode
Chris@16 4955 * defines a 4 by 4 double-precision matrix. You can also instantiate it directly with
Chris@16 4956 * \code c_matrix<int,8,5> my_fast_matrix \endcode. This will make a 8 by 5 integer matrix. The
Chris@16 4957 * price to pay for this speed is that you cannot resize it to a size larger than the one defined
Chris@16 4958 * in the template parameters. In the previous example, a size of 4 by 5 or 3 by 2 is acceptable,
Chris@16 4959 * but a new size of 9 by 5 or even 10 by 10 will raise a bad_size() exception.
Chris@16 4960 *
Chris@16 4961 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 4962 * \tparam N the default maximum number of rows
Chris@16 4963 * \tparam M the default maximum number of columns
Chris@16 4964 */
Chris@16 4965 template<class T, std::size_t N, std::size_t M>
Chris@16 4966 class c_matrix:
Chris@16 4967 public matrix_container<c_matrix<T, N, M> > {
Chris@16 4968
Chris@16 4969 typedef c_matrix<T, N, M> self_type;
Chris@16 4970 public:
Chris@16 4971 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 4972 using matrix_container<self_type>::operator ();
Chris@16 4973 #endif
Chris@16 4974 typedef std::size_t size_type;
Chris@16 4975 typedef std::ptrdiff_t difference_type;
Chris@16 4976 typedef T value_type;
Chris@16 4977 typedef const T &const_reference;
Chris@16 4978 typedef T &reference;
Chris@16 4979 typedef const T *const_pointer;
Chris@16 4980 typedef T *pointer;
Chris@16 4981 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 4982 typedef matrix_reference<self_type> closure_type;
Chris@16 4983 typedef c_vector<T, N * M> vector_temporary_type; // vector able to store all elements of c_matrix
Chris@16 4984 typedef self_type matrix_temporary_type;
Chris@16 4985 typedef dense_tag storage_category;
Chris@16 4986 // This could be better for performance,
Chris@16 4987 // typedef typename unknown_orientation_tag orientation_category;
Chris@16 4988 // but others depend on the orientation information...
Chris@16 4989 typedef row_major_tag orientation_category;
Chris@16 4990
Chris@16 4991 // Construction and destruction
Chris@16 4992 BOOST_UBLAS_INLINE
Chris@16 4993 c_matrix ():
Chris@16 4994 size1_ (N), size2_ (M) /* , data_ () */ {
Chris@16 4995 }
Chris@16 4996 BOOST_UBLAS_INLINE
Chris@16 4997 c_matrix (size_type size1, size_type size2):
Chris@16 4998 size1_ (size1), size2_ (size2) /* , data_ () */ {
Chris@16 4999 if (size1_ > N || size2_ > M)
Chris@16 5000 bad_size ().raise ();
Chris@16 5001 }
Chris@16 5002 BOOST_UBLAS_INLINE
Chris@16 5003 c_matrix (const c_matrix &m):
Chris@16 5004 size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ {
Chris@16 5005 if (size1_ > N || size2_ > M)
Chris@16 5006 bad_size ().raise ();
Chris@16 5007 assign(m);
Chris@16 5008 }
Chris@16 5009 template<class AE>
Chris@16 5010 BOOST_UBLAS_INLINE
Chris@16 5011 c_matrix (const matrix_expression<AE> &ae):
Chris@16 5012 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ {
Chris@16 5013 if (size1_ > N || size2_ > M)
Chris@16 5014 bad_size ().raise ();
Chris@16 5015 matrix_assign<scalar_assign> (*this, ae);
Chris@16 5016 }
Chris@16 5017
Chris@16 5018 // Accessors
Chris@16 5019 BOOST_UBLAS_INLINE
Chris@16 5020 size_type size1 () const {
Chris@16 5021 return size1_;
Chris@16 5022 }
Chris@16 5023 BOOST_UBLAS_INLINE
Chris@16 5024 size_type size2 () const {
Chris@16 5025 return size2_;
Chris@16 5026 }
Chris@16 5027 BOOST_UBLAS_INLINE
Chris@16 5028 const_pointer data () const {
Chris@16 5029 return reinterpret_cast<const_pointer> (data_);
Chris@16 5030 }
Chris@16 5031 BOOST_UBLAS_INLINE
Chris@16 5032 pointer data () {
Chris@16 5033 return reinterpret_cast<pointer> (data_);
Chris@16 5034 }
Chris@16 5035
Chris@16 5036 // Resizing
Chris@16 5037 BOOST_UBLAS_INLINE
Chris@16 5038 void resize (size_type size1, size_type size2, bool preserve = true) {
Chris@16 5039 if (size1 > N || size2 > M)
Chris@16 5040 bad_size ().raise ();
Chris@16 5041 if (preserve) {
Chris@16 5042 self_type temporary (size1, size2);
Chris@16 5043 // Common elements to preserve
Chris@16 5044 const size_type size1_min = (std::min) (size1, size1_);
Chris@16 5045 const size_type size2_min = (std::min) (size2, size2_);
Chris@16 5046 for (size_type i = 0; i != size1_min; ++i) { // indexing copy over major
Chris@16 5047 for (size_type j = 0; j != size2_min; ++j) {
Chris@16 5048 temporary.data_[i][j] = data_[i][j];
Chris@16 5049 }
Chris@16 5050 }
Chris@16 5051 assign_temporary (temporary);
Chris@16 5052 }
Chris@16 5053 else {
Chris@16 5054 size1_ = size1;
Chris@16 5055 size2_ = size2;
Chris@16 5056 }
Chris@16 5057 }
Chris@16 5058
Chris@16 5059 // Element access
Chris@16 5060 BOOST_UBLAS_INLINE
Chris@16 5061 const_reference operator () (size_type i, size_type j) const {
Chris@16 5062 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
Chris@16 5063 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
Chris@16 5064 return data_ [i] [j];
Chris@16 5065 }
Chris@16 5066 BOOST_UBLAS_INLINE
Chris@16 5067 reference at_element (size_type i, size_type j) {
Chris@16 5068 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
Chris@16 5069 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
Chris@16 5070 return data_ [i] [j];
Chris@16 5071 }
Chris@16 5072 BOOST_UBLAS_INLINE
Chris@16 5073 reference operator () (size_type i, size_type j) {
Chris@16 5074 return at_element (i, j);
Chris@16 5075 }
Chris@16 5076
Chris@16 5077 // Element assignment
Chris@16 5078 BOOST_UBLAS_INLINE
Chris@16 5079 reference insert_element (size_type i, size_type j, const_reference t) {
Chris@16 5080 return (at_element (i, j) = t);
Chris@16 5081 }
Chris@16 5082
Chris@16 5083 // Zeroing
Chris@16 5084 BOOST_UBLAS_INLINE
Chris@16 5085 void clear () {
Chris@16 5086 for (size_type i = 0; i < size1_; ++ i)
Chris@16 5087 std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/());
Chris@16 5088 }
Chris@16 5089
Chris@16 5090 // Assignment
Chris@16 5091 #ifdef BOOST_UBLAS_MOVE_SEMANTICS
Chris@16 5092
Chris@16 5093 /*! @note "pass by value" the key idea to enable move semantics */
Chris@16 5094 BOOST_UBLAS_INLINE
Chris@16 5095 c_matrix &operator = (c_matrix m) {
Chris@16 5096 assign_temporary(m);
Chris@16 5097 return *this;
Chris@16 5098 }
Chris@16 5099 #else
Chris@16 5100 BOOST_UBLAS_INLINE
Chris@16 5101 c_matrix &operator = (const c_matrix &m) {
Chris@16 5102 size1_ = m.size1_;
Chris@16 5103 size2_ = m.size2_;
Chris@16 5104 for (size_type i = 0; i < m.size1_; ++ i)
Chris@16 5105 std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]);
Chris@16 5106 return *this;
Chris@16 5107 }
Chris@16 5108 #endif
Chris@16 5109 template<class C> // Container assignment without temporary
Chris@16 5110 BOOST_UBLAS_INLINE
Chris@16 5111 c_matrix &operator = (const matrix_container<C> &m) {
Chris@16 5112 resize (m ().size1 (), m ().size2 (), false);
Chris@16 5113 assign (m);
Chris@16 5114 return *this;
Chris@16 5115 }
Chris@16 5116 BOOST_UBLAS_INLINE
Chris@16 5117 c_matrix &assign_temporary (c_matrix &m) {
Chris@16 5118 swap (m);
Chris@16 5119 return *this;
Chris@16 5120 }
Chris@16 5121 template<class AE>
Chris@16 5122 BOOST_UBLAS_INLINE
Chris@16 5123 c_matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 5124 self_type temporary (ae);
Chris@16 5125 return assign_temporary (temporary);
Chris@16 5126 }
Chris@16 5127 template<class AE>
Chris@16 5128 BOOST_UBLAS_INLINE
Chris@16 5129 c_matrix &assign (const matrix_expression<AE> &ae) {
Chris@16 5130 matrix_assign<scalar_assign> (*this, ae);
Chris@16 5131 return *this;
Chris@16 5132 }
Chris@16 5133 template<class AE>
Chris@16 5134 BOOST_UBLAS_INLINE
Chris@16 5135 c_matrix& operator += (const matrix_expression<AE> &ae) {
Chris@16 5136 self_type temporary (*this + ae);
Chris@16 5137 return assign_temporary (temporary);
Chris@16 5138 }
Chris@16 5139 template<class C> // Container assignment without temporary
Chris@16 5140 BOOST_UBLAS_INLINE
Chris@16 5141 c_matrix &operator += (const matrix_container<C> &m) {
Chris@16 5142 plus_assign (m);
Chris@16 5143 return *this;
Chris@16 5144 }
Chris@16 5145 template<class AE>
Chris@16 5146 BOOST_UBLAS_INLINE
Chris@16 5147 c_matrix &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 5148 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 5149 return *this;
Chris@16 5150 }
Chris@16 5151 template<class AE>
Chris@16 5152 BOOST_UBLAS_INLINE
Chris@16 5153 c_matrix& operator -= (const matrix_expression<AE> &ae) {
Chris@16 5154 self_type temporary (*this - ae);
Chris@16 5155 return assign_temporary (temporary);
Chris@16 5156 }
Chris@16 5157 template<class C> // Container assignment without temporary
Chris@16 5158 BOOST_UBLAS_INLINE
Chris@16 5159 c_matrix &operator -= (const matrix_container<C> &m) {
Chris@16 5160 minus_assign (m);
Chris@16 5161 return *this;
Chris@16 5162 }
Chris@16 5163 template<class AE>
Chris@16 5164 BOOST_UBLAS_INLINE
Chris@16 5165 c_matrix &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 5166 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 5167 return *this;
Chris@16 5168 }
Chris@16 5169 template<class AT>
Chris@16 5170 BOOST_UBLAS_INLINE
Chris@16 5171 c_matrix& operator *= (const AT &at) {
Chris@16 5172 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 5173 return *this;
Chris@16 5174 }
Chris@16 5175 template<class AT>
Chris@16 5176 BOOST_UBLAS_INLINE
Chris@16 5177 c_matrix& operator /= (const AT &at) {
Chris@16 5178 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 5179 return *this;
Chris@16 5180 }
Chris@16 5181
Chris@16 5182 // Swapping
Chris@16 5183 BOOST_UBLAS_INLINE
Chris@16 5184 void swap (c_matrix &m) {
Chris@16 5185 if (this != &m) {
Chris@16 5186 BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ());
Chris@16 5187 BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ());
Chris@16 5188 std::swap (size1_, m.size1_);
Chris@16 5189 std::swap (size2_, m.size2_);
Chris@16 5190 for (size_type i = 0; i < size1_; ++ i)
Chris@16 5191 std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]);
Chris@16 5192 }
Chris@16 5193 }
Chris@16 5194 BOOST_UBLAS_INLINE
Chris@16 5195 friend void swap (c_matrix &m1, c_matrix &m2) {
Chris@16 5196 m1.swap (m2);
Chris@16 5197 }
Chris@16 5198
Chris@16 5199 // Iterator types
Chris@16 5200 private:
Chris@16 5201 // Use pointers for iterator
Chris@16 5202 typedef const_pointer const_subiterator_type;
Chris@16 5203 typedef pointer subiterator_type;
Chris@16 5204
Chris@16 5205 public:
Chris@16 5206 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5207 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
Chris@16 5208 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
Chris@16 5209 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
Chris@16 5210 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
Chris@16 5211 #else
Chris@16 5212 class const_iterator1;
Chris@16 5213 class iterator1;
Chris@16 5214 class const_iterator2;
Chris@16 5215 class iterator2;
Chris@16 5216 #endif
Chris@16 5217 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 5218 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 5219 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 5220 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 5221
Chris@16 5222 // Element lookup
Chris@16 5223 BOOST_UBLAS_INLINE
Chris@101 5224 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
Chris@16 5225 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5226 return const_iterator1 (*this, i, j);
Chris@16 5227 #else
Chris@16 5228 return const_iterator1 (*this, &data_ [i] [j]);
Chris@16 5229 #endif
Chris@16 5230 }
Chris@16 5231 BOOST_UBLAS_INLINE
Chris@101 5232 iterator1 find1 (int /*rank*/, size_type i, size_type j) {
Chris@16 5233 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5234 return iterator1 (*this, i, j);
Chris@16 5235 #else
Chris@16 5236 return iterator1 (*this, &data_ [i] [j]);
Chris@16 5237 #endif
Chris@16 5238 }
Chris@16 5239 BOOST_UBLAS_INLINE
Chris@101 5240 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
Chris@16 5241 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5242 return const_iterator2 (*this, i, j);
Chris@16 5243 #else
Chris@16 5244 return const_iterator2 (*this, &data_ [i] [j]);
Chris@16 5245 #endif
Chris@16 5246 }
Chris@16 5247 BOOST_UBLAS_INLINE
Chris@101 5248 iterator2 find2 (int /*rank*/, size_type i, size_type j) {
Chris@16 5249 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5250 return iterator2 (*this, i, j);
Chris@16 5251 #else
Chris@16 5252 return iterator2 (*this, &data_ [i] [j]);
Chris@16 5253 #endif
Chris@16 5254 }
Chris@16 5255
Chris@16 5256
Chris@16 5257 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5258 class const_iterator1:
Chris@16 5259 public container_const_reference<c_matrix>,
Chris@16 5260 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 5261 const_iterator1, value_type> {
Chris@16 5262 public:
Chris@16 5263 typedef typename c_matrix::difference_type difference_type;
Chris@16 5264 typedef typename c_matrix::value_type value_type;
Chris@16 5265 typedef typename c_matrix::const_reference reference;
Chris@16 5266 typedef typename c_matrix::const_pointer pointer;
Chris@16 5267
Chris@16 5268 typedef const_iterator2 dual_iterator_type;
Chris@16 5269 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 5270
Chris@16 5271 // Construction and destruction
Chris@16 5272 BOOST_UBLAS_INLINE
Chris@16 5273 const_iterator1 ():
Chris@16 5274 container_const_reference<self_type> (), it_ () {}
Chris@16 5275 BOOST_UBLAS_INLINE
Chris@16 5276 const_iterator1 (const self_type &m, const const_subiterator_type &it):
Chris@16 5277 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 5278 BOOST_UBLAS_INLINE
Chris@16 5279 const_iterator1 (const iterator1 &it):
Chris@16 5280 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 5281
Chris@16 5282 // Arithmetic
Chris@16 5283 BOOST_UBLAS_INLINE
Chris@16 5284 const_iterator1 &operator ++ () {
Chris@16 5285 it_ += M;
Chris@16 5286 return *this;
Chris@16 5287 }
Chris@16 5288 BOOST_UBLAS_INLINE
Chris@16 5289 const_iterator1 &operator -- () {
Chris@16 5290 it_ -= M;
Chris@16 5291 return *this;
Chris@16 5292 }
Chris@16 5293 BOOST_UBLAS_INLINE
Chris@16 5294 const_iterator1 &operator += (difference_type n) {
Chris@16 5295 it_ += n * M;
Chris@16 5296 return *this;
Chris@16 5297 }
Chris@16 5298 BOOST_UBLAS_INLINE
Chris@16 5299 const_iterator1 &operator -= (difference_type n) {
Chris@16 5300 it_ -= n * M;
Chris@16 5301 return *this;
Chris@16 5302 }
Chris@16 5303 BOOST_UBLAS_INLINE
Chris@16 5304 difference_type operator - (const const_iterator1 &it) const {
Chris@16 5305 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5306 return (it_ - it.it_) / M;
Chris@16 5307 }
Chris@16 5308
Chris@16 5309 // Dereference
Chris@16 5310 BOOST_UBLAS_INLINE
Chris@16 5311 const_reference operator * () const {
Chris@16 5312 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 5313 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 5314 return *it_;
Chris@16 5315 }
Chris@16 5316 BOOST_UBLAS_INLINE
Chris@16 5317 const_reference operator [] (difference_type n) const {
Chris@16 5318 return *(*this + n);
Chris@16 5319 }
Chris@16 5320
Chris@16 5321 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 5322 BOOST_UBLAS_INLINE
Chris@16 5323 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5324 typename self_type::
Chris@16 5325 #endif
Chris@16 5326 const_iterator2 begin () const {
Chris@16 5327 const self_type &m = (*this) ();
Chris@16 5328 return m.find2 (1, index1 (), 0);
Chris@16 5329 }
Chris@16 5330 BOOST_UBLAS_INLINE
Chris@16 5331 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5332 typename self_type::
Chris@16 5333 #endif
Chris@101 5334 const_iterator2 cbegin () const {
Chris@101 5335 return begin ();
Chris@101 5336 }
Chris@101 5337 BOOST_UBLAS_INLINE
Chris@101 5338 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 5339 typename self_type::
Chris@101 5340 #endif
Chris@16 5341 const_iterator2 end () const {
Chris@16 5342 const self_type &m = (*this) ();
Chris@16 5343 return m.find2 (1, index1 (), m.size2 ());
Chris@16 5344 }
Chris@16 5345 BOOST_UBLAS_INLINE
Chris@16 5346 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5347 typename self_type::
Chris@16 5348 #endif
Chris@101 5349 const_iterator2 cend () const {
Chris@101 5350 return end ();
Chris@101 5351 }
Chris@101 5352 BOOST_UBLAS_INLINE
Chris@101 5353 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 5354 typename self_type::
Chris@101 5355 #endif
Chris@16 5356 const_reverse_iterator2 rbegin () const {
Chris@16 5357 return const_reverse_iterator2 (end ());
Chris@16 5358 }
Chris@16 5359 BOOST_UBLAS_INLINE
Chris@16 5360 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5361 typename self_type::
Chris@16 5362 #endif
Chris@101 5363 const_reverse_iterator2 crbegin () const {
Chris@101 5364 return rbegin ();
Chris@101 5365 }
Chris@101 5366 BOOST_UBLAS_INLINE
Chris@101 5367 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 5368 typename self_type::
Chris@101 5369 #endif
Chris@16 5370 const_reverse_iterator2 rend () const {
Chris@16 5371 return const_reverse_iterator2 (begin ());
Chris@16 5372 }
Chris@101 5373 BOOST_UBLAS_INLINE
Chris@101 5374 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 5375 typename self_type::
Chris@101 5376 #endif
Chris@101 5377 const_reverse_iterator2 crend () const {
Chris@101 5378 return rend ();
Chris@101 5379 }
Chris@16 5380 #endif
Chris@16 5381
Chris@16 5382 // Indices
Chris@16 5383 BOOST_UBLAS_INLINE
Chris@16 5384 size_type index1 () const {
Chris@16 5385 const self_type &m = (*this) ();
Chris@16 5386 return (it_ - m.begin1 ().it_) / M;
Chris@16 5387 }
Chris@16 5388 BOOST_UBLAS_INLINE
Chris@16 5389 size_type index2 () const {
Chris@16 5390 const self_type &m = (*this) ();
Chris@16 5391 return (it_ - m.begin1 ().it_) % M;
Chris@16 5392 }
Chris@16 5393
Chris@16 5394 // Assignment
Chris@16 5395 BOOST_UBLAS_INLINE
Chris@16 5396 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 5397 container_const_reference<self_type>::assign (&it ());
Chris@16 5398 it_ = it.it_;
Chris@16 5399 return *this;
Chris@16 5400 }
Chris@16 5401
Chris@16 5402 // Comparison
Chris@16 5403 BOOST_UBLAS_INLINE
Chris@16 5404 bool operator == (const const_iterator1 &it) const {
Chris@16 5405 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5406 return it_ == it.it_;
Chris@16 5407 }
Chris@16 5408 BOOST_UBLAS_INLINE
Chris@16 5409 bool operator < (const const_iterator1 &it) const {
Chris@16 5410 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5411 return it_ < it.it_;
Chris@16 5412 }
Chris@16 5413
Chris@16 5414 private:
Chris@16 5415 const_subiterator_type it_;
Chris@16 5416
Chris@16 5417 friend class iterator1;
Chris@16 5418 };
Chris@16 5419 #endif
Chris@16 5420
Chris@16 5421 BOOST_UBLAS_INLINE
Chris@16 5422 const_iterator1 begin1 () const {
Chris@16 5423 return find1 (0, 0, 0);
Chris@16 5424 }
Chris@16 5425 BOOST_UBLAS_INLINE
Chris@101 5426 const_iterator1 cbegin1 () const {
Chris@101 5427 return begin1 ();
Chris@101 5428 }
Chris@101 5429 BOOST_UBLAS_INLINE
Chris@16 5430 const_iterator1 end1 () const {
Chris@16 5431 return find1 (0, size1_, 0);
Chris@16 5432 }
Chris@101 5433 BOOST_UBLAS_INLINE
Chris@101 5434 const_iterator1 cend1 () const {
Chris@101 5435 return end1 ();
Chris@101 5436 }
Chris@16 5437
Chris@16 5438 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5439 class iterator1:
Chris@16 5440 public container_reference<c_matrix>,
Chris@16 5441 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 5442 iterator1, value_type> {
Chris@16 5443 public:
Chris@16 5444
Chris@16 5445 typedef typename c_matrix::difference_type difference_type;
Chris@16 5446 typedef typename c_matrix::value_type value_type;
Chris@16 5447 typedef typename c_matrix::reference reference;
Chris@16 5448 typedef typename c_matrix::pointer pointer;
Chris@16 5449
Chris@16 5450 typedef iterator2 dual_iterator_type;
Chris@16 5451 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 5452
Chris@16 5453 // Construction and destruction
Chris@16 5454 BOOST_UBLAS_INLINE
Chris@16 5455 iterator1 ():
Chris@16 5456 container_reference<self_type> (), it_ () {}
Chris@16 5457 BOOST_UBLAS_INLINE
Chris@16 5458 iterator1 (self_type &m, const subiterator_type &it):
Chris@16 5459 container_reference<self_type> (m), it_ (it) {}
Chris@16 5460
Chris@16 5461 // Arithmetic
Chris@16 5462 BOOST_UBLAS_INLINE
Chris@16 5463 iterator1 &operator ++ () {
Chris@16 5464 it_ += M;
Chris@16 5465 return *this;
Chris@16 5466 }
Chris@16 5467 BOOST_UBLAS_INLINE
Chris@16 5468 iterator1 &operator -- () {
Chris@16 5469 it_ -= M;
Chris@16 5470 return *this;
Chris@16 5471 }
Chris@16 5472 BOOST_UBLAS_INLINE
Chris@16 5473 iterator1 &operator += (difference_type n) {
Chris@16 5474 it_ += n * M;
Chris@16 5475 return *this;
Chris@16 5476 }
Chris@16 5477 BOOST_UBLAS_INLINE
Chris@16 5478 iterator1 &operator -= (difference_type n) {
Chris@16 5479 it_ -= n * M;
Chris@16 5480 return *this;
Chris@16 5481 }
Chris@16 5482 BOOST_UBLAS_INLINE
Chris@16 5483 difference_type operator - (const iterator1 &it) const {
Chris@16 5484 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5485 return (it_ - it.it_) / M;
Chris@16 5486 }
Chris@16 5487
Chris@16 5488 // Dereference
Chris@16 5489 BOOST_UBLAS_INLINE
Chris@16 5490 reference operator * () const {
Chris@16 5491 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 5492 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 5493 return *it_;
Chris@16 5494 }
Chris@16 5495 BOOST_UBLAS_INLINE
Chris@16 5496 reference operator [] (difference_type n) const {
Chris@16 5497 return *(*this + n);
Chris@16 5498 }
Chris@16 5499
Chris@16 5500 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 5501 BOOST_UBLAS_INLINE
Chris@16 5502 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5503 typename self_type::
Chris@16 5504 #endif
Chris@16 5505 iterator2 begin () const {
Chris@16 5506 self_type &m = (*this) ();
Chris@16 5507 return m.find2 (1, index1 (), 0);
Chris@16 5508 }
Chris@16 5509 BOOST_UBLAS_INLINE
Chris@16 5510 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5511 typename self_type::
Chris@16 5512 #endif
Chris@16 5513 iterator2 end () const {
Chris@16 5514 self_type &m = (*this) ();
Chris@16 5515 return m.find2 (1, index1 (), m.size2 ());
Chris@16 5516 }
Chris@16 5517 BOOST_UBLAS_INLINE
Chris@16 5518 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5519 typename self_type::
Chris@16 5520 #endif
Chris@16 5521 reverse_iterator2 rbegin () const {
Chris@16 5522 return reverse_iterator2 (end ());
Chris@16 5523 }
Chris@16 5524 BOOST_UBLAS_INLINE
Chris@16 5525 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5526 typename self_type::
Chris@16 5527 #endif
Chris@16 5528 reverse_iterator2 rend () const {
Chris@16 5529 return reverse_iterator2 (begin ());
Chris@16 5530 }
Chris@16 5531 #endif
Chris@16 5532
Chris@16 5533 // Indices
Chris@16 5534 BOOST_UBLAS_INLINE
Chris@16 5535 size_type index1 () const {
Chris@16 5536 const self_type &m = (*this) ();
Chris@16 5537 return (it_ - m.begin1 ().it_) / M;
Chris@16 5538 }
Chris@16 5539 BOOST_UBLAS_INLINE
Chris@16 5540 size_type index2 () const {
Chris@16 5541 const self_type &m = (*this) ();
Chris@16 5542 return (it_ - m.begin1 ().it_) % M;
Chris@16 5543 }
Chris@16 5544
Chris@16 5545 // Assignment
Chris@16 5546 BOOST_UBLAS_INLINE
Chris@16 5547 iterator1 &operator = (const iterator1 &it) {
Chris@16 5548 container_reference<self_type>::assign (&it ());
Chris@16 5549 it_ = it.it_;
Chris@16 5550 return *this;
Chris@16 5551 }
Chris@16 5552
Chris@16 5553 // Comparison
Chris@16 5554 BOOST_UBLAS_INLINE
Chris@16 5555 bool operator == (const iterator1 &it) const {
Chris@16 5556 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5557 return it_ == it.it_;
Chris@16 5558 }
Chris@16 5559 BOOST_UBLAS_INLINE
Chris@16 5560 bool operator < (const iterator1 &it) const {
Chris@16 5561 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5562 return it_ < it.it_;
Chris@16 5563 }
Chris@16 5564
Chris@16 5565 private:
Chris@16 5566 subiterator_type it_;
Chris@16 5567
Chris@16 5568 friend class const_iterator1;
Chris@16 5569 };
Chris@16 5570 #endif
Chris@16 5571
Chris@16 5572 BOOST_UBLAS_INLINE
Chris@16 5573 iterator1 begin1 () {
Chris@16 5574 return find1 (0, 0, 0);
Chris@16 5575 }
Chris@16 5576 BOOST_UBLAS_INLINE
Chris@16 5577 iterator1 end1 () {
Chris@16 5578 return find1 (0, size1_, 0);
Chris@16 5579 }
Chris@16 5580
Chris@16 5581 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5582 class const_iterator2:
Chris@16 5583 public container_const_reference<c_matrix>,
Chris@16 5584 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 5585 const_iterator2, value_type> {
Chris@16 5586 public:
Chris@16 5587 typedef typename c_matrix::difference_type difference_type;
Chris@16 5588 typedef typename c_matrix::value_type value_type;
Chris@16 5589 typedef typename c_matrix::const_reference reference;
Chris@16 5590 typedef typename c_matrix::const_reference pointer;
Chris@16 5591
Chris@16 5592 typedef const_iterator1 dual_iterator_type;
Chris@16 5593 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 5594
Chris@16 5595 // Construction and destruction
Chris@16 5596 BOOST_UBLAS_INLINE
Chris@16 5597 const_iterator2 ():
Chris@16 5598 container_const_reference<self_type> (), it_ () {}
Chris@16 5599 BOOST_UBLAS_INLINE
Chris@16 5600 const_iterator2 (const self_type &m, const const_subiterator_type &it):
Chris@16 5601 container_const_reference<self_type> (m), it_ (it) {}
Chris@16 5602 BOOST_UBLAS_INLINE
Chris@16 5603 const_iterator2 (const iterator2 &it):
Chris@16 5604 container_const_reference<self_type> (it ()), it_ (it.it_) {}
Chris@16 5605
Chris@16 5606 // Arithmetic
Chris@16 5607 BOOST_UBLAS_INLINE
Chris@16 5608 const_iterator2 &operator ++ () {
Chris@16 5609 ++ it_;
Chris@16 5610 return *this;
Chris@16 5611 }
Chris@16 5612 BOOST_UBLAS_INLINE
Chris@16 5613 const_iterator2 &operator -- () {
Chris@16 5614 -- it_;
Chris@16 5615 return *this;
Chris@16 5616 }
Chris@16 5617 BOOST_UBLAS_INLINE
Chris@16 5618 const_iterator2 &operator += (difference_type n) {
Chris@16 5619 it_ += n;
Chris@16 5620 return *this;
Chris@16 5621 }
Chris@16 5622 BOOST_UBLAS_INLINE
Chris@16 5623 const_iterator2 &operator -= (difference_type n) {
Chris@16 5624 it_ -= n;
Chris@16 5625 return *this;
Chris@16 5626 }
Chris@16 5627 BOOST_UBLAS_INLINE
Chris@16 5628 difference_type operator - (const const_iterator2 &it) const {
Chris@16 5629 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5630 return it_ - it.it_;
Chris@16 5631 }
Chris@16 5632
Chris@16 5633 // Dereference
Chris@16 5634 BOOST_UBLAS_INLINE
Chris@16 5635 const_reference operator * () const {
Chris@16 5636 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 5637 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 5638 return *it_;
Chris@16 5639 }
Chris@16 5640 BOOST_UBLAS_INLINE
Chris@16 5641 const_reference operator [] (difference_type n) const {
Chris@16 5642 return *(*this + n);
Chris@16 5643 }
Chris@16 5644
Chris@16 5645 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 5646 BOOST_UBLAS_INLINE
Chris@16 5647 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5648 typename self_type::
Chris@16 5649 #endif
Chris@16 5650 const_iterator1 begin () const {
Chris@16 5651 const self_type &m = (*this) ();
Chris@16 5652 return m.find1 (1, 0, index2 ());
Chris@16 5653 }
Chris@16 5654 BOOST_UBLAS_INLINE
Chris@16 5655 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5656 typename self_type::
Chris@16 5657 #endif
Chris@101 5658 const_iterator1 cbegin () const {
Chris@101 5659 return begin ();
Chris@101 5660 }
Chris@101 5661 BOOST_UBLAS_INLINE
Chris@101 5662 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 5663 typename self_type::
Chris@101 5664 #endif
Chris@16 5665 const_iterator1 end () const {
Chris@16 5666 const self_type &m = (*this) ();
Chris@16 5667 return m.find1 (1, m.size1 (), index2 ());
Chris@16 5668 }
Chris@16 5669 BOOST_UBLAS_INLINE
Chris@16 5670 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5671 typename self_type::
Chris@16 5672 #endif
Chris@101 5673 const_iterator1 cend () const {
Chris@101 5674 return end ();
Chris@101 5675 }
Chris@101 5676 BOOST_UBLAS_INLINE
Chris@101 5677 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 5678 typename self_type::
Chris@101 5679 #endif
Chris@16 5680 const_reverse_iterator1 rbegin () const {
Chris@16 5681 return const_reverse_iterator1 (end ());
Chris@16 5682 }
Chris@16 5683 BOOST_UBLAS_INLINE
Chris@16 5684 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5685 typename self_type::
Chris@16 5686 #endif
Chris@101 5687 const_reverse_iterator1 crbegin () const {
Chris@101 5688 return rbegin ();
Chris@101 5689 }
Chris@101 5690 BOOST_UBLAS_INLINE
Chris@101 5691 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 5692 typename self_type::
Chris@101 5693 #endif
Chris@16 5694 const_reverse_iterator1 rend () const {
Chris@16 5695 return const_reverse_iterator1 (begin ());
Chris@16 5696 }
Chris@101 5697 BOOST_UBLAS_INLINE
Chris@101 5698 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 5699 typename self_type::
Chris@101 5700 #endif
Chris@101 5701 const_reverse_iterator1 crend () const {
Chris@101 5702 return rend ();
Chris@101 5703 }
Chris@16 5704 #endif
Chris@16 5705
Chris@16 5706 // Indices
Chris@16 5707 BOOST_UBLAS_INLINE
Chris@16 5708 size_type index1 () const {
Chris@16 5709 const self_type &m = (*this) ();
Chris@16 5710 return (it_ - m.begin2 ().it_) / M;
Chris@16 5711 }
Chris@16 5712 BOOST_UBLAS_INLINE
Chris@16 5713 size_type index2 () const {
Chris@16 5714 const self_type &m = (*this) ();
Chris@16 5715 return (it_ - m.begin2 ().it_) % M;
Chris@16 5716 }
Chris@16 5717
Chris@16 5718 // Assignment
Chris@16 5719 BOOST_UBLAS_INLINE
Chris@16 5720 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 5721 container_const_reference<self_type>::assign (&it ());
Chris@16 5722 it_ = it.it_;
Chris@16 5723 return *this;
Chris@16 5724 }
Chris@16 5725
Chris@16 5726 // Comparison
Chris@16 5727 BOOST_UBLAS_INLINE
Chris@16 5728 bool operator == (const const_iterator2 &it) const {
Chris@16 5729 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5730 return it_ == it.it_;
Chris@16 5731 }
Chris@16 5732 BOOST_UBLAS_INLINE
Chris@16 5733 bool operator < (const const_iterator2 &it) const {
Chris@16 5734 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5735 return it_ < it.it_;
Chris@16 5736 }
Chris@16 5737
Chris@16 5738 private:
Chris@16 5739 const_subiterator_type it_;
Chris@16 5740
Chris@16 5741 friend class iterator2;
Chris@16 5742 };
Chris@16 5743 #endif
Chris@16 5744
Chris@16 5745 BOOST_UBLAS_INLINE
Chris@16 5746 const_iterator2 begin2 () const {
Chris@16 5747 return find2 (0, 0, 0);
Chris@16 5748 }
Chris@16 5749 BOOST_UBLAS_INLINE
Chris@101 5750 const_iterator2 cbegin2 () const {
Chris@101 5751 return begin2 ();
Chris@101 5752 }
Chris@101 5753 BOOST_UBLAS_INLINE
Chris@16 5754 const_iterator2 end2 () const {
Chris@16 5755 return find2 (0, 0, size2_);
Chris@16 5756 }
Chris@101 5757 BOOST_UBLAS_INLINE
Chris@101 5758 const_iterator2 cend2 () const {
Chris@101 5759 return end2 ();
Chris@101 5760 }
Chris@16 5761
Chris@16 5762 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 5763 class iterator2:
Chris@16 5764 public container_reference<c_matrix>,
Chris@16 5765 public random_access_iterator_base<dense_random_access_iterator_tag,
Chris@16 5766 iterator2, value_type> {
Chris@16 5767 public:
Chris@16 5768 typedef typename c_matrix::difference_type difference_type;
Chris@16 5769 typedef typename c_matrix::value_type value_type;
Chris@16 5770 typedef typename c_matrix::reference reference;
Chris@16 5771 typedef typename c_matrix::pointer pointer;
Chris@16 5772
Chris@16 5773 typedef iterator1 dual_iterator_type;
Chris@16 5774 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 5775
Chris@16 5776 // Construction and destruction
Chris@16 5777 BOOST_UBLAS_INLINE
Chris@16 5778 iterator2 ():
Chris@16 5779 container_reference<self_type> (), it_ () {}
Chris@16 5780 BOOST_UBLAS_INLINE
Chris@16 5781 iterator2 (self_type &m, const subiterator_type &it):
Chris@16 5782 container_reference<self_type> (m), it_ (it) {}
Chris@16 5783
Chris@16 5784 // Arithmetic
Chris@16 5785 BOOST_UBLAS_INLINE
Chris@16 5786 iterator2 &operator ++ () {
Chris@16 5787 ++ it_;
Chris@16 5788 return *this;
Chris@16 5789 }
Chris@16 5790 BOOST_UBLAS_INLINE
Chris@16 5791 iterator2 &operator -- () {
Chris@16 5792 -- it_;
Chris@16 5793 return *this;
Chris@16 5794 }
Chris@16 5795 BOOST_UBLAS_INLINE
Chris@16 5796 iterator2 &operator += (difference_type n) {
Chris@16 5797 it_ += n;
Chris@16 5798 return *this;
Chris@16 5799 }
Chris@16 5800 BOOST_UBLAS_INLINE
Chris@16 5801 iterator2 &operator -= (difference_type n) {
Chris@16 5802 it_ -= n;
Chris@16 5803 return *this;
Chris@16 5804 }
Chris@16 5805 BOOST_UBLAS_INLINE
Chris@16 5806 difference_type operator - (const iterator2 &it) const {
Chris@16 5807 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5808 return it_ - it.it_;
Chris@16 5809 }
Chris@16 5810
Chris@16 5811 // Dereference
Chris@16 5812 BOOST_UBLAS_INLINE
Chris@16 5813 reference operator * () const {
Chris@16 5814 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
Chris@16 5815 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
Chris@16 5816 return *it_;
Chris@16 5817 }
Chris@16 5818 BOOST_UBLAS_INLINE
Chris@16 5819 reference operator [] (difference_type n) const {
Chris@16 5820 return *(*this + n);
Chris@16 5821 }
Chris@16 5822
Chris@16 5823 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 5824 BOOST_UBLAS_INLINE
Chris@16 5825 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5826 typename self_type::
Chris@16 5827 #endif
Chris@16 5828 iterator1 begin () const {
Chris@16 5829 self_type &m = (*this) ();
Chris@16 5830 return m.find1 (1, 0, index2 ());
Chris@16 5831 }
Chris@16 5832 BOOST_UBLAS_INLINE
Chris@16 5833 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5834 typename self_type::
Chris@16 5835 #endif
Chris@16 5836 iterator1 end () const {
Chris@16 5837 self_type &m = (*this) ();
Chris@16 5838 return m.find1 (1, m.size1 (), index2 ());
Chris@16 5839 }
Chris@16 5840 BOOST_UBLAS_INLINE
Chris@16 5841 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5842 typename self_type::
Chris@16 5843 #endif
Chris@16 5844 reverse_iterator1 rbegin () const {
Chris@16 5845 return reverse_iterator1 (end ());
Chris@16 5846 }
Chris@16 5847 BOOST_UBLAS_INLINE
Chris@16 5848 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 5849 typename self_type::
Chris@16 5850 #endif
Chris@16 5851 reverse_iterator1 rend () const {
Chris@16 5852 return reverse_iterator1 (begin ());
Chris@16 5853 }
Chris@16 5854 #endif
Chris@16 5855
Chris@16 5856 // Indices
Chris@16 5857 BOOST_UBLAS_INLINE
Chris@16 5858 size_type index1 () const {
Chris@16 5859 const self_type &m = (*this) ();
Chris@16 5860 return (it_ - m.begin2 ().it_) / M;
Chris@16 5861 }
Chris@16 5862 BOOST_UBLAS_INLINE
Chris@16 5863 size_type index2 () const {
Chris@16 5864 const self_type &m = (*this) ();
Chris@16 5865 return (it_ - m.begin2 ().it_) % M;
Chris@16 5866 }
Chris@16 5867
Chris@16 5868 // Assignment
Chris@16 5869 BOOST_UBLAS_INLINE
Chris@16 5870 iterator2 &operator = (const iterator2 &it) {
Chris@16 5871 container_reference<self_type>::assign (&it ());
Chris@16 5872 it_ = it.it_;
Chris@16 5873 return *this;
Chris@16 5874 }
Chris@16 5875
Chris@16 5876 // Comparison
Chris@16 5877 BOOST_UBLAS_INLINE
Chris@16 5878 bool operator == (const iterator2 &it) const {
Chris@16 5879 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5880 return it_ == it.it_;
Chris@16 5881 }
Chris@16 5882 BOOST_UBLAS_INLINE
Chris@16 5883 bool operator < (const iterator2 &it) const {
Chris@16 5884 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 5885 return it_ < it.it_;
Chris@16 5886 }
Chris@16 5887
Chris@16 5888 private:
Chris@16 5889 subiterator_type it_;
Chris@16 5890
Chris@16 5891 friend class const_iterator2;
Chris@16 5892 };
Chris@16 5893 #endif
Chris@16 5894
Chris@16 5895 BOOST_UBLAS_INLINE
Chris@16 5896 iterator2 begin2 () {
Chris@16 5897 return find2 (0, 0, 0);
Chris@16 5898 }
Chris@16 5899 BOOST_UBLAS_INLINE
Chris@16 5900 iterator2 end2 () {
Chris@16 5901 return find2 (0, 0, size2_);
Chris@16 5902 }
Chris@16 5903
Chris@16 5904 // Reverse iterators
Chris@16 5905
Chris@16 5906 BOOST_UBLAS_INLINE
Chris@16 5907 const_reverse_iterator1 rbegin1 () const {
Chris@16 5908 return const_reverse_iterator1 (end1 ());
Chris@16 5909 }
Chris@16 5910 BOOST_UBLAS_INLINE
Chris@101 5911 const_reverse_iterator1 crbegin1 () const {
Chris@101 5912 return rbegin1 ();
Chris@101 5913 }
Chris@101 5914 BOOST_UBLAS_INLINE
Chris@16 5915 const_reverse_iterator1 rend1 () const {
Chris@16 5916 return const_reverse_iterator1 (begin1 ());
Chris@16 5917 }
Chris@101 5918 BOOST_UBLAS_INLINE
Chris@101 5919 const_reverse_iterator1 crend1 () const {
Chris@101 5920 return rend1 ();
Chris@101 5921 }
Chris@16 5922
Chris@16 5923 BOOST_UBLAS_INLINE
Chris@16 5924 reverse_iterator1 rbegin1 () {
Chris@16 5925 return reverse_iterator1 (end1 ());
Chris@16 5926 }
Chris@16 5927 BOOST_UBLAS_INLINE
Chris@16 5928 reverse_iterator1 rend1 () {
Chris@16 5929 return reverse_iterator1 (begin1 ());
Chris@16 5930 }
Chris@16 5931
Chris@16 5932 BOOST_UBLAS_INLINE
Chris@16 5933 const_reverse_iterator2 rbegin2 () const {
Chris@16 5934 return const_reverse_iterator2 (end2 ());
Chris@16 5935 }
Chris@16 5936 BOOST_UBLAS_INLINE
Chris@101 5937 const_reverse_iterator2 crbegin2 () const {
Chris@101 5938 return rbegin2 ();
Chris@101 5939 }
Chris@101 5940 BOOST_UBLAS_INLINE
Chris@16 5941 const_reverse_iterator2 rend2 () const {
Chris@16 5942 return const_reverse_iterator2 (begin2 ());
Chris@16 5943 }
Chris@101 5944 BOOST_UBLAS_INLINE
Chris@101 5945 const_reverse_iterator2 crend2 () const {
Chris@101 5946 return rend2 ();
Chris@101 5947 }
Chris@16 5948
Chris@16 5949 BOOST_UBLAS_INLINE
Chris@16 5950 reverse_iterator2 rbegin2 () {
Chris@16 5951 return reverse_iterator2 (end2 ());
Chris@16 5952 }
Chris@16 5953 BOOST_UBLAS_INLINE
Chris@16 5954 reverse_iterator2 rend2 () {
Chris@16 5955 return reverse_iterator2 (begin2 ());
Chris@16 5956 }
Chris@16 5957
Chris@16 5958 // Serialization
Chris@16 5959 template<class Archive>
Chris@16 5960 void serialize(Archive & ar, const unsigned int /* file_version */){
Chris@16 5961
Chris@16 5962 // we need to copy to a collection_size_type to get a portable
Chris@16 5963 // and efficient serialization
Chris@16 5964 serialization::collection_size_type s1 (size1_);
Chris@16 5965 serialization::collection_size_type s2 (size2_);
Chris@16 5966
Chris@16 5967 // serialize the sizes
Chris@16 5968 ar & serialization::make_nvp("size1",s1)
Chris@16 5969 & serialization::make_nvp("size2",s2);
Chris@16 5970
Chris@16 5971 // copy the values back if loading
Chris@16 5972 if (Archive::is_loading::value) {
Chris@16 5973 size1_ = s1;
Chris@16 5974 size2_ = s2;
Chris@16 5975 }
Chris@16 5976 // could probably use make_array( &(data[0][0]), N*M )
Chris@16 5977 ar & serialization::make_array(data_, N);
Chris@16 5978 }
Chris@16 5979
Chris@16 5980 private:
Chris@16 5981 size_type size1_;
Chris@16 5982 size_type size2_;
Chris@16 5983 value_type data_ [N] [M];
Chris@16 5984 };
Chris@16 5985
Chris@16 5986 }}}
Chris@16 5987
Chris@16 5988 #endif