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