File indexing completed on 2025-12-16 09:58:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef _BOOST_UBLAS_MATRIX_ASSIGN_
0014 #define _BOOST_UBLAS_MATRIX_ASSIGN_
0015
0016 #include <boost/numeric/ublas/traits.hpp>
0017
0018 #include <vector>
0019
0020
0021
0022 namespace boost { namespace numeric { namespace ublas {
0023 namespace detail {
0024
0025
0026
0027
0028
0029
0030 template<class E1, class E2, class S>
0031 BOOST_UBLAS_INLINE
0032 bool equals (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2, S epsilon, S min_norm) {
0033 return norm_inf (e1 - e2) <= epsilon *
0034 std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
0035 }
0036
0037 template<class E1, class E2>
0038 BOOST_UBLAS_INLINE
0039 bool expression_type_check (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
0040 typedef typename type_traits<typename promote_traits<typename E1::value_type,
0041 typename E2::value_type>::promote_type>::real_type real_type;
0042 return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
0043 }
0044
0045
0046 template<class M, class E, class R>
0047
0048 void make_conformant (M &m, const matrix_expression<E> &e, row_major_tag, R) {
0049 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
0050 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
0051 typedef R conformant_restrict_type;
0052 typedef typename M::size_type size_type;
0053 typedef typename M::difference_type difference_type;
0054 typedef typename M::value_type value_type;
0055
0056 std::vector<std::pair<size_type, size_type> > index;
0057 typename M::iterator1 it1 (m.begin1 ());
0058 typename M::iterator1 it1_end (m.end1 ());
0059 typename E::const_iterator1 it1e (e ().begin1 ());
0060 typename E::const_iterator1 it1e_end (e ().end1 ());
0061 while (it1 != it1_end && it1e != it1e_end) {
0062 difference_type compare = it1.index1 () - it1e.index1 ();
0063 if (compare == 0) {
0064 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0065 typename M::iterator2 it2 (it1.begin ());
0066 typename M::iterator2 it2_end (it1.end ());
0067 typename E::const_iterator2 it2e (it1e.begin ());
0068 typename E::const_iterator2 it2e_end (it1e.end ());
0069 #else
0070 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
0071 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
0072 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
0073 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
0074 #endif
0075 if (it2 != it2_end && it2e != it2e_end) {
0076 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
0077 for (;;) {
0078 difference_type compare2 = it2_index - it2e_index;
0079 if (compare2 == 0) {
0080 ++ it2, ++ it2e;
0081 if (it2 != it2_end && it2e != it2e_end) {
0082 it2_index = it2.index2 ();
0083 it2e_index = it2e.index2 ();
0084 } else
0085 break;
0086 } else if (compare2 < 0) {
0087 increment (it2, it2_end, - compare2);
0088 if (it2 != it2_end)
0089 it2_index = it2.index2 ();
0090 else
0091 break;
0092 } else if (compare2 > 0) {
0093 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
0094 if (static_cast<value_type>(*it2e) != value_type())
0095 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
0096 ++ it2e;
0097 if (it2e != it2e_end)
0098 it2e_index = it2e.index2 ();
0099 else
0100 break;
0101 }
0102 }
0103 }
0104 while (it2e != it2e_end) {
0105 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
0106 if (static_cast<value_type>(*it2e) != value_type())
0107 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
0108 ++ it2e;
0109 }
0110 ++ it1, ++ it1e;
0111 } else if (compare < 0) {
0112 increment (it1, it1_end, - compare);
0113 } else if (compare > 0) {
0114 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0115 typename E::const_iterator2 it2e (it1e.begin ());
0116 typename E::const_iterator2 it2e_end (it1e.end ());
0117 #else
0118 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
0119 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
0120 #endif
0121 while (it2e != it2e_end) {
0122 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
0123 if (static_cast<value_type>(*it2e) != value_type())
0124 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
0125 ++ it2e;
0126 }
0127 ++ it1e;
0128 }
0129 }
0130 while (it1e != it1e_end) {
0131 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0132 typename E::const_iterator2 it2e (it1e.begin ());
0133 typename E::const_iterator2 it2e_end (it1e.end ());
0134 #else
0135 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
0136 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
0137 #endif
0138 while (it2e != it2e_end) {
0139 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
0140 if (static_cast<value_type>(*it2e) != value_type())
0141 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
0142 ++ it2e;
0143 }
0144 ++ it1e;
0145 }
0146
0147 for (size_type k = 0; k < index.size (); ++ k)
0148 m (index [k].first, index [k].second) = value_type();
0149 }
0150 template<class M, class E, class R>
0151
0152 void make_conformant (M &m, const matrix_expression<E> &e, column_major_tag, R) {
0153 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
0154 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
0155 typedef R conformant_restrict_type;
0156 typedef typename M::size_type size_type;
0157 typedef typename M::difference_type difference_type;
0158 typedef typename M::value_type value_type;
0159 std::vector<std::pair<size_type, size_type> > index;
0160 typename M::iterator2 it2 (m.begin2 ());
0161 typename M::iterator2 it2_end (m.end2 ());
0162 typename E::const_iterator2 it2e (e ().begin2 ());
0163 typename E::const_iterator2 it2e_end (e ().end2 ());
0164 while (it2 != it2_end && it2e != it2e_end) {
0165 difference_type compare = it2.index2 () - it2e.index2 ();
0166 if (compare == 0) {
0167 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0168 typename M::iterator1 it1 (it2.begin ());
0169 typename M::iterator1 it1_end (it2.end ());
0170 typename E::const_iterator1 it1e (it2e.begin ());
0171 typename E::const_iterator1 it1e_end (it2e.end ());
0172 #else
0173 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
0174 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
0175 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
0176 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
0177 #endif
0178 if (it1 != it1_end && it1e != it1e_end) {
0179 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
0180 for (;;) {
0181 difference_type compare2 = it1_index - it1e_index;
0182 if (compare2 == 0) {
0183 ++ it1, ++ it1e;
0184 if (it1 != it1_end && it1e != it1e_end) {
0185 it1_index = it1.index1 ();
0186 it1e_index = it1e.index1 ();
0187 } else
0188 break;
0189 } else if (compare2 < 0) {
0190 increment (it1, it1_end, - compare2);
0191 if (it1 != it1_end)
0192 it1_index = it1.index1 ();
0193 else
0194 break;
0195 } else if (compare2 > 0) {
0196 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
0197 if (static_cast<value_type>(*it1e) != value_type())
0198 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
0199 ++ it1e;
0200 if (it1e != it1e_end)
0201 it1e_index = it1e.index1 ();
0202 else
0203 break;
0204 }
0205 }
0206 }
0207 while (it1e != it1e_end) {
0208 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
0209 if (static_cast<value_type>(*it1e) != value_type())
0210 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
0211 ++ it1e;
0212 }
0213 ++ it2, ++ it2e;
0214 } else if (compare < 0) {
0215 increment (it2, it2_end, - compare);
0216 } else if (compare > 0) {
0217 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0218 typename E::const_iterator1 it1e (it2e.begin ());
0219 typename E::const_iterator1 it1e_end (it2e.end ());
0220 #else
0221 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
0222 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
0223 #endif
0224 while (it1e != it1e_end) {
0225 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
0226 if (static_cast<value_type>(*it1e) != value_type())
0227 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
0228 ++ it1e;
0229 }
0230 ++ it2e;
0231 }
0232 }
0233 while (it2e != it2e_end) {
0234 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0235 typename E::const_iterator1 it1e (it2e.begin ());
0236 typename E::const_iterator1 it1e_end (it2e.end ());
0237 #else
0238 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
0239 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
0240 #endif
0241 while (it1e != it1e_end) {
0242 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
0243 if (static_cast<value_type>(*it1e) != value_type())
0244 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
0245 ++ it1e;
0246 }
0247 ++ it2e;
0248 }
0249
0250 for (size_type k = 0; k < index.size (); ++ k)
0251 m (index [k].first, index [k].second) = value_type();
0252 }
0253
0254 }
0255
0256
0257
0258 template<template <class T1, class T2> class F, class M, class T>
0259
0260 void iterating_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
0261 typedef F<typename M::iterator2::reference, T> functor_type;
0262 typedef typename M::difference_type difference_type;
0263 difference_type size1 (m.size1 ());
0264 difference_type size2 (m.size2 ());
0265 typename M::iterator1 it1 (m.begin1 ());
0266 BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
0267 while (-- size1 >= 0) {
0268 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0269 typename M::iterator2 it2 (it1.begin ());
0270 #else
0271 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
0272 #endif
0273 BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
0274 difference_type temp_size2 (size2);
0275 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
0276 while (-- temp_size2 >= 0)
0277 functor_type::apply (*it2, t), ++ it2;
0278 #else
0279 DD (temp_size2, 4, r, (functor_type::apply (*it2, t), ++ it2));
0280 #endif
0281 ++ it1;
0282 }
0283 }
0284
0285 template<template <class T1, class T2> class F, class M, class T>
0286
0287 void iterating_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
0288 typedef F<typename M::iterator1::reference, T> functor_type;
0289 typedef typename M::difference_type difference_type;
0290 difference_type size2 (m.size2 ());
0291 difference_type size1 (m.size1 ());
0292 typename M::iterator2 it2 (m.begin2 ());
0293 BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
0294 while (-- size2 >= 0) {
0295 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0296 typename M::iterator1 it1 (it2.begin ());
0297 #else
0298 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
0299 #endif
0300 BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
0301 difference_type temp_size1 (size1);
0302 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
0303 while (-- temp_size1 >= 0)
0304 functor_type::apply (*it1, t), ++ it1;
0305 #else
0306 DD (temp_size1, 4, r, (functor_type::apply (*it1, t), ++ it1));
0307 #endif
0308 ++ it2;
0309 }
0310 }
0311
0312 template<template <class T1, class T2> class F, class M, class T>
0313
0314 void indexing_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
0315 typedef F<typename M::reference, T> functor_type;
0316 typedef typename M::size_type size_type;
0317 size_type size1 (m.size1 ());
0318 size_type size2 (m.size2 ());
0319 for (size_type i = 0; i < size1; ++ i) {
0320 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
0321 for (size_type j = 0; j < size2; ++ j)
0322 functor_type::apply (m (i, j), t);
0323 #else
0324 size_type j (0);
0325 DD (size2, 4, r, (functor_type::apply (m (i, j), t), ++ j));
0326 #endif
0327 }
0328 }
0329
0330 template<template <class T1, class T2> class F, class M, class T>
0331
0332 void indexing_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
0333 typedef F<typename M::reference, T> functor_type;
0334 typedef typename M::size_type size_type;
0335 size_type size2 (m.size2 ());
0336 size_type size1 (m.size1 ());
0337 for (size_type j = 0; j < size2; ++ j) {
0338 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
0339 for (size_type i = 0; i < size1; ++ i)
0340 functor_type::apply (m (i, j), t);
0341 #else
0342 size_type i (0);
0343 DD (size1, 4, r, (functor_type::apply (m (i, j), t), ++ i));
0344 #endif
0345 }
0346 }
0347
0348
0349 template<template <class T1, class T2> class F, class M, class T, class C>
0350
0351 void matrix_assign_scalar (M &m, const T &t, dense_proxy_tag, C) {
0352 typedef C orientation_category;
0353 #ifdef BOOST_UBLAS_USE_INDEXING
0354 indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
0355 #elif BOOST_UBLAS_USE_ITERATING
0356 iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
0357 #else
0358 typedef typename M::size_type size_type;
0359 size_type size1 (m.size1 ());
0360 size_type size2 (m.size2 ());
0361 if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
0362 size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
0363 iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
0364 else
0365 indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
0366 #endif
0367 }
0368
0369 template<template <class T1, class T2> class F, class M, class T>
0370
0371 void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, row_major_tag) {
0372 typedef F<typename M::iterator2::reference, T> functor_type;
0373 typedef typename M::difference_type difference_type;
0374 typename M::iterator1 it1 (m.begin1 ());
0375 difference_type size1 (m.end1 () - it1);
0376 while (-- size1 >= 0) {
0377 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0378 typename M::iterator2 it2 (it1.begin ());
0379 difference_type size2 (it1.end () - it2);
0380 #else
0381 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
0382 difference_type size2 (end (it1, iterator1_tag ()) - it2);
0383 #endif
0384 while (-- size2 >= 0)
0385 functor_type::apply (*it2, t), ++ it2;
0386 ++ it1;
0387 }
0388 }
0389
0390 template<template <class T1, class T2> class F, class M, class T>
0391
0392 void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, column_major_tag) {
0393 typedef F<typename M::iterator1::reference, T> functor_type;
0394 typedef typename M::difference_type difference_type;
0395 typename M::iterator2 it2 (m.begin2 ());
0396 difference_type size2 (m.end2 () - it2);
0397 while (-- size2 >= 0) {
0398 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0399 typename M::iterator1 it1 (it2.begin ());
0400 difference_type size1 (it2.end () - it1);
0401 #else
0402 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
0403 difference_type size1 (end (it2, iterator2_tag ()) - it1);
0404 #endif
0405 while (-- size1 >= 0)
0406 functor_type::apply (*it1, t), ++ it1;
0407 ++ it2;
0408 }
0409 }
0410
0411 template<template <class T1, class T2> class F, class M, class T>
0412
0413 void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, row_major_tag) {
0414 typedef F<typename M::iterator2::reference, T> functor_type;
0415 typename M::iterator1 it1 (m.begin1 ());
0416 typename M::iterator1 it1_end (m.end1 ());
0417 while (it1 != it1_end) {
0418 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0419 typename M::iterator2 it2 (it1.begin ());
0420 typename M::iterator2 it2_end (it1.end ());
0421 #else
0422 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
0423 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
0424 #endif
0425 while (it2 != it2_end)
0426 functor_type::apply (*it2, t), ++ it2;
0427 ++ it1;
0428 }
0429 }
0430
0431 template<template <class T1, class T2> class F, class M, class T>
0432
0433 void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, column_major_tag) {
0434 typedef F<typename M::iterator1::reference, T> functor_type;
0435 typename M::iterator2 it2 (m.begin2 ());
0436 typename M::iterator2 it2_end (m.end2 ());
0437 while (it2 != it2_end) {
0438 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0439 typename M::iterator1 it1 (it2.begin ());
0440 typename M::iterator1 it1_end (it2.end ());
0441 #else
0442 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
0443 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
0444 #endif
0445 while (it1 != it1_end)
0446 functor_type::apply (*it1, t), ++ it1;
0447 ++ it2;
0448 }
0449 }
0450
0451
0452 template<template <class T1, class T2> class F, class M, class T>
0453 BOOST_UBLAS_INLINE
0454 void matrix_assign_scalar (M &m, const T &t) {
0455 typedef typename M::storage_category storage_category;
0456 typedef typename M::orientation_category orientation_category;
0457 matrix_assign_scalar<F> (m, t, storage_category (), orientation_category ());
0458 }
0459
0460 template<class SC, bool COMPUTED, class RI1, class RI2>
0461 struct matrix_assign_traits {
0462 typedef SC storage_category;
0463 };
0464
0465 template<bool COMPUTED>
0466 struct matrix_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
0467 typedef packed_tag storage_category;
0468 };
0469 template<>
0470 struct matrix_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
0471 typedef sparse_tag storage_category;
0472 };
0473 template<>
0474 struct matrix_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
0475 typedef sparse_proxy_tag storage_category;
0476 };
0477
0478 template<bool COMPUTED>
0479 struct matrix_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
0480 typedef packed_proxy_tag storage_category;
0481 };
0482 template<bool COMPUTED>
0483 struct matrix_assign_traits<dense_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
0484 typedef sparse_proxy_tag storage_category;
0485 };
0486
0487 template<>
0488 struct matrix_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
0489 typedef sparse_tag storage_category;
0490 };
0491 template<>
0492 struct matrix_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
0493 typedef sparse_proxy_tag storage_category;
0494 };
0495
0496 template<bool COMPUTED>
0497 struct matrix_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
0498 typedef sparse_proxy_tag storage_category;
0499 };
0500
0501 template<>
0502 struct matrix_assign_traits<sparse_tag, true, dense_random_access_iterator_tag, dense_random_access_iterator_tag> {
0503 typedef sparse_proxy_tag storage_category;
0504 };
0505 template<>
0506 struct matrix_assign_traits<sparse_tag, true, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
0507 typedef sparse_proxy_tag storage_category;
0508 };
0509 template<>
0510 struct matrix_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
0511 typedef sparse_proxy_tag storage_category;
0512 };
0513
0514
0515 template<template <class T1, class T2> class F, class M, class E>
0516
0517 void iterating_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
0518 typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
0519 typedef typename M::difference_type difference_type;
0520 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
0521 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
0522 typename M::iterator1 it1 (m.begin1 ());
0523 BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
0524 typename E::const_iterator1 it1e (e ().begin1 ());
0525 BOOST_UBLAS_CHECK (size2 == 0 || e ().end1 () - it1e == size1, bad_size ());
0526 while (-- size1 >= 0) {
0527 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0528 typename M::iterator2 it2 (it1.begin ());
0529 typename E::const_iterator2 it2e (it1e.begin ());
0530 #else
0531 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
0532 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
0533 #endif
0534 BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
0535 BOOST_UBLAS_CHECK (it1e.end () - it2e == size2, bad_size ());
0536 difference_type temp_size2 (size2);
0537 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
0538 while (-- temp_size2 >= 0)
0539 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
0540 #else
0541 DD (temp_size2, 2, r, (functor_type::apply (*it2, *it2e), ++ it2, ++ it2e));
0542 #endif
0543 ++ it1, ++ it1e;
0544 }
0545 }
0546
0547 template<template <class T1, class T2> class F, class M, class E>
0548
0549 void iterating_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
0550 typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
0551 typedef typename M::difference_type difference_type;
0552 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
0553 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
0554 typename M::iterator2 it2 (m.begin2 ());
0555 BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
0556 typename E::const_iterator2 it2e (e ().begin2 ());
0557 BOOST_UBLAS_CHECK (size1 == 0 || e ().end2 () - it2e == size2, bad_size ());
0558 while (-- size2 >= 0) {
0559 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0560 typename M::iterator1 it1 (it2.begin ());
0561 typename E::const_iterator1 it1e (it2e.begin ());
0562 #else
0563 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
0564 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
0565 #endif
0566 BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
0567 BOOST_UBLAS_CHECK (it2e.end () - it1e == size1, bad_size ());
0568 difference_type temp_size1 (size1);
0569 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
0570 while (-- temp_size1 >= 0)
0571 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
0572 #else
0573 DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e));
0574 #endif
0575 ++ it2, ++ it2e;
0576 }
0577 }
0578
0579 template<template <class T1, class T2> class F, class M, class E>
0580
0581 void indexing_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
0582 typedef F<typename M::reference, typename E::value_type> functor_type;
0583 typedef typename M::size_type size_type;
0584 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
0585 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
0586 for (size_type i = 0; i < size1; ++ i) {
0587 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
0588 for (size_type j = 0; j < size2; ++ j)
0589 functor_type::apply (m (i, j), e () (i, j));
0590 #else
0591 size_type j (0);
0592 DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j));
0593 #endif
0594 }
0595 }
0596
0597 template<template <class T1, class T2> class F, class M, class E>
0598
0599 void indexing_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
0600 typedef F<typename M::reference, typename E::value_type> functor_type;
0601 typedef typename M::size_type size_type;
0602 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
0603 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
0604 for (size_type j = 0; j < size2; ++ j) {
0605 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
0606 for (size_type i = 0; i < size1; ++ i)
0607 functor_type::apply (m (i, j), e () (i, j));
0608 #else
0609 size_type i (0);
0610 DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i));
0611 #endif
0612 }
0613 }
0614
0615
0616 template<template <class T1, class T2> class F, class R, class M, class E, class C>
0617
0618 void matrix_assign (M &m, const matrix_expression<E> &e, dense_proxy_tag, C) {
0619
0620 typedef C orientation_category;
0621 #ifdef BOOST_UBLAS_USE_INDEXING
0622 indexing_matrix_assign<F> (m, e, orientation_category ());
0623 #elif BOOST_UBLAS_USE_ITERATING
0624 iterating_matrix_assign<F> (m, e, orientation_category ());
0625 #else
0626 typedef typename M::difference_type difference_type;
0627 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
0628 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
0629 if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
0630 size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
0631 iterating_matrix_assign<F> (m, e, orientation_category ());
0632 else
0633 indexing_matrix_assign<F> (m, e, orientation_category ());
0634 #endif
0635 }
0636
0637 template<template <class T1, class T2> class F, class R, class M, class E>
0638
0639 void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
0640 typedef typename matrix_traits<E>::value_type expr_value_type;
0641 typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
0642
0643 typedef typename M::difference_type difference_type;
0644
0645 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
0646 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
0647
0648 #if BOOST_UBLAS_TYPE_CHECK
0649 typedef typename M::value_type value_type;
0650 matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
0651 indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
0652 indexing_matrix_assign<F> (cm, e, row_major_tag ());
0653 #endif
0654 typename M::iterator1 it1 (m.begin1 ());
0655 typename M::iterator1 it1_end (m.end1 ());
0656 typename E::const_iterator1 it1e (e ().begin1 ());
0657 typename E::const_iterator1 it1e_end (e ().end1 ());
0658 difference_type it1_size (it1_end - it1);
0659 difference_type it1e_size (it1e_end - it1e);
0660 difference_type diff1 (0);
0661 if (it1_size > 0 && it1e_size > 0)
0662 diff1 = it1.index1 () - it1e.index1 ();
0663 if (diff1 != 0) {
0664 difference_type size1 = (std::min) (diff1, it1e_size);
0665 if (size1 > 0) {
0666 it1e += size1;
0667 it1e_size -= size1;
0668 diff1 -= size1;
0669 }
0670 size1 = (std::min) (- diff1, it1_size);
0671 if (size1 > 0) {
0672 it1_size -= size1;
0673
0674 #ifdef _MSC_VER
0675 #pragma warning(push)
0676 #pragma warning(disable: 4127)
0677 #endif
0678 if (!functor_type::computed) {
0679 #ifdef _MSC_VER
0680 #pragma warning(pop)
0681 #endif
0682 while (-- size1 >= 0) {
0683 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0684 typename M::iterator2 it2 (it1.begin ());
0685 typename M::iterator2 it2_end (it1.end ());
0686 #else
0687 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
0688 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
0689 #endif
0690 difference_type size2 (it2_end - it2);
0691 while (-- size2 >= 0)
0692 functor_type::apply (*it2, expr_value_type()), ++ it2;
0693 ++ it1;
0694 }
0695 } else {
0696 it1 += size1;
0697 }
0698 diff1 += size1;
0699 }
0700 }
0701 difference_type size1 ((std::min) (it1_size, it1e_size));
0702 it1_size -= size1;
0703 it1e_size -= size1;
0704 while (-- size1 >= 0) {
0705 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0706 typename M::iterator2 it2 (it1.begin ());
0707 typename M::iterator2 it2_end (it1.end ());
0708 typename E::const_iterator2 it2e (it1e.begin ());
0709 typename E::const_iterator2 it2e_end (it1e.end ());
0710 #else
0711 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
0712 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
0713 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
0714 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
0715 #endif
0716 difference_type it2_size (it2_end - it2);
0717 difference_type it2e_size (it2e_end - it2e);
0718 difference_type diff2 (0);
0719 if (it2_size > 0 && it2e_size > 0) {
0720 diff2 = it2.index2 () - it2e.index2 ();
0721 difference_type size2 = (std::min) (diff2, it2e_size);
0722 if (size2 > 0) {
0723 it2e += size2;
0724 it2e_size -= size2;
0725 diff2 -= size2;
0726 }
0727 size2 = (std::min) (- diff2, it2_size);
0728 if (size2 > 0) {
0729 it2_size -= size2;
0730
0731 #ifdef _MSC_VER
0732 #pragma warning(push)
0733 #pragma warning(disable: 4127)
0734 #endif
0735 if (!functor_type::computed) {
0736 #ifdef _MSC_VER
0737 #pragma warning(pop)
0738 #endif
0739 while (-- size2 >= 0)
0740 functor_type::apply (*it2, expr_value_type()), ++ it2;
0741 } else {
0742 it2 += size2;
0743 }
0744 diff2 += size2;
0745 }
0746 }
0747 difference_type size2 ((std::min) (it2_size, it2e_size));
0748 it2_size -= size2;
0749 it2e_size -= size2;
0750 while (-- size2 >= 0)
0751 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
0752 size2 = it2_size;
0753
0754 #ifdef _MSC_VER
0755 #pragma warning(push)
0756 #pragma warning(disable: 4127)
0757 #endif
0758 if (!functor_type::computed) {
0759 #ifdef _MSC_VER
0760 #pragma warning(pop)
0761 #endif
0762 while (-- size2 >= 0)
0763 functor_type::apply (*it2, expr_value_type()), ++ it2;
0764 } else {
0765 it2 += size2;
0766 }
0767 ++ it1, ++ it1e;
0768 }
0769 size1 = it1_size;
0770
0771 #ifdef _MSC_VER
0772 #pragma warning(push)
0773 #pragma warning(disable: 4127)
0774 #endif
0775 if (!functor_type::computed) {
0776 #ifdef _MSC_VER
0777 #pragma warning(pop)
0778 #endif
0779 while (-- size1 >= 0) {
0780 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0781 typename M::iterator2 it2 (it1.begin ());
0782 typename M::iterator2 it2_end (it1.end ());
0783 #else
0784 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
0785 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
0786 #endif
0787 difference_type size2 (it2_end - it2);
0788 while (-- size2 >= 0)
0789 functor_type::apply (*it2, expr_value_type()), ++ it2;
0790 ++ it1;
0791 }
0792 } else {
0793 it1 += size1;
0794 }
0795 #if BOOST_UBLAS_TYPE_CHECK
0796 if (! disable_type_check<bool>::value)
0797 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
0798 #endif
0799 }
0800
0801 template<template <class T1, class T2> class F, class R, class M, class E>
0802
0803 void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
0804 typedef typename matrix_traits<E>::value_type expr_value_type;
0805 typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
0806
0807 typedef typename M::difference_type difference_type;
0808
0809 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
0810 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
0811
0812 #if BOOST_UBLAS_TYPE_CHECK
0813 typedef typename M::value_type value_type;
0814 matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
0815 indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
0816 indexing_matrix_assign<F> (cm, e, column_major_tag ());
0817 #endif
0818 typename M::iterator2 it2 (m.begin2 ());
0819 typename M::iterator2 it2_end (m.end2 ());
0820 typename E::const_iterator2 it2e (e ().begin2 ());
0821 typename E::const_iterator2 it2e_end (e ().end2 ());
0822 difference_type it2_size (it2_end - it2);
0823 difference_type it2e_size (it2e_end - it2e);
0824 difference_type diff2 (0);
0825 if (it2_size > 0 && it2e_size > 0)
0826 diff2 = it2.index2 () - it2e.index2 ();
0827 if (diff2 != 0) {
0828 difference_type size2 = (std::min) (diff2, it2e_size);
0829 if (size2 > 0) {
0830 it2e += size2;
0831 it2e_size -= size2;
0832 diff2 -= size2;
0833 }
0834 size2 = (std::min) (- diff2, it2_size);
0835 if (size2 > 0) {
0836 it2_size -= size2;
0837
0838 #ifdef _MSC_VER
0839 #pragma warning(push)
0840 #pragma warning(disable: 4127)
0841 #endif
0842 if (!functor_type::computed) {
0843 #ifdef _MSC_VER
0844 #pragma warning(pop)
0845 #endif
0846 while (-- size2 >= 0) {
0847 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0848 typename M::iterator1 it1 (it2.begin ());
0849 typename M::iterator1 it1_end (it2.end ());
0850 #else
0851 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
0852 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
0853 #endif
0854 difference_type size1 (it1_end - it1);
0855 while (-- size1 >= 0)
0856 functor_type::apply (*it1, expr_value_type()), ++ it1;
0857 ++ it2;
0858 }
0859 } else {
0860 it2 += size2;
0861 }
0862 diff2 += size2;
0863 }
0864 }
0865 difference_type size2 ((std::min) (it2_size, it2e_size));
0866 it2_size -= size2;
0867 it2e_size -= size2;
0868 while (-- size2 >= 0) {
0869 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0870 typename M::iterator1 it1 (it2.begin ());
0871 typename M::iterator1 it1_end (it2.end ());
0872 typename E::const_iterator1 it1e (it2e.begin ());
0873 typename E::const_iterator1 it1e_end (it2e.end ());
0874 #else
0875 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
0876 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
0877 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
0878 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
0879 #endif
0880 difference_type it1_size (it1_end - it1);
0881 difference_type it1e_size (it1e_end - it1e);
0882 difference_type diff1 (0);
0883 if (it1_size > 0 && it1e_size > 0) {
0884 diff1 = it1.index1 () - it1e.index1 ();
0885 difference_type size1 = (std::min) (diff1, it1e_size);
0886 if (size1 > 0) {
0887 it1e += size1;
0888 it1e_size -= size1;
0889 diff1 -= size1;
0890 }
0891 size1 = (std::min) (- diff1, it1_size);
0892 if (size1 > 0) {
0893 it1_size -= size1;
0894
0895 #ifdef _MSC_VER
0896 #pragma warning(push)
0897 #pragma warning(disable: 4127)
0898 #endif
0899 if (!functor_type::computed) {
0900 #ifdef _MSC_VER
0901 #pragma warning(pop)
0902 #endif
0903 while (-- size1 >= 0)
0904 functor_type::apply (*it1, expr_value_type()), ++ it1;
0905 } else {
0906 it1 += size1;
0907 }
0908 diff1 += size1;
0909 }
0910 }
0911 difference_type size1 ((std::min) (it1_size, it1e_size));
0912 it1_size -= size1;
0913 it1e_size -= size1;
0914 while (-- size1 >= 0)
0915 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
0916 size1 = it1_size;
0917
0918 #ifdef _MSC_VER
0919 #pragma warning(push)
0920 #pragma warning(disable: 4127)
0921 #endif
0922 if (!functor_type::computed) {
0923
0924 #ifdef _MSC_VER
0925 #pragma warning(pop)
0926 #endif
0927 while (-- size1 >= 0)
0928 functor_type::apply (*it1, expr_value_type()), ++ it1;
0929 } else {
0930 it1 += size1;
0931 }
0932 ++ it2, ++ it2e;
0933 }
0934 size2 = it2_size;
0935
0936 #ifdef _MSC_VER
0937 #pragma warning(push)
0938 #pragma warning(disable: 4127)
0939 #endif
0940 if (!functor_type::computed) {
0941 #ifdef _MSC_VER
0942 #pragma warning(pop)
0943 #endif
0944 while (-- size2 >= 0) {
0945 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0946 typename M::iterator1 it1 (it2.begin ());
0947 typename M::iterator1 it1_end (it2.end ());
0948 #else
0949 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
0950 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
0951 #endif
0952 difference_type size1 (it1_end - it1);
0953 while (-- size1 >= 0)
0954 functor_type::apply (*it1, expr_value_type()), ++ it1;
0955 ++ it2;
0956 }
0957 } else {
0958 it2 += size2;
0959 }
0960 #if BOOST_UBLAS_TYPE_CHECK
0961 if (! disable_type_check<bool>::value)
0962 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
0963 #endif
0964 }
0965
0966 template<template <class T1, class T2> class F, class R, class M, class E>
0967
0968 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, row_major_tag) {
0969 typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
0970
0971
0972
0973 #ifdef _MSC_VER
0974 #pragma warning(push)
0975 #pragma warning(disable: 4127)
0976 #endif
0977 BOOST_STATIC_ASSERT ((!functor_type::computed));
0978 #ifdef _MSC_VER
0979 #pragma warning(pop)
0980 #endif
0981 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
0982 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
0983 typedef typename M::value_type value_type;
0984
0985
0986 m.clear ();
0987 typename E::const_iterator1 it1e (e ().begin1 ());
0988 typename E::const_iterator1 it1e_end (e ().end1 ());
0989 while (it1e != it1e_end) {
0990 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0991 typename E::const_iterator2 it2e (it1e.begin ());
0992 typename E::const_iterator2 it2e_end (it1e.end ());
0993 #else
0994 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
0995 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
0996 #endif
0997 while (it2e != it2e_end) {
0998 value_type t (*it2e);
0999 if (t != value_type())
1000 m.insert_element (it2e.index1 (), it2e.index2 (), t);
1001 ++ it2e;
1002 }
1003 ++ it1e;
1004 }
1005 }
1006
1007 template<template <class T1, class T2> class F, class R, class M, class E>
1008
1009 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, column_major_tag) {
1010 typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
1011
1012
1013
1014 #ifdef _MSC_VER
1015 #pragma warning(push)
1016 #pragma warning(disable: 4127)
1017 #endif
1018 BOOST_STATIC_ASSERT ((!functor_type::computed));
1019 #ifdef _MSC_VER
1020 #pragma warning(pop)
1021 #endif
1022 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1023 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1024 typedef typename M::value_type value_type;
1025
1026
1027 m.clear ();
1028 typename E::const_iterator2 it2e (e ().begin2 ());
1029 typename E::const_iterator2 it2e_end (e ().end2 ());
1030 while (it2e != it2e_end) {
1031 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1032 typename E::const_iterator1 it1e (it2e.begin ());
1033 typename E::const_iterator1 it1e_end (it2e.end ());
1034 #else
1035 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
1036 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
1037 #endif
1038 while (it1e != it1e_end) {
1039 value_type t (*it1e);
1040 if (t != value_type())
1041 m.insert_element (it1e.index1 (), it1e.index2 (), t);
1042 ++ it1e;
1043 }
1044 ++ it2e;
1045 }
1046 }
1047
1048 template<template <class T1, class T2> class F, class R, class M, class E>
1049
1050 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
1051 typedef typename matrix_traits<E>::value_type expr_value_type;
1052 typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
1053 typedef R conformant_restrict_type;
1054 typedef typename M::size_type size_type;
1055 typedef typename M::difference_type difference_type;
1056
1057 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1058 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1059
1060 #if BOOST_UBLAS_TYPE_CHECK
1061 typedef typename M::value_type value_type;
1062 matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
1063 indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
1064 indexing_matrix_assign<F> (cm, e, row_major_tag ());
1065 #endif
1066 detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
1067
1068 typename M::iterator1 it1 (m.begin1 ());
1069 typename M::iterator1 it1_end (m.end1 ());
1070 typename E::const_iterator1 it1e (e ().begin1 ());
1071 typename E::const_iterator1 it1e_end (e ().end1 ());
1072 while (it1 != it1_end && it1e != it1e_end) {
1073 difference_type compare = it1.index1 () - it1e.index1 ();
1074 if (compare == 0) {
1075 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1076 typename M::iterator2 it2 (it1.begin ());
1077 typename M::iterator2 it2_end (it1.end ());
1078 typename E::const_iterator2 it2e (it1e.begin ());
1079 typename E::const_iterator2 it2e_end (it1e.end ());
1080 #else
1081 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1082 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1083 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
1084 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
1085 #endif
1086 if (it2 != it2_end && it2e != it2e_end) {
1087 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
1088 for (;;) {
1089 difference_type compare2 = it2_index - it2e_index;
1090 if (compare2 == 0) {
1091 functor_type::apply (*it2, *it2e);
1092 ++ it2, ++ it2e;
1093 if (it2 != it2_end && it2e != it2e_end) {
1094 it2_index = it2.index2 ();
1095 it2e_index = it2e.index2 ();
1096 } else
1097 break;
1098 } else if (compare2 < 0) {
1099
1100 #ifdef _MSC_VER
1101 #pragma warning(push)
1102 #pragma warning(disable: 4127)
1103 #endif
1104 if (!functor_type::computed) {
1105 #ifdef _MSC_VER
1106 #pragma warning(pop)
1107 #endif
1108 functor_type::apply (*it2, expr_value_type());
1109 ++ it2;
1110 } else
1111 increment (it2, it2_end, - compare2);
1112 if (it2 != it2_end)
1113 it2_index = it2.index2 ();
1114 else
1115 break;
1116 } else if (compare2 > 0) {
1117 increment (it2e, it2e_end, compare2);
1118 if (it2e != it2e_end)
1119 it2e_index = it2e.index2 ();
1120 else
1121 break;
1122 }
1123 }
1124 }
1125
1126 #ifdef _MSC_VER
1127 #pragma warning(push)
1128 #pragma warning(disable: 4127)
1129 #endif
1130 if (!functor_type::computed) {
1131 #ifdef _MSC_VER
1132 #pragma warning(pop)
1133 #endif
1134 while (it2 != it2_end) {
1135 functor_type::apply (*it2, expr_value_type());
1136 ++ it2;
1137 }
1138 } else {
1139 it2 = it2_end;
1140 }
1141 ++ it1, ++ it1e;
1142 } else if (compare < 0) {
1143
1144 #ifdef _MSC_VER
1145 #pragma warning(push)
1146 #pragma warning(disable: 4127)
1147 #endif
1148 if (!functor_type::computed) {
1149 #ifdef _MSC_VER
1150 #pragma warning(pop)
1151 #endif
1152 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1153 typename M::iterator2 it2 (it1.begin ());
1154 typename M::iterator2 it2_end (it1.end ());
1155 #else
1156 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1157 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1158 #endif
1159 while (it2 != it2_end) {
1160 functor_type::apply (*it2, expr_value_type());
1161 ++ it2;
1162 }
1163 ++ it1;
1164 } else {
1165 increment (it1, it1_end, - compare);
1166 }
1167 } else if (compare > 0) {
1168 increment (it1e, it1e_end, compare);
1169 }
1170 }
1171
1172 #ifdef _MSC_VER
1173 #pragma warning(push)
1174 #pragma warning(disable: 4127)
1175 #endif
1176 if (!functor_type::computed) {
1177 #ifdef _MSC_VER
1178 #pragma warning(pop)
1179 #endif
1180 while (it1 != it1_end) {
1181 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1182 typename M::iterator2 it2 (it1.begin ());
1183 typename M::iterator2 it2_end (it1.end ());
1184 #else
1185 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1186 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1187 #endif
1188 while (it2 != it2_end) {
1189 functor_type::apply (*it2, expr_value_type());
1190 ++ it2;
1191 }
1192 ++ it1;
1193 }
1194 } else {
1195 it1 = it1_end;
1196 }
1197 #if BOOST_UBLAS_TYPE_CHECK
1198 if (! disable_type_check<bool>::value)
1199 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
1200 #endif
1201 }
1202
1203 template<template <class T1, class T2> class F, class R, class M, class E>
1204
1205 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
1206 typedef typename matrix_traits<E>::value_type expr_value_type;
1207 typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
1208 typedef R conformant_restrict_type;
1209 typedef typename M::size_type size_type;
1210 typedef typename M::difference_type difference_type;
1211
1212 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1213 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1214
1215 #if BOOST_UBLAS_TYPE_CHECK
1216 typedef typename M::value_type value_type;
1217 matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
1218 indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
1219 indexing_matrix_assign<F> (cm, e, column_major_tag ());
1220 #endif
1221 detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
1222
1223 typename M::iterator2 it2 (m.begin2 ());
1224 typename M::iterator2 it2_end (m.end2 ());
1225 typename E::const_iterator2 it2e (e ().begin2 ());
1226 typename E::const_iterator2 it2e_end (e ().end2 ());
1227 while (it2 != it2_end && it2e != it2e_end) {
1228 difference_type compare = it2.index2 () - it2e.index2 ();
1229 if (compare == 0) {
1230 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1231 typename M::iterator1 it1 (it2.begin ());
1232 typename M::iterator1 it1_end (it2.end ());
1233 typename E::const_iterator1 it1e (it2e.begin ());
1234 typename E::const_iterator1 it1e_end (it2e.end ());
1235 #else
1236 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1237 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1238 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
1239 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
1240 #endif
1241 if (it1 != it1_end && it1e != it1e_end) {
1242 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
1243 for (;;) {
1244 difference_type compare2 = it1_index - it1e_index;
1245 if (compare2 == 0) {
1246 functor_type::apply (*it1, *it1e);
1247 ++ it1, ++ it1e;
1248 if (it1 != it1_end && it1e != it1e_end) {
1249 it1_index = it1.index1 ();
1250 it1e_index = it1e.index1 ();
1251 } else
1252 break;
1253 } else if (compare2 < 0) {
1254
1255 #ifdef _MSC_VER
1256 #pragma warning(push)
1257 #pragma warning(disable: 4127)
1258 #endif
1259 if (!functor_type::computed) {
1260 #ifdef _MSC_VER
1261 #pragma warning(pop)
1262 #endif
1263 functor_type::apply (*it1, expr_value_type());
1264 ++ it1;
1265 } else
1266 increment (it1, it1_end, - compare2);
1267 if (it1 != it1_end)
1268 it1_index = it1.index1 ();
1269 else
1270 break;
1271 } else if (compare2 > 0) {
1272 increment (it1e, it1e_end, compare2);
1273 if (it1e != it1e_end)
1274 it1e_index = it1e.index1 ();
1275 else
1276 break;
1277 }
1278 }
1279 }
1280
1281 #ifdef _MSC_VER
1282 #pragma warning(push)
1283 #pragma warning(disable: 4127)
1284 #endif
1285 if (!functor_type::computed) {
1286 #ifdef _MSC_VER
1287 #pragma warning(pop)
1288 #endif
1289 while (it1 != it1_end) {
1290 functor_type::apply (*it1, expr_value_type());
1291 ++ it1;
1292 }
1293 } else {
1294 it1 = it1_end;
1295 }
1296 ++ it2, ++ it2e;
1297 } else if (compare < 0) {
1298
1299 #ifdef _MSC_VER
1300 #pragma warning(push)
1301 #pragma warning(disable: 4127)
1302 #endif
1303 if (!functor_type::computed) {
1304 #ifdef _MSC_VER
1305 #pragma warning(pop)
1306 #endif
1307 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1308 typename M::iterator1 it1 (it2.begin ());
1309 typename M::iterator1 it1_end (it2.end ());
1310 #else
1311 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1312 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1313 #endif
1314 while (it1 != it1_end) {
1315 functor_type::apply (*it1, expr_value_type());
1316 ++ it1;
1317 }
1318 ++ it2;
1319 } else {
1320 increment (it2, it2_end, - compare);
1321 }
1322 } else if (compare > 0) {
1323 increment (it2e, it2e_end, compare);
1324 }
1325 }
1326
1327 #ifdef _MSC_VER
1328 #pragma warning(push)
1329 #pragma warning(disable: 4127)
1330 #endif
1331 if (!functor_type::computed) {
1332 #ifdef _MSC_VER
1333 #pragma warning(pop)
1334 #endif
1335 while (it2 != it2_end) {
1336 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1337 typename M::iterator1 it1 (it2.begin ());
1338 typename M::iterator1 it1_end (it2.end ());
1339 #else
1340 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1341 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1342 #endif
1343 while (it1 != it1_end) {
1344 functor_type::apply (*it1, expr_value_type());
1345 ++ it1;
1346 }
1347 ++ it2;
1348 }
1349 } else {
1350 it2 = it2_end;
1351 }
1352 #if BOOST_UBLAS_TYPE_CHECK
1353 if (! disable_type_check<bool>::value)
1354 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
1355 #endif
1356 }
1357
1358
1359 template<template <class T1, class T2> class F, class M, class E>
1360 BOOST_UBLAS_INLINE
1361 void matrix_assign (M &m, const matrix_expression<E> &e) {
1362 typedef typename matrix_assign_traits<typename M::storage_category,
1363 F<typename M::reference, typename E::value_type>::computed,
1364 typename E::const_iterator1::iterator_category,
1365 typename E::const_iterator2::iterator_category>::storage_category storage_category;
1366
1367 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1368 typename E::orientation_category ,
1369 typename M::orientation_category >::type orientation_category;
1370 typedef basic_full<typename M::size_type> unrestricted;
1371 matrix_assign<F, unrestricted> (m, e, storage_category (), orientation_category ());
1372 }
1373 template<template <class T1, class T2> class F, class R, class M, class E>
1374 BOOST_UBLAS_INLINE
1375 void matrix_assign (M &m, const matrix_expression<E> &e) {
1376 typedef R conformant_restrict_type;
1377 typedef typename matrix_assign_traits<typename M::storage_category,
1378 F<typename M::reference, typename E::value_type>::computed,
1379 typename E::const_iterator1::iterator_category,
1380 typename E::const_iterator2::iterator_category>::storage_category storage_category;
1381
1382 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1383 typename E::orientation_category ,
1384 typename M::orientation_category >::type orientation_category;
1385 matrix_assign<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
1386 }
1387
1388 template<class SC, class RI1, class RI2>
1389 struct matrix_swap_traits {
1390 typedef SC storage_category;
1391 };
1392
1393 template<>
1394 struct matrix_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
1395 typedef sparse_proxy_tag storage_category;
1396 };
1397
1398 template<>
1399 struct matrix_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
1400 typedef sparse_proxy_tag storage_category;
1401 };
1402
1403
1404 template<template <class T1, class T2> class F, class R, class M, class E>
1405
1406 void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, row_major_tag) {
1407 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1408
1409
1410 typedef typename M::difference_type difference_type;
1411 typename M::iterator1 it1 (m.begin1 ());
1412 typename E::iterator1 it1e (e ().begin1 ());
1413 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (e ().end1 () - it1e)));
1414 while (-- size1 >= 0) {
1415 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1416 typename M::iterator2 it2 (it1.begin ());
1417 typename E::iterator2 it2e (it1e.begin ());
1418 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (it1e.end () - it2e)));
1419 #else
1420 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1421 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1422 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (end (it1e, iterator1_tag ()) - it2e)));
1423 #endif
1424 while (-- size2 >= 0)
1425 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
1426 ++ it1, ++ it1e;
1427 }
1428 }
1429
1430 template<template <class T1, class T2> class F, class R, class M, class E>
1431
1432 void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, column_major_tag) {
1433 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1434
1435
1436 typedef typename M::difference_type difference_type;
1437 typename M::iterator2 it2 (m.begin2 ());
1438 typename E::iterator2 it2e (e ().begin2 ());
1439 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (e ().end2 () - it2e)));
1440 while (-- size2 >= 0) {
1441 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1442 typename M::iterator1 it1 (it2.begin ());
1443 typename E::iterator1 it1e (it2e.begin ());
1444 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (it2e.end () - it1e)));
1445 #else
1446 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1447 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1448 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (end (it2e, iterator2_tag ()) - it1e)));
1449 #endif
1450 while (-- size1 >= 0)
1451 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
1452 ++ it2, ++ it2e;
1453 }
1454 }
1455
1456 template<template <class T1, class T2> class F, class R, class M, class E>
1457
1458 void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
1459 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1460
1461 typedef typename M::difference_type difference_type;
1462 typename M::iterator1 it1 (m.begin1 ());
1463 typename E::iterator1 it1e (e ().begin1 ());
1464 difference_type size1 (BOOST_UBLAS_SAME (m.end1 () - it1, e ().end1 () - it1e));
1465 while (-- size1 >= 0) {
1466 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1467 typename M::iterator2 it2 (it1.begin ());
1468 typename E::iterator2 it2e (it1e.begin ());
1469 difference_type size2 (BOOST_UBLAS_SAME (it1.end () - it2, it1e.end () - it2e));
1470 #else
1471 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1472 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1473 difference_type size2 (BOOST_UBLAS_SAME (end (it1, iterator1_tag ()) - it2, end (it1e, iterator1_tag ()) - it2e));
1474 #endif
1475 while (-- size2 >= 0)
1476 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
1477 ++ it1, ++ it1e;
1478 }
1479 }
1480
1481 template<template <class T1, class T2> class F, class R, class M, class E>
1482
1483 void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
1484 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1485
1486 typedef typename M::difference_type difference_type;
1487 typename M::iterator2 it2 (m.begin2 ());
1488 typename E::iterator2 it2e (e ().begin2 ());
1489 difference_type size2 (BOOST_UBLAS_SAME (m.end2 () - it2, e ().end2 () - it2e));
1490 while (-- size2 >= 0) {
1491 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1492 typename M::iterator1 it1 (it2.begin ());
1493 typename E::iterator1 it1e (it2e.begin ());
1494 difference_type size1 (BOOST_UBLAS_SAME (it2.end () - it1, it2e.end () - it1e));
1495 #else
1496 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1497 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1498 difference_type size1 (BOOST_UBLAS_SAME (end (it2, iterator2_tag ()) - it1, end (it2e, iterator2_tag ()) - it1e));
1499 #endif
1500 while (-- size1 >= 0)
1501 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
1502 ++ it2, ++ it2e;
1503 }
1504 }
1505
1506 template<template <class T1, class T2> class F, class R, class M, class E>
1507
1508 void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
1509 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1510 typedef R conformant_restrict_type;
1511 typedef typename M::size_type size_type;
1512 typedef typename M::difference_type difference_type;
1513 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1514 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1515
1516 detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
1517
1518 detail::make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
1519
1520 typename M::iterator1 it1 (m.begin1 ());
1521 typename M::iterator1 it1_end (m.end1 ());
1522 typename E::iterator1 it1e (e ().begin1 ());
1523 typename E::iterator1 it1e_end (e ().end1 ());
1524 while (it1 != it1_end && it1e != it1e_end) {
1525 difference_type compare = it1.index1 () - it1e.index1 ();
1526 if (compare == 0) {
1527 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1528 typename M::iterator2 it2 (it1.begin ());
1529 typename M::iterator2 it2_end (it1.end ());
1530 typename E::iterator2 it2e (it1e.begin ());
1531 typename E::iterator2 it2e_end (it1e.end ());
1532 #else
1533 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1534 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1535 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1536 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1537 #endif
1538 if (it2 != it2_end && it2e != it2e_end) {
1539 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
1540 for (;;) {
1541 difference_type compare2 = it2_index - it2e_index;
1542 if (compare2 == 0) {
1543 functor_type::apply (*it2, *it2e);
1544 ++ it2, ++ it2e;
1545 if (it2 != it2_end && it2e != it2e_end) {
1546 it2_index = it2.index2 ();
1547 it2e_index = it2e.index2 ();
1548 } else
1549 break;
1550 } else if (compare2 < 0) {
1551 increment (it2, it2_end, - compare2);
1552 if (it2 != it2_end)
1553 it2_index = it2.index2 ();
1554 else
1555 break;
1556 } else if (compare2 > 0) {
1557 increment (it2e, it2e_end, compare2);
1558 if (it2e != it2e_end)
1559 it2e_index = it2e.index2 ();
1560 else
1561 break;
1562 }
1563 }
1564 }
1565 #if BOOST_UBLAS_TYPE_CHECK
1566 increment (it2e, it2e_end);
1567 increment (it2, it2_end);
1568 #endif
1569 ++ it1, ++ it1e;
1570 } else if (compare < 0) {
1571 #if BOOST_UBLAS_TYPE_CHECK
1572 while (it1.index1 () < it1e.index1 ()) {
1573 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1574 typename M::iterator2 it2 (it1.begin ());
1575 typename M::iterator2 it2_end (it1.end ());
1576 #else
1577 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1578 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1579 #endif
1580 increment (it2, it2_end);
1581 ++ it1;
1582 }
1583 #else
1584 increment (it1, it1_end, - compare);
1585 #endif
1586 } else if (compare > 0) {
1587 #if BOOST_UBLAS_TYPE_CHECK
1588 while (it1e.index1 () < it1.index1 ()) {
1589 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1590 typename E::iterator2 it2e (it1e.begin ());
1591 typename E::iterator2 it2e_end (it1e.end ());
1592 #else
1593 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1594 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1595 #endif
1596 increment (it2e, it2e_end);
1597 ++ it1e;
1598 }
1599 #else
1600 increment (it1e, it1e_end, compare);
1601 #endif
1602 }
1603 }
1604 #if BOOST_UBLAS_TYPE_CHECK
1605 while (it1e != it1e_end) {
1606 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1607 typename E::iterator2 it2e (it1e.begin ());
1608 typename E::iterator2 it2e_end (it1e.end ());
1609 #else
1610 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1611 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1612 #endif
1613 increment (it2e, it2e_end);
1614 ++ it1e;
1615 }
1616 while (it1 != it1_end) {
1617 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1618 typename M::iterator2 it2 (it1.begin ());
1619 typename M::iterator2 it2_end (it1.end ());
1620 #else
1621 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1622 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1623 #endif
1624 increment (it2, it2_end);
1625 ++ it1;
1626 }
1627 #endif
1628 }
1629
1630 template<template <class T1, class T2> class F, class R, class M, class E>
1631
1632 void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
1633 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1634 typedef R conformant_restrict_type;
1635 typedef typename M::size_type size_type;
1636 typedef typename M::difference_type difference_type;
1637
1638 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1639 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1640
1641 detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
1642
1643 detail::make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
1644
1645 typename M::iterator2 it2 (m.begin2 ());
1646 typename M::iterator2 it2_end (m.end2 ());
1647 typename E::iterator2 it2e (e ().begin2 ());
1648 typename E::iterator2 it2e_end (e ().end2 ());
1649 while (it2 != it2_end && it2e != it2e_end) {
1650 difference_type compare = it2.index2 () - it2e.index2 ();
1651 if (compare == 0) {
1652 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1653 typename M::iterator1 it1 (it2.begin ());
1654 typename M::iterator1 it1_end (it2.end ());
1655 typename E::iterator1 it1e (it2e.begin ());
1656 typename E::iterator1 it1e_end (it2e.end ());
1657 #else
1658 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1659 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1660 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1661 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1662 #endif
1663 if (it1 != it1_end && it1e != it1e_end) {
1664 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
1665 for (;;) {
1666 difference_type compare2 = it1_index - it1e_index;
1667 if (compare2 == 0) {
1668 functor_type::apply (*it1, *it1e);
1669 ++ it1, ++ it1e;
1670 if (it1 != it1_end && it1e != it1e_end) {
1671 it1_index = it1.index1 ();
1672 it1e_index = it1e.index1 ();
1673 } else
1674 break;
1675 } else if (compare2 < 0) {
1676 increment (it1, it1_end, - compare2);
1677 if (it1 != it1_end)
1678 it1_index = it1.index1 ();
1679 else
1680 break;
1681 } else if (compare2 > 0) {
1682 increment (it1e, it1e_end, compare2);
1683 if (it1e != it1e_end)
1684 it1e_index = it1e.index1 ();
1685 else
1686 break;
1687 }
1688 }
1689 }
1690 #if BOOST_UBLAS_TYPE_CHECK
1691 increment (it1e, it1e_end);
1692 increment (it1, it1_end);
1693 #endif
1694 ++ it2, ++ it2e;
1695 } else if (compare < 0) {
1696 #if BOOST_UBLAS_TYPE_CHECK
1697 while (it2.index2 () < it2e.index2 ()) {
1698 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1699 typename M::iterator1 it1 (it2.begin ());
1700 typename M::iterator1 it1_end (it2.end ());
1701 #else
1702 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1703 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1704 #endif
1705 increment (it1, it1_end);
1706 ++ it2;
1707 }
1708 #else
1709 increment (it2, it2_end, - compare);
1710 #endif
1711 } else if (compare > 0) {
1712 #if BOOST_UBLAS_TYPE_CHECK
1713 while (it2e.index2 () < it2.index2 ()) {
1714 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1715 typename E::iterator1 it1e (it2e.begin ());
1716 typename E::iterator1 it1e_end (it2e.end ());
1717 #else
1718 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1719 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1720 #endif
1721 increment (it1e, it1e_end);
1722 ++ it2e;
1723 }
1724 #else
1725 increment (it2e, it2e_end, compare);
1726 #endif
1727 }
1728 }
1729 #if BOOST_UBLAS_TYPE_CHECK
1730 while (it2e != it2e_end) {
1731 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1732 typename E::iterator1 it1e (it2e.begin ());
1733 typename E::iterator1 it1e_end (it2e.end ());
1734 #else
1735 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1736 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1737 #endif
1738 increment (it1e, it1e_end);
1739 ++ it2e;
1740 }
1741 while (it2 != it2_end) {
1742 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1743 typename M::iterator1 it1 (it2.begin ());
1744 typename M::iterator1 it1_end (it2.end ());
1745 #else
1746 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1747 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1748 #endif
1749 increment (it1, it1_end);
1750 ++ it2;
1751 }
1752 #endif
1753 }
1754
1755
1756 template<template <class T1, class T2> class F, class M, class E>
1757 BOOST_UBLAS_INLINE
1758 void matrix_swap (M &m, matrix_expression<E> &e) {
1759 typedef typename matrix_swap_traits<typename M::storage_category,
1760 typename E::const_iterator1::iterator_category,
1761 typename E::const_iterator2::iterator_category>::storage_category storage_category;
1762
1763 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1764 typename E::orientation_category ,
1765 typename M::orientation_category >::type orientation_category;
1766 typedef basic_full<typename M::size_type> unrestricted;
1767 matrix_swap<F, unrestricted> (m, e, storage_category (), orientation_category ());
1768 }
1769 template<template <class T1, class T2> class F, class R, class M, class E>
1770 BOOST_UBLAS_INLINE
1771 void matrix_swap (M &m, matrix_expression<E> &e) {
1772 typedef R conformant_restrict_type;
1773 typedef typename matrix_swap_traits<typename M::storage_category,
1774 typename E::const_iterator1::iterator_category,
1775 typename E::const_iterator2::iterator_category>::storage_category storage_category;
1776
1777 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1778 typename E::orientation_category ,
1779 typename M::orientation_category >::type orientation_category;
1780 matrix_swap<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
1781 }
1782
1783 }}}
1784
1785 #endif