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