annotate DEPENDENCIES/generic/include/boost/numeric/ublas/detail/matrix_assign.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_ASSIGN_
Chris@16 14 #define _BOOST_UBLAS_MATRIX_ASSIGN_
Chris@16 15
Chris@16 16 #include <boost/numeric/ublas/traits.hpp>
Chris@16 17 // Required for make_conformant storage
Chris@16 18 #include <vector>
Chris@16 19
Chris@16 20 // Iterators based on ideas of Jeremy Siek
Chris@16 21
Chris@16 22 namespace boost { namespace numeric { namespace ublas {
Chris@16 23 namespace detail {
Chris@16 24
Chris@16 25 // Weak equality check - useful to compare equality two arbitary matrix expression results.
Chris@16 26 // Since the actual expressions are unknown, we check for and arbitary error bound
Chris@16 27 // on the relative error.
Chris@16 28 // For a linear expression the infinity norm makes sense as we do not know how the elements will be
Chris@16 29 // combined in the expression. False positive results are inevitable for arbirary expressions!
Chris@16 30 template<class E1, class E2, class S>
Chris@16 31 BOOST_UBLAS_INLINE
Chris@16 32 bool equals (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2, S epsilon, S min_norm) {
Chris@16 33 return norm_inf (e1 - e2) < epsilon *
Chris@16 34 std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
Chris@16 35 }
Chris@16 36
Chris@16 37 template<class E1, class E2>
Chris@16 38 BOOST_UBLAS_INLINE
Chris@16 39 bool expression_type_check (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
Chris@16 40 typedef typename type_traits<typename promote_traits<typename E1::value_type,
Chris@16 41 typename E2::value_type>::promote_type>::real_type real_type;
Chris@16 42 return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
Chris@16 43 }
Chris@16 44
Chris@16 45
Chris@16 46 template<class M, class E, class R>
Chris@16 47 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 48 void make_conformant (M &m, const matrix_expression<E> &e, row_major_tag, R) {
Chris@16 49 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 50 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@16 51 typedef R conformant_restrict_type;
Chris@16 52 typedef typename M::size_type size_type;
Chris@16 53 typedef typename M::difference_type difference_type;
Chris@16 54 typedef typename M::value_type value_type;
Chris@16 55 // FIXME unbounded_array with push_back maybe better
Chris@16 56 std::vector<std::pair<size_type, size_type> > index;
Chris@16 57 typename M::iterator1 it1 (m.begin1 ());
Chris@16 58 typename M::iterator1 it1_end (m.end1 ());
Chris@16 59 typename E::const_iterator1 it1e (e ().begin1 ());
Chris@16 60 typename E::const_iterator1 it1e_end (e ().end1 ());
Chris@16 61 while (it1 != it1_end && it1e != it1e_end) {
Chris@16 62 difference_type compare = it1.index1 () - it1e.index1 ();
Chris@16 63 if (compare == 0) {
Chris@16 64 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 65 typename M::iterator2 it2 (it1.begin ());
Chris@16 66 typename M::iterator2 it2_end (it1.end ());
Chris@16 67 typename E::const_iterator2 it2e (it1e.begin ());
Chris@16 68 typename E::const_iterator2 it2e_end (it1e.end ());
Chris@16 69 #else
Chris@16 70 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 71 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 72 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 73 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 74 #endif
Chris@16 75 if (it2 != it2_end && it2e != it2e_end) {
Chris@16 76 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
Chris@16 77 while (true) {
Chris@101 78 difference_type compare2 = it2_index - it2e_index;
Chris@101 79 if (compare2 == 0) {
Chris@16 80 ++ it2, ++ it2e;
Chris@16 81 if (it2 != it2_end && it2e != it2e_end) {
Chris@16 82 it2_index = it2.index2 ();
Chris@16 83 it2e_index = it2e.index2 ();
Chris@16 84 } else
Chris@16 85 break;
Chris@101 86 } else if (compare2 < 0) {
Chris@101 87 increment (it2, it2_end, - compare2);
Chris@16 88 if (it2 != it2_end)
Chris@16 89 it2_index = it2.index2 ();
Chris@16 90 else
Chris@16 91 break;
Chris@101 92 } else if (compare2 > 0) {
Chris@16 93 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
Chris@16 94 if (static_cast<value_type>(*it2e) != value_type/*zero*/())
Chris@16 95 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
Chris@16 96 ++ it2e;
Chris@16 97 if (it2e != it2e_end)
Chris@16 98 it2e_index = it2e.index2 ();
Chris@16 99 else
Chris@16 100 break;
Chris@16 101 }
Chris@16 102 }
Chris@16 103 }
Chris@16 104 while (it2e != it2e_end) {
Chris@16 105 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
Chris@16 106 if (static_cast<value_type>(*it2e) != value_type/*zero*/())
Chris@16 107 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
Chris@16 108 ++ it2e;
Chris@16 109 }
Chris@16 110 ++ it1, ++ it1e;
Chris@16 111 } else if (compare < 0) {
Chris@16 112 increment (it1, it1_end, - compare);
Chris@16 113 } else if (compare > 0) {
Chris@16 114 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 115 typename E::const_iterator2 it2e (it1e.begin ());
Chris@16 116 typename E::const_iterator2 it2e_end (it1e.end ());
Chris@16 117 #else
Chris@16 118 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 119 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 120 #endif
Chris@16 121 while (it2e != it2e_end) {
Chris@16 122 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
Chris@16 123 if (static_cast<value_type>(*it2e) != value_type/*zero*/())
Chris@16 124 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
Chris@16 125 ++ it2e;
Chris@16 126 }
Chris@16 127 ++ it1e;
Chris@16 128 }
Chris@16 129 }
Chris@16 130 while (it1e != it1e_end) {
Chris@16 131 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 132 typename E::const_iterator2 it2e (it1e.begin ());
Chris@16 133 typename E::const_iterator2 it2e_end (it1e.end ());
Chris@16 134 #else
Chris@16 135 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 136 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 137 #endif
Chris@16 138 while (it2e != it2e_end) {
Chris@16 139 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
Chris@16 140 if (static_cast<value_type>(*it2e) != value_type/*zero*/())
Chris@16 141 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
Chris@16 142 ++ it2e;
Chris@16 143 }
Chris@16 144 ++ it1e;
Chris@16 145 }
Chris@16 146 // ISSUE proxies require insert_element
Chris@16 147 for (size_type k = 0; k < index.size (); ++ k)
Chris@16 148 m (index [k].first, index [k].second) = value_type/*zero*/();
Chris@16 149 }
Chris@16 150 template<class M, class E, class R>
Chris@16 151 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 152 void make_conformant (M &m, const matrix_expression<E> &e, column_major_tag, R) {
Chris@16 153 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 154 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@16 155 typedef R conformant_restrict_type;
Chris@16 156 typedef typename M::size_type size_type;
Chris@16 157 typedef typename M::difference_type difference_type;
Chris@16 158 typedef typename M::value_type value_type;
Chris@16 159 std::vector<std::pair<size_type, size_type> > index;
Chris@16 160 typename M::iterator2 it2 (m.begin2 ());
Chris@16 161 typename M::iterator2 it2_end (m.end2 ());
Chris@16 162 typename E::const_iterator2 it2e (e ().begin2 ());
Chris@16 163 typename E::const_iterator2 it2e_end (e ().end2 ());
Chris@16 164 while (it2 != it2_end && it2e != it2e_end) {
Chris@16 165 difference_type compare = it2.index2 () - it2e.index2 ();
Chris@16 166 if (compare == 0) {
Chris@16 167 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 168 typename M::iterator1 it1 (it2.begin ());
Chris@16 169 typename M::iterator1 it1_end (it2.end ());
Chris@16 170 typename E::const_iterator1 it1e (it2e.begin ());
Chris@16 171 typename E::const_iterator1 it1e_end (it2e.end ());
Chris@16 172 #else
Chris@16 173 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 174 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 175 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 176 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 177 #endif
Chris@16 178 if (it1 != it1_end && it1e != it1e_end) {
Chris@16 179 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
Chris@16 180 while (true) {
Chris@101 181 difference_type compare2 = it1_index - it1e_index;
Chris@101 182 if (compare2 == 0) {
Chris@16 183 ++ it1, ++ it1e;
Chris@16 184 if (it1 != it1_end && it1e != it1e_end) {
Chris@16 185 it1_index = it1.index1 ();
Chris@16 186 it1e_index = it1e.index1 ();
Chris@16 187 } else
Chris@16 188 break;
Chris@101 189 } else if (compare2 < 0) {
Chris@101 190 increment (it1, it1_end, - compare2);
Chris@16 191 if (it1 != it1_end)
Chris@16 192 it1_index = it1.index1 ();
Chris@16 193 else
Chris@16 194 break;
Chris@101 195 } else if (compare2 > 0) {
Chris@16 196 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
Chris@16 197 if (static_cast<value_type>(*it1e) != value_type/*zero*/())
Chris@16 198 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
Chris@16 199 ++ it1e;
Chris@16 200 if (it1e != it1e_end)
Chris@16 201 it1e_index = it1e.index1 ();
Chris@16 202 else
Chris@16 203 break;
Chris@16 204 }
Chris@16 205 }
Chris@16 206 }
Chris@16 207 while (it1e != it1e_end) {
Chris@16 208 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
Chris@16 209 if (static_cast<value_type>(*it1e) != value_type/*zero*/())
Chris@16 210 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
Chris@16 211 ++ it1e;
Chris@16 212 }
Chris@16 213 ++ it2, ++ it2e;
Chris@16 214 } else if (compare < 0) {
Chris@16 215 increment (it2, it2_end, - compare);
Chris@16 216 } else if (compare > 0) {
Chris@16 217 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 218 typename E::const_iterator1 it1e (it2e.begin ());
Chris@16 219 typename E::const_iterator1 it1e_end (it2e.end ());
Chris@16 220 #else
Chris@16 221 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 222 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 223 #endif
Chris@16 224 while (it1e != it1e_end) {
Chris@16 225 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
Chris@16 226 if (static_cast<value_type>(*it1e) != value_type/*zero*/())
Chris@16 227 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
Chris@16 228 ++ it1e;
Chris@16 229 }
Chris@16 230 ++ it2e;
Chris@16 231 }
Chris@16 232 }
Chris@16 233 while (it2e != it2e_end) {
Chris@16 234 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 235 typename E::const_iterator1 it1e (it2e.begin ());
Chris@16 236 typename E::const_iterator1 it1e_end (it2e.end ());
Chris@16 237 #else
Chris@16 238 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 239 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 240 #endif
Chris@16 241 while (it1e != it1e_end) {
Chris@16 242 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
Chris@16 243 if (static_cast<value_type>(*it1e) != value_type/*zero*/())
Chris@16 244 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
Chris@16 245 ++ it1e;
Chris@16 246 }
Chris@16 247 ++ it2e;
Chris@16 248 }
Chris@16 249 // ISSUE proxies require insert_element
Chris@16 250 for (size_type k = 0; k < index.size (); ++ k)
Chris@16 251 m (index [k].first, index [k].second) = value_type/*zero*/();
Chris@16 252 }
Chris@16 253
Chris@16 254 }//namespace detail
Chris@16 255
Chris@16 256
Chris@16 257 // Explicitly iterating row major
Chris@16 258 template<template <class T1, class T2> class F, class M, class T>
Chris@16 259 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 260 void iterating_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
Chris@16 261 typedef F<typename M::iterator2::reference, T> functor_type;
Chris@16 262 typedef typename M::difference_type difference_type;
Chris@16 263 difference_type size1 (m.size1 ());
Chris@16 264 difference_type size2 (m.size2 ());
Chris@16 265 typename M::iterator1 it1 (m.begin1 ());
Chris@16 266 BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
Chris@16 267 while (-- size1 >= 0) {
Chris@16 268 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 269 typename M::iterator2 it2 (it1.begin ());
Chris@16 270 #else
Chris@16 271 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 272 #endif
Chris@16 273 BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
Chris@16 274 difference_type temp_size2 (size2);
Chris@16 275 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 276 while (-- temp_size2 >= 0)
Chris@16 277 functor_type::apply (*it2, t), ++ it2;
Chris@16 278 #else
Chris@16 279 DD (temp_size2, 4, r, (functor_type::apply (*it2, t), ++ it2));
Chris@16 280 #endif
Chris@16 281 ++ it1;
Chris@16 282 }
Chris@16 283 }
Chris@16 284 // Explicitly iterating column major
Chris@16 285 template<template <class T1, class T2> class F, class M, class T>
Chris@16 286 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 287 void iterating_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
Chris@16 288 typedef F<typename M::iterator1::reference, T> functor_type;
Chris@16 289 typedef typename M::difference_type difference_type;
Chris@16 290 difference_type size2 (m.size2 ());
Chris@16 291 difference_type size1 (m.size1 ());
Chris@16 292 typename M::iterator2 it2 (m.begin2 ());
Chris@16 293 BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
Chris@16 294 while (-- size2 >= 0) {
Chris@16 295 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 296 typename M::iterator1 it1 (it2.begin ());
Chris@16 297 #else
Chris@16 298 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 299 #endif
Chris@16 300 BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
Chris@16 301 difference_type temp_size1 (size1);
Chris@16 302 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 303 while (-- temp_size1 >= 0)
Chris@16 304 functor_type::apply (*it1, t), ++ it1;
Chris@16 305 #else
Chris@16 306 DD (temp_size1, 4, r, (functor_type::apply (*it1, t), ++ it1));
Chris@16 307 #endif
Chris@16 308 ++ it2;
Chris@16 309 }
Chris@16 310 }
Chris@16 311 // Explicitly indexing row major
Chris@16 312 template<template <class T1, class T2> class F, class M, class T>
Chris@16 313 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 314 void indexing_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
Chris@16 315 typedef F<typename M::reference, T> functor_type;
Chris@16 316 typedef typename M::size_type size_type;
Chris@16 317 size_type size1 (m.size1 ());
Chris@16 318 size_type size2 (m.size2 ());
Chris@16 319 for (size_type i = 0; i < size1; ++ i) {
Chris@16 320 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 321 for (size_type j = 0; j < size2; ++ j)
Chris@16 322 functor_type::apply (m (i, j), t);
Chris@16 323 #else
Chris@16 324 size_type j (0);
Chris@16 325 DD (size2, 4, r, (functor_type::apply (m (i, j), t), ++ j));
Chris@16 326 #endif
Chris@16 327 }
Chris@16 328 }
Chris@16 329 // Explicitly indexing column major
Chris@16 330 template<template <class T1, class T2> class F, class M, class T>
Chris@16 331 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 332 void indexing_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
Chris@16 333 typedef F<typename M::reference, T> functor_type;
Chris@16 334 typedef typename M::size_type size_type;
Chris@16 335 size_type size2 (m.size2 ());
Chris@16 336 size_type size1 (m.size1 ());
Chris@16 337 for (size_type j = 0; j < size2; ++ j) {
Chris@16 338 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 339 for (size_type i = 0; i < size1; ++ i)
Chris@16 340 functor_type::apply (m (i, j), t);
Chris@16 341 #else
Chris@16 342 size_type i (0);
Chris@16 343 DD (size1, 4, r, (functor_type::apply (m (i, j), t), ++ i));
Chris@16 344 #endif
Chris@16 345 }
Chris@16 346 }
Chris@16 347
Chris@16 348 // Dense (proxy) case
Chris@16 349 template<template <class T1, class T2> class F, class M, class T, class C>
Chris@16 350 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 351 void matrix_assign_scalar (M &m, const T &t, dense_proxy_tag, C) {
Chris@16 352 typedef C orientation_category;
Chris@16 353 #ifdef BOOST_UBLAS_USE_INDEXING
Chris@16 354 indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
Chris@16 355 #elif BOOST_UBLAS_USE_ITERATING
Chris@16 356 iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
Chris@16 357 #else
Chris@16 358 typedef typename M::size_type size_type;
Chris@16 359 size_type size1 (m.size1 ());
Chris@16 360 size_type size2 (m.size2 ());
Chris@16 361 if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
Chris@16 362 size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
Chris@16 363 iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
Chris@16 364 else
Chris@16 365 indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
Chris@16 366 #endif
Chris@16 367 }
Chris@16 368 // Packed (proxy) row major case
Chris@16 369 template<template <class T1, class T2> class F, class M, class T>
Chris@16 370 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 371 void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, row_major_tag) {
Chris@16 372 typedef F<typename M::iterator2::reference, T> functor_type;
Chris@16 373 typedef typename M::difference_type difference_type;
Chris@16 374 typename M::iterator1 it1 (m.begin1 ());
Chris@16 375 difference_type size1 (m.end1 () - it1);
Chris@16 376 while (-- size1 >= 0) {
Chris@16 377 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 378 typename M::iterator2 it2 (it1.begin ());
Chris@16 379 difference_type size2 (it1.end () - it2);
Chris@16 380 #else
Chris@16 381 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 382 difference_type size2 (end (it1, iterator1_tag ()) - it2);
Chris@16 383 #endif
Chris@16 384 while (-- size2 >= 0)
Chris@16 385 functor_type::apply (*it2, t), ++ it2;
Chris@16 386 ++ it1;
Chris@16 387 }
Chris@16 388 }
Chris@16 389 // Packed (proxy) column major case
Chris@16 390 template<template <class T1, class T2> class F, class M, class T>
Chris@16 391 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 392 void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, column_major_tag) {
Chris@16 393 typedef F<typename M::iterator1::reference, T> functor_type;
Chris@16 394 typedef typename M::difference_type difference_type;
Chris@16 395 typename M::iterator2 it2 (m.begin2 ());
Chris@16 396 difference_type size2 (m.end2 () - it2);
Chris@16 397 while (-- size2 >= 0) {
Chris@16 398 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 399 typename M::iterator1 it1 (it2.begin ());
Chris@16 400 difference_type size1 (it2.end () - it1);
Chris@16 401 #else
Chris@16 402 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 403 difference_type size1 (end (it2, iterator2_tag ()) - it1);
Chris@16 404 #endif
Chris@16 405 while (-- size1 >= 0)
Chris@16 406 functor_type::apply (*it1, t), ++ it1;
Chris@16 407 ++ it2;
Chris@16 408 }
Chris@16 409 }
Chris@16 410 // Sparse (proxy) row major case
Chris@16 411 template<template <class T1, class T2> class F, class M, class T>
Chris@16 412 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 413 void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, row_major_tag) {
Chris@16 414 typedef F<typename M::iterator2::reference, T> functor_type;
Chris@16 415 typename M::iterator1 it1 (m.begin1 ());
Chris@16 416 typename M::iterator1 it1_end (m.end1 ());
Chris@16 417 while (it1 != it1_end) {
Chris@16 418 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 419 typename M::iterator2 it2 (it1.begin ());
Chris@16 420 typename M::iterator2 it2_end (it1.end ());
Chris@16 421 #else
Chris@16 422 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 423 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 424 #endif
Chris@16 425 while (it2 != it2_end)
Chris@16 426 functor_type::apply (*it2, t), ++ it2;
Chris@16 427 ++ it1;
Chris@16 428 }
Chris@16 429 }
Chris@16 430 // Sparse (proxy) column major case
Chris@16 431 template<template <class T1, class T2> class F, class M, class T>
Chris@16 432 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 433 void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, column_major_tag) {
Chris@16 434 typedef F<typename M::iterator1::reference, T> functor_type;
Chris@16 435 typename M::iterator2 it2 (m.begin2 ());
Chris@16 436 typename M::iterator2 it2_end (m.end2 ());
Chris@16 437 while (it2 != it2_end) {
Chris@16 438 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 439 typename M::iterator1 it1 (it2.begin ());
Chris@16 440 typename M::iterator1 it1_end (it2.end ());
Chris@16 441 #else
Chris@16 442 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 443 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 444 #endif
Chris@16 445 while (it1 != it1_end)
Chris@16 446 functor_type::apply (*it1, t), ++ it1;
Chris@16 447 ++ it2;
Chris@16 448 }
Chris@16 449 }
Chris@16 450
Chris@16 451 // Dispatcher
Chris@16 452 template<template <class T1, class T2> class F, class M, class T>
Chris@16 453 BOOST_UBLAS_INLINE
Chris@16 454 void matrix_assign_scalar (M &m, const T &t) {
Chris@16 455 typedef typename M::storage_category storage_category;
Chris@16 456 typedef typename M::orientation_category orientation_category;
Chris@16 457 matrix_assign_scalar<F> (m, t, storage_category (), orientation_category ());
Chris@16 458 }
Chris@16 459
Chris@16 460 template<class SC, bool COMPUTED, class RI1, class RI2>
Chris@16 461 struct matrix_assign_traits {
Chris@16 462 typedef SC storage_category;
Chris@16 463 };
Chris@16 464
Chris@16 465 template<bool COMPUTED>
Chris@16 466 struct matrix_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
Chris@16 467 typedef packed_tag storage_category;
Chris@16 468 };
Chris@16 469 template<>
Chris@16 470 struct matrix_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 471 typedef sparse_tag storage_category;
Chris@16 472 };
Chris@16 473 template<>
Chris@16 474 struct matrix_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 475 typedef sparse_proxy_tag storage_category;
Chris@16 476 };
Chris@16 477
Chris@16 478 template<bool COMPUTED>
Chris@16 479 struct matrix_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
Chris@16 480 typedef packed_proxy_tag storage_category;
Chris@16 481 };
Chris@16 482 template<bool COMPUTED>
Chris@16 483 struct matrix_assign_traits<dense_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 484 typedef sparse_proxy_tag storage_category;
Chris@16 485 };
Chris@16 486
Chris@16 487 template<>
Chris@16 488 struct matrix_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 489 typedef sparse_tag storage_category;
Chris@16 490 };
Chris@16 491 template<>
Chris@16 492 struct matrix_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 493 typedef sparse_proxy_tag storage_category;
Chris@16 494 };
Chris@16 495
Chris@16 496 template<bool COMPUTED>
Chris@16 497 struct matrix_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 498 typedef sparse_proxy_tag storage_category;
Chris@16 499 };
Chris@16 500
Chris@16 501 template<>
Chris@16 502 struct matrix_assign_traits<sparse_tag, true, dense_random_access_iterator_tag, dense_random_access_iterator_tag> {
Chris@16 503 typedef sparse_proxy_tag storage_category;
Chris@16 504 };
Chris@16 505 template<>
Chris@16 506 struct matrix_assign_traits<sparse_tag, true, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
Chris@16 507 typedef sparse_proxy_tag storage_category;
Chris@16 508 };
Chris@16 509 template<>
Chris@16 510 struct matrix_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 511 typedef sparse_proxy_tag storage_category;
Chris@16 512 };
Chris@16 513
Chris@16 514 // Explicitly iterating row major
Chris@16 515 template<template <class T1, class T2> class F, class M, class E>
Chris@16 516 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 517 void iterating_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
Chris@16 518 typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
Chris@16 519 typedef typename M::difference_type difference_type;
Chris@16 520 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
Chris@16 521 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
Chris@16 522 typename M::iterator1 it1 (m.begin1 ());
Chris@16 523 BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
Chris@16 524 typename E::const_iterator1 it1e (e ().begin1 ());
Chris@16 525 BOOST_UBLAS_CHECK (size2 == 0 || e ().end1 () - it1e == size1, bad_size ());
Chris@16 526 while (-- size1 >= 0) {
Chris@16 527 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 528 typename M::iterator2 it2 (it1.begin ());
Chris@16 529 typename E::const_iterator2 it2e (it1e.begin ());
Chris@16 530 #else
Chris@16 531 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 532 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 533 #endif
Chris@16 534 BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
Chris@16 535 BOOST_UBLAS_CHECK (it1e.end () - it2e == size2, bad_size ());
Chris@16 536 difference_type temp_size2 (size2);
Chris@16 537 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 538 while (-- temp_size2 >= 0)
Chris@16 539 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
Chris@16 540 #else
Chris@16 541 DD (temp_size2, 2, r, (functor_type::apply (*it2, *it2e), ++ it2, ++ it2e));
Chris@16 542 #endif
Chris@16 543 ++ it1, ++ it1e;
Chris@16 544 }
Chris@16 545 }
Chris@16 546 // Explicitly iterating column major
Chris@16 547 template<template <class T1, class T2> class F, class M, class E>
Chris@16 548 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 549 void iterating_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
Chris@16 550 typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
Chris@16 551 typedef typename M::difference_type difference_type;
Chris@16 552 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
Chris@16 553 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
Chris@16 554 typename M::iterator2 it2 (m.begin2 ());
Chris@16 555 BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
Chris@16 556 typename E::const_iterator2 it2e (e ().begin2 ());
Chris@16 557 BOOST_UBLAS_CHECK (size1 == 0 || e ().end2 () - it2e == size2, bad_size ());
Chris@16 558 while (-- size2 >= 0) {
Chris@16 559 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 560 typename M::iterator1 it1 (it2.begin ());
Chris@16 561 typename E::const_iterator1 it1e (it2e.begin ());
Chris@16 562 #else
Chris@16 563 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 564 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 565 #endif
Chris@16 566 BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
Chris@16 567 BOOST_UBLAS_CHECK (it2e.end () - it1e == size1, bad_size ());
Chris@16 568 difference_type temp_size1 (size1);
Chris@16 569 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 570 while (-- temp_size1 >= 0)
Chris@16 571 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
Chris@16 572 #else
Chris@16 573 DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e));
Chris@16 574 #endif
Chris@16 575 ++ it2, ++ it2e;
Chris@16 576 }
Chris@16 577 }
Chris@16 578 // Explicitly indexing row major
Chris@16 579 template<template <class T1, class T2> class F, class M, class E>
Chris@16 580 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 581 void indexing_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
Chris@16 582 typedef F<typename M::reference, typename E::value_type> functor_type;
Chris@16 583 typedef typename M::size_type size_type;
Chris@16 584 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
Chris@16 585 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
Chris@16 586 for (size_type i = 0; i < size1; ++ i) {
Chris@16 587 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 588 for (size_type j = 0; j < size2; ++ j)
Chris@16 589 functor_type::apply (m (i, j), e () (i, j));
Chris@16 590 #else
Chris@16 591 size_type j (0);
Chris@16 592 DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j));
Chris@16 593 #endif
Chris@16 594 }
Chris@16 595 }
Chris@16 596 // Explicitly indexing column major
Chris@16 597 template<template <class T1, class T2> class F, class M, class E>
Chris@16 598 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 599 void indexing_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
Chris@16 600 typedef F<typename M::reference, typename E::value_type> functor_type;
Chris@16 601 typedef typename M::size_type size_type;
Chris@16 602 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
Chris@16 603 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
Chris@16 604 for (size_type j = 0; j < size2; ++ j) {
Chris@16 605 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 606 for (size_type i = 0; i < size1; ++ i)
Chris@16 607 functor_type::apply (m (i, j), e () (i, j));
Chris@16 608 #else
Chris@16 609 size_type i (0);
Chris@16 610 DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i));
Chris@16 611 #endif
Chris@16 612 }
Chris@16 613 }
Chris@16 614
Chris@16 615 // Dense (proxy) case
Chris@16 616 template<template <class T1, class T2> class F, class R, class M, class E, class C>
Chris@16 617 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 618 void matrix_assign (M &m, const matrix_expression<E> &e, dense_proxy_tag, C) {
Chris@16 619 // R unnecessary, make_conformant not required
Chris@16 620 typedef C orientation_category;
Chris@16 621 #ifdef BOOST_UBLAS_USE_INDEXING
Chris@16 622 indexing_matrix_assign<F> (m, e, orientation_category ());
Chris@16 623 #elif BOOST_UBLAS_USE_ITERATING
Chris@16 624 iterating_matrix_assign<F> (m, e, orientation_category ());
Chris@16 625 #else
Chris@16 626 typedef typename M::difference_type difference_type;
Chris@16 627 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
Chris@16 628 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
Chris@16 629 if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
Chris@16 630 size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
Chris@16 631 iterating_matrix_assign<F> (m, e, orientation_category ());
Chris@16 632 else
Chris@16 633 indexing_matrix_assign<F> (m, e, orientation_category ());
Chris@16 634 #endif
Chris@16 635 }
Chris@16 636 // Packed (proxy) row major case
Chris@16 637 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 638 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 639 void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
Chris@16 640 typedef typename matrix_traits<E>::value_type expr_value_type;
Chris@16 641 typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
Chris@16 642 // R unnecessary, make_conformant not required
Chris@16 643 typedef typename M::difference_type difference_type;
Chris@101 644
Chris@16 645 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 646 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@101 647
Chris@16 648 #if BOOST_UBLAS_TYPE_CHECK
Chris@101 649 typedef typename M::value_type value_type;
Chris@16 650 matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
Chris@16 651 indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
Chris@16 652 indexing_matrix_assign<F> (cm, e, row_major_tag ());
Chris@16 653 #endif
Chris@16 654 typename M::iterator1 it1 (m.begin1 ());
Chris@16 655 typename M::iterator1 it1_end (m.end1 ());
Chris@16 656 typename E::const_iterator1 it1e (e ().begin1 ());
Chris@16 657 typename E::const_iterator1 it1e_end (e ().end1 ());
Chris@16 658 difference_type it1_size (it1_end - it1);
Chris@16 659 difference_type it1e_size (it1e_end - it1e);
Chris@16 660 difference_type diff1 (0);
Chris@16 661 if (it1_size > 0 && it1e_size > 0)
Chris@16 662 diff1 = it1.index1 () - it1e.index1 ();
Chris@16 663 if (diff1 != 0) {
Chris@16 664 difference_type size1 = (std::min) (diff1, it1e_size);
Chris@16 665 if (size1 > 0) {
Chris@16 666 it1e += size1;
Chris@16 667 it1e_size -= size1;
Chris@16 668 diff1 -= size1;
Chris@16 669 }
Chris@16 670 size1 = (std::min) (- diff1, it1_size);
Chris@16 671 if (size1 > 0) {
Chris@16 672 it1_size -= size1;
Chris@16 673 if (!functor_type::computed) {
Chris@16 674 while (-- size1 >= 0) { // zeroing
Chris@16 675 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 676 typename M::iterator2 it2 (it1.begin ());
Chris@16 677 typename M::iterator2 it2_end (it1.end ());
Chris@16 678 #else
Chris@16 679 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 680 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 681 #endif
Chris@16 682 difference_type size2 (it2_end - it2);
Chris@16 683 while (-- size2 >= 0)
Chris@16 684 functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
Chris@16 685 ++ it1;
Chris@16 686 }
Chris@16 687 } else {
Chris@16 688 it1 += size1;
Chris@16 689 }
Chris@16 690 diff1 += size1;
Chris@16 691 }
Chris@16 692 }
Chris@16 693 difference_type size1 ((std::min) (it1_size, it1e_size));
Chris@16 694 it1_size -= size1;
Chris@16 695 it1e_size -= size1;
Chris@16 696 while (-- size1 >= 0) {
Chris@16 697 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 698 typename M::iterator2 it2 (it1.begin ());
Chris@16 699 typename M::iterator2 it2_end (it1.end ());
Chris@16 700 typename E::const_iterator2 it2e (it1e.begin ());
Chris@16 701 typename E::const_iterator2 it2e_end (it1e.end ());
Chris@16 702 #else
Chris@16 703 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 704 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 705 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 706 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 707 #endif
Chris@16 708 difference_type it2_size (it2_end - it2);
Chris@16 709 difference_type it2e_size (it2e_end - it2e);
Chris@16 710 difference_type diff2 (0);
Chris@16 711 if (it2_size > 0 && it2e_size > 0) {
Chris@16 712 diff2 = it2.index2 () - it2e.index2 ();
Chris@16 713 difference_type size2 = (std::min) (diff2, it2e_size);
Chris@16 714 if (size2 > 0) {
Chris@16 715 it2e += size2;
Chris@16 716 it2e_size -= size2;
Chris@16 717 diff2 -= size2;
Chris@16 718 }
Chris@16 719 size2 = (std::min) (- diff2, it2_size);
Chris@16 720 if (size2 > 0) {
Chris@16 721 it2_size -= size2;
Chris@16 722 if (!functor_type::computed) {
Chris@16 723 while (-- size2 >= 0) // zeroing
Chris@16 724 functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
Chris@16 725 } else {
Chris@16 726 it2 += size2;
Chris@16 727 }
Chris@16 728 diff2 += size2;
Chris@16 729 }
Chris@16 730 }
Chris@16 731 difference_type size2 ((std::min) (it2_size, it2e_size));
Chris@16 732 it2_size -= size2;
Chris@16 733 it2e_size -= size2;
Chris@16 734 while (-- size2 >= 0)
Chris@16 735 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
Chris@16 736 size2 = it2_size;
Chris@16 737 if (!functor_type::computed) {
Chris@16 738 while (-- size2 >= 0) // zeroing
Chris@16 739 functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
Chris@16 740 } else {
Chris@16 741 it2 += size2;
Chris@16 742 }
Chris@16 743 ++ it1, ++ it1e;
Chris@16 744 }
Chris@16 745 size1 = it1_size;
Chris@16 746 if (!functor_type::computed) {
Chris@16 747 while (-- size1 >= 0) { // zeroing
Chris@16 748 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 749 typename M::iterator2 it2 (it1.begin ());
Chris@16 750 typename M::iterator2 it2_end (it1.end ());
Chris@16 751 #else
Chris@16 752 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 753 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 754 #endif
Chris@16 755 difference_type size2 (it2_end - it2);
Chris@16 756 while (-- size2 >= 0)
Chris@16 757 functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
Chris@16 758 ++ it1;
Chris@16 759 }
Chris@16 760 } else {
Chris@16 761 it1 += size1;
Chris@16 762 }
Chris@16 763 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 764 if (! disable_type_check<bool>::value)
Chris@16 765 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
Chris@16 766 #endif
Chris@16 767 }
Chris@16 768 // Packed (proxy) column major case
Chris@16 769 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 770 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 771 void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
Chris@16 772 typedef typename matrix_traits<E>::value_type expr_value_type;
Chris@16 773 typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
Chris@16 774 // R unnecessary, make_conformant not required
Chris@16 775 typedef typename M::difference_type difference_type;
Chris@101 776
Chris@16 777 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@16 778 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@101 779
Chris@16 780 #if BOOST_UBLAS_TYPE_CHECK
Chris@101 781 typedef typename M::value_type value_type;
Chris@16 782 matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
Chris@16 783 indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
Chris@16 784 indexing_matrix_assign<F> (cm, e, column_major_tag ());
Chris@16 785 #endif
Chris@16 786 typename M::iterator2 it2 (m.begin2 ());
Chris@16 787 typename M::iterator2 it2_end (m.end2 ());
Chris@16 788 typename E::const_iterator2 it2e (e ().begin2 ());
Chris@16 789 typename E::const_iterator2 it2e_end (e ().end2 ());
Chris@16 790 difference_type it2_size (it2_end - it2);
Chris@16 791 difference_type it2e_size (it2e_end - it2e);
Chris@16 792 difference_type diff2 (0);
Chris@16 793 if (it2_size > 0 && it2e_size > 0)
Chris@16 794 diff2 = it2.index2 () - it2e.index2 ();
Chris@16 795 if (diff2 != 0) {
Chris@16 796 difference_type size2 = (std::min) (diff2, it2e_size);
Chris@16 797 if (size2 > 0) {
Chris@16 798 it2e += size2;
Chris@16 799 it2e_size -= size2;
Chris@16 800 diff2 -= size2;
Chris@16 801 }
Chris@16 802 size2 = (std::min) (- diff2, it2_size);
Chris@16 803 if (size2 > 0) {
Chris@16 804 it2_size -= size2;
Chris@16 805 if (!functor_type::computed) {
Chris@16 806 while (-- size2 >= 0) { // zeroing
Chris@16 807 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 808 typename M::iterator1 it1 (it2.begin ());
Chris@16 809 typename M::iterator1 it1_end (it2.end ());
Chris@16 810 #else
Chris@16 811 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 812 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 813 #endif
Chris@16 814 difference_type size1 (it1_end - it1);
Chris@16 815 while (-- size1 >= 0)
Chris@16 816 functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
Chris@16 817 ++ it2;
Chris@16 818 }
Chris@16 819 } else {
Chris@16 820 it2 += size2;
Chris@16 821 }
Chris@16 822 diff2 += size2;
Chris@16 823 }
Chris@16 824 }
Chris@16 825 difference_type size2 ((std::min) (it2_size, it2e_size));
Chris@16 826 it2_size -= size2;
Chris@16 827 it2e_size -= size2;
Chris@16 828 while (-- size2 >= 0) {
Chris@16 829 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 830 typename M::iterator1 it1 (it2.begin ());
Chris@16 831 typename M::iterator1 it1_end (it2.end ());
Chris@16 832 typename E::const_iterator1 it1e (it2e.begin ());
Chris@16 833 typename E::const_iterator1 it1e_end (it2e.end ());
Chris@16 834 #else
Chris@16 835 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 836 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 837 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 838 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 839 #endif
Chris@16 840 difference_type it1_size (it1_end - it1);
Chris@16 841 difference_type it1e_size (it1e_end - it1e);
Chris@16 842 difference_type diff1 (0);
Chris@16 843 if (it1_size > 0 && it1e_size > 0) {
Chris@16 844 diff1 = it1.index1 () - it1e.index1 ();
Chris@16 845 difference_type size1 = (std::min) (diff1, it1e_size);
Chris@16 846 if (size1 > 0) {
Chris@16 847 it1e += size1;
Chris@16 848 it1e_size -= size1;
Chris@16 849 diff1 -= size1;
Chris@16 850 }
Chris@16 851 size1 = (std::min) (- diff1, it1_size);
Chris@16 852 if (size1 > 0) {
Chris@16 853 it1_size -= size1;
Chris@16 854 if (!functor_type::computed) {
Chris@16 855 while (-- size1 >= 0) // zeroing
Chris@16 856 functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
Chris@16 857 } else {
Chris@16 858 it1 += size1;
Chris@16 859 }
Chris@16 860 diff1 += size1;
Chris@16 861 }
Chris@16 862 }
Chris@16 863 difference_type size1 ((std::min) (it1_size, it1e_size));
Chris@16 864 it1_size -= size1;
Chris@16 865 it1e_size -= size1;
Chris@16 866 while (-- size1 >= 0)
Chris@16 867 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
Chris@16 868 size1 = it1_size;
Chris@16 869 if (!functor_type::computed) {
Chris@16 870 while (-- size1 >= 0) // zeroing
Chris@16 871 functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
Chris@16 872 } else {
Chris@16 873 it1 += size1;
Chris@16 874 }
Chris@16 875 ++ it2, ++ it2e;
Chris@16 876 }
Chris@16 877 size2 = it2_size;
Chris@16 878 if (!functor_type::computed) {
Chris@16 879 while (-- size2 >= 0) { // zeroing
Chris@16 880 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 881 typename M::iterator1 it1 (it2.begin ());
Chris@16 882 typename M::iterator1 it1_end (it2.end ());
Chris@16 883 #else
Chris@16 884 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 885 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 886 #endif
Chris@16 887 difference_type size1 (it1_end - it1);
Chris@16 888 while (-- size1 >= 0)
Chris@16 889 functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
Chris@16 890 ++ it2;
Chris@16 891 }
Chris@16 892 } else {
Chris@16 893 it2 += size2;
Chris@16 894 }
Chris@16 895 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 896 if (! disable_type_check<bool>::value)
Chris@16 897 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
Chris@16 898 #endif
Chris@16 899 }
Chris@16 900 // Sparse row major case
Chris@16 901 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 902 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 903 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, row_major_tag) {
Chris@16 904 typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
Chris@16 905 // R unnecessary, make_conformant not required
Chris@16 906 BOOST_STATIC_ASSERT ((!functor_type::computed));
Chris@16 907 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 908 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@16 909 typedef typename M::value_type value_type;
Chris@16 910 // Sparse type has no numeric constraints to check
Chris@16 911
Chris@16 912 m.clear ();
Chris@16 913 typename E::const_iterator1 it1e (e ().begin1 ());
Chris@16 914 typename E::const_iterator1 it1e_end (e ().end1 ());
Chris@16 915 while (it1e != it1e_end) {
Chris@16 916 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 917 typename E::const_iterator2 it2e (it1e.begin ());
Chris@16 918 typename E::const_iterator2 it2e_end (it1e.end ());
Chris@16 919 #else
Chris@16 920 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 921 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 922 #endif
Chris@16 923 while (it2e != it2e_end) {
Chris@16 924 value_type t (*it2e);
Chris@16 925 if (t != value_type/*zero*/())
Chris@16 926 m.insert_element (it2e.index1 (), it2e.index2 (), t);
Chris@16 927 ++ it2e;
Chris@16 928 }
Chris@16 929 ++ it1e;
Chris@16 930 }
Chris@16 931 }
Chris@16 932 // Sparse column major case
Chris@16 933 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 934 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 935 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, column_major_tag) {
Chris@16 936 typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
Chris@16 937 // R unnecessary, make_conformant not required
Chris@16 938 BOOST_STATIC_ASSERT ((!functor_type::computed));
Chris@16 939 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 940 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@16 941 typedef typename M::value_type value_type;
Chris@16 942 // Sparse type has no numeric constraints to check
Chris@16 943
Chris@16 944 m.clear ();
Chris@16 945 typename E::const_iterator2 it2e (e ().begin2 ());
Chris@16 946 typename E::const_iterator2 it2e_end (e ().end2 ());
Chris@16 947 while (it2e != it2e_end) {
Chris@16 948 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 949 typename E::const_iterator1 it1e (it2e.begin ());
Chris@16 950 typename E::const_iterator1 it1e_end (it2e.end ());
Chris@16 951 #else
Chris@16 952 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 953 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 954 #endif
Chris@16 955 while (it1e != it1e_end) {
Chris@16 956 value_type t (*it1e);
Chris@16 957 if (t != value_type/*zero*/())
Chris@16 958 m.insert_element (it1e.index1 (), it1e.index2 (), t);
Chris@16 959 ++ it1e;
Chris@16 960 }
Chris@16 961 ++ it2e;
Chris@16 962 }
Chris@16 963 }
Chris@16 964 // Sparse proxy or functional row major case
Chris@16 965 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 966 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 967 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
Chris@16 968 typedef typename matrix_traits<E>::value_type expr_value_type;
Chris@16 969 typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
Chris@16 970 typedef R conformant_restrict_type;
Chris@16 971 typedef typename M::size_type size_type;
Chris@16 972 typedef typename M::difference_type difference_type;
Chris@101 973
Chris@16 974 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 975 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@101 976
Chris@16 977 #if BOOST_UBLAS_TYPE_CHECK
Chris@101 978 typedef typename M::value_type value_type;
Chris@16 979 matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
Chris@16 980 indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
Chris@16 981 indexing_matrix_assign<F> (cm, e, row_major_tag ());
Chris@16 982 #endif
Chris@16 983 detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
Chris@16 984
Chris@16 985 typename M::iterator1 it1 (m.begin1 ());
Chris@16 986 typename M::iterator1 it1_end (m.end1 ());
Chris@16 987 typename E::const_iterator1 it1e (e ().begin1 ());
Chris@16 988 typename E::const_iterator1 it1e_end (e ().end1 ());
Chris@16 989 while (it1 != it1_end && it1e != it1e_end) {
Chris@16 990 difference_type compare = it1.index1 () - it1e.index1 ();
Chris@16 991 if (compare == 0) {
Chris@16 992 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 993 typename M::iterator2 it2 (it1.begin ());
Chris@16 994 typename M::iterator2 it2_end (it1.end ());
Chris@16 995 typename E::const_iterator2 it2e (it1e.begin ());
Chris@16 996 typename E::const_iterator2 it2e_end (it1e.end ());
Chris@16 997 #else
Chris@16 998 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 999 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 1000 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 1001 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 1002 #endif
Chris@16 1003 if (it2 != it2_end && it2e != it2e_end) {
Chris@16 1004 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
Chris@16 1005 while (true) {
Chris@101 1006 difference_type compare2 = it2_index - it2e_index;
Chris@101 1007 if (compare2 == 0) {
Chris@16 1008 functor_type::apply (*it2, *it2e);
Chris@16 1009 ++ it2, ++ it2e;
Chris@16 1010 if (it2 != it2_end && it2e != it2e_end) {
Chris@16 1011 it2_index = it2.index2 ();
Chris@16 1012 it2e_index = it2e.index2 ();
Chris@16 1013 } else
Chris@16 1014 break;
Chris@101 1015 } else if (compare2 < 0) {
Chris@16 1016 if (!functor_type::computed) {
Chris@16 1017 functor_type::apply (*it2, expr_value_type/*zero*/());
Chris@16 1018 ++ it2;
Chris@16 1019 } else
Chris@101 1020 increment (it2, it2_end, - compare2);
Chris@16 1021 if (it2 != it2_end)
Chris@16 1022 it2_index = it2.index2 ();
Chris@16 1023 else
Chris@16 1024 break;
Chris@101 1025 } else if (compare2 > 0) {
Chris@101 1026 increment (it2e, it2e_end, compare2);
Chris@16 1027 if (it2e != it2e_end)
Chris@16 1028 it2e_index = it2e.index2 ();
Chris@16 1029 else
Chris@16 1030 break;
Chris@16 1031 }
Chris@16 1032 }
Chris@16 1033 }
Chris@16 1034 if (!functor_type::computed) {
Chris@16 1035 while (it2 != it2_end) { // zeroing
Chris@16 1036 functor_type::apply (*it2, expr_value_type/*zero*/());
Chris@16 1037 ++ it2;
Chris@16 1038 }
Chris@16 1039 } else {
Chris@16 1040 it2 = it2_end;
Chris@16 1041 }
Chris@16 1042 ++ it1, ++ it1e;
Chris@16 1043 } else if (compare < 0) {
Chris@16 1044 if (!functor_type::computed) {
Chris@16 1045 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1046 typename M::iterator2 it2 (it1.begin ());
Chris@16 1047 typename M::iterator2 it2_end (it1.end ());
Chris@16 1048 #else
Chris@16 1049 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 1050 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 1051 #endif
Chris@16 1052 while (it2 != it2_end) { // zeroing
Chris@16 1053 functor_type::apply (*it2, expr_value_type/*zero*/());
Chris@16 1054 ++ it2;
Chris@16 1055 }
Chris@16 1056 ++ it1;
Chris@16 1057 } else {
Chris@16 1058 increment (it1, it1_end, - compare);
Chris@16 1059 }
Chris@16 1060 } else if (compare > 0) {
Chris@16 1061 increment (it1e, it1e_end, compare);
Chris@16 1062 }
Chris@16 1063 }
Chris@16 1064 if (!functor_type::computed) {
Chris@16 1065 while (it1 != it1_end) {
Chris@16 1066 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1067 typename M::iterator2 it2 (it1.begin ());
Chris@16 1068 typename M::iterator2 it2_end (it1.end ());
Chris@16 1069 #else
Chris@16 1070 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 1071 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 1072 #endif
Chris@16 1073 while (it2 != it2_end) { // zeroing
Chris@16 1074 functor_type::apply (*it2, expr_value_type/*zero*/());
Chris@16 1075 ++ it2;
Chris@16 1076 }
Chris@16 1077 ++ it1;
Chris@16 1078 }
Chris@16 1079 } else {
Chris@16 1080 it1 = it1_end;
Chris@16 1081 }
Chris@16 1082 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1083 if (! disable_type_check<bool>::value)
Chris@16 1084 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
Chris@16 1085 #endif
Chris@16 1086 }
Chris@16 1087 // Sparse proxy or functional column major case
Chris@16 1088 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1089 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 1090 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
Chris@16 1091 typedef typename matrix_traits<E>::value_type expr_value_type;
Chris@16 1092 typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
Chris@16 1093 typedef R conformant_restrict_type;
Chris@16 1094 typedef typename M::size_type size_type;
Chris@16 1095 typedef typename M::difference_type difference_type;
Chris@101 1096
Chris@16 1097 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 1098 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@101 1099
Chris@16 1100 #if BOOST_UBLAS_TYPE_CHECK
Chris@101 1101 typedef typename M::value_type value_type;
Chris@16 1102 matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
Chris@16 1103 indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
Chris@16 1104 indexing_matrix_assign<F> (cm, e, column_major_tag ());
Chris@16 1105 #endif
Chris@16 1106 detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
Chris@16 1107
Chris@16 1108 typename M::iterator2 it2 (m.begin2 ());
Chris@16 1109 typename M::iterator2 it2_end (m.end2 ());
Chris@16 1110 typename E::const_iterator2 it2e (e ().begin2 ());
Chris@16 1111 typename E::const_iterator2 it2e_end (e ().end2 ());
Chris@16 1112 while (it2 != it2_end && it2e != it2e_end) {
Chris@16 1113 difference_type compare = it2.index2 () - it2e.index2 ();
Chris@16 1114 if (compare == 0) {
Chris@16 1115 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1116 typename M::iterator1 it1 (it2.begin ());
Chris@16 1117 typename M::iterator1 it1_end (it2.end ());
Chris@16 1118 typename E::const_iterator1 it1e (it2e.begin ());
Chris@16 1119 typename E::const_iterator1 it1e_end (it2e.end ());
Chris@16 1120 #else
Chris@16 1121 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 1122 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 1123 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 1124 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 1125 #endif
Chris@16 1126 if (it1 != it1_end && it1e != it1e_end) {
Chris@16 1127 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
Chris@16 1128 while (true) {
Chris@101 1129 difference_type compare2 = it1_index - it1e_index;
Chris@101 1130 if (compare2 == 0) {
Chris@16 1131 functor_type::apply (*it1, *it1e);
Chris@16 1132 ++ it1, ++ it1e;
Chris@16 1133 if (it1 != it1_end && it1e != it1e_end) {
Chris@16 1134 it1_index = it1.index1 ();
Chris@16 1135 it1e_index = it1e.index1 ();
Chris@16 1136 } else
Chris@16 1137 break;
Chris@101 1138 } else if (compare2 < 0) {
Chris@16 1139 if (!functor_type::computed) {
Chris@16 1140 functor_type::apply (*it1, expr_value_type/*zero*/()); // zeroing
Chris@16 1141 ++ it1;
Chris@16 1142 } else
Chris@101 1143 increment (it1, it1_end, - compare2);
Chris@16 1144 if (it1 != it1_end)
Chris@16 1145 it1_index = it1.index1 ();
Chris@16 1146 else
Chris@16 1147 break;
Chris@101 1148 } else if (compare2 > 0) {
Chris@101 1149 increment (it1e, it1e_end, compare2);
Chris@16 1150 if (it1e != it1e_end)
Chris@16 1151 it1e_index = it1e.index1 ();
Chris@16 1152 else
Chris@16 1153 break;
Chris@16 1154 }
Chris@16 1155 }
Chris@16 1156 }
Chris@16 1157 if (!functor_type::computed) {
Chris@16 1158 while (it1 != it1_end) { // zeroing
Chris@16 1159 functor_type::apply (*it1, expr_value_type/*zero*/());
Chris@16 1160 ++ it1;
Chris@16 1161 }
Chris@16 1162 } else {
Chris@16 1163 it1 = it1_end;
Chris@16 1164 }
Chris@16 1165 ++ it2, ++ it2e;
Chris@16 1166 } else if (compare < 0) {
Chris@16 1167 if (!functor_type::computed) {
Chris@16 1168 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1169 typename M::iterator1 it1 (it2.begin ());
Chris@16 1170 typename M::iterator1 it1_end (it2.end ());
Chris@16 1171 #else
Chris@16 1172 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 1173 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 1174 #endif
Chris@16 1175 while (it1 != it1_end) { // zeroing
Chris@16 1176 functor_type::apply (*it1, expr_value_type/*zero*/());
Chris@16 1177 ++ it1;
Chris@16 1178 }
Chris@16 1179 ++ it2;
Chris@16 1180 } else {
Chris@16 1181 increment (it2, it2_end, - compare);
Chris@16 1182 }
Chris@16 1183 } else if (compare > 0) {
Chris@16 1184 increment (it2e, it2e_end, compare);
Chris@16 1185 }
Chris@16 1186 }
Chris@16 1187 if (!functor_type::computed) {
Chris@16 1188 while (it2 != it2_end) {
Chris@16 1189 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1190 typename M::iterator1 it1 (it2.begin ());
Chris@16 1191 typename M::iterator1 it1_end (it2.end ());
Chris@16 1192 #else
Chris@16 1193 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 1194 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 1195 #endif
Chris@16 1196 while (it1 != it1_end) { // zeroing
Chris@16 1197 functor_type::apply (*it1, expr_value_type/*zero*/());
Chris@16 1198 ++ it1;
Chris@16 1199 }
Chris@16 1200 ++ it2;
Chris@16 1201 }
Chris@16 1202 } else {
Chris@16 1203 it2 = it2_end;
Chris@16 1204 }
Chris@16 1205 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1206 if (! disable_type_check<bool>::value)
Chris@16 1207 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
Chris@16 1208 #endif
Chris@16 1209 }
Chris@16 1210
Chris@16 1211 // Dispatcher
Chris@16 1212 template<template <class T1, class T2> class F, class M, class E>
Chris@16 1213 BOOST_UBLAS_INLINE
Chris@16 1214 void matrix_assign (M &m, const matrix_expression<E> &e) {
Chris@16 1215 typedef typename matrix_assign_traits<typename M::storage_category,
Chris@16 1216 F<typename M::reference, typename E::value_type>::computed,
Chris@16 1217 typename E::const_iterator1::iterator_category,
Chris@16 1218 typename E::const_iterator2::iterator_category>::storage_category storage_category;
Chris@16 1219 // give preference to matrix M's orientation if known
Chris@16 1220 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
Chris@16 1221 typename E::orientation_category ,
Chris@16 1222 typename M::orientation_category >::type orientation_category;
Chris@16 1223 typedef basic_full<typename M::size_type> unrestricted;
Chris@16 1224 matrix_assign<F, unrestricted> (m, e, storage_category (), orientation_category ());
Chris@16 1225 }
Chris@16 1226 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1227 BOOST_UBLAS_INLINE
Chris@16 1228 void matrix_assign (M &m, const matrix_expression<E> &e) {
Chris@16 1229 typedef R conformant_restrict_type;
Chris@16 1230 typedef typename matrix_assign_traits<typename M::storage_category,
Chris@16 1231 F<typename M::reference, typename E::value_type>::computed,
Chris@16 1232 typename E::const_iterator1::iterator_category,
Chris@16 1233 typename E::const_iterator2::iterator_category>::storage_category storage_category;
Chris@16 1234 // give preference to matrix M's orientation if known
Chris@16 1235 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
Chris@16 1236 typename E::orientation_category ,
Chris@16 1237 typename M::orientation_category >::type orientation_category;
Chris@16 1238 matrix_assign<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
Chris@16 1239 }
Chris@16 1240
Chris@16 1241 template<class SC, class RI1, class RI2>
Chris@16 1242 struct matrix_swap_traits {
Chris@16 1243 typedef SC storage_category;
Chris@16 1244 };
Chris@16 1245
Chris@16 1246 template<>
Chris@16 1247 struct matrix_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 1248 typedef sparse_proxy_tag storage_category;
Chris@16 1249 };
Chris@16 1250
Chris@16 1251 template<>
Chris@16 1252 struct matrix_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
Chris@16 1253 typedef sparse_proxy_tag storage_category;
Chris@16 1254 };
Chris@16 1255
Chris@16 1256 // Dense (proxy) row major case
Chris@16 1257 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1258 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 1259 void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, row_major_tag) {
Chris@16 1260 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
Chris@16 1261 // R unnecessary, make_conformant not required
Chris@101 1262 //typedef typename M::size_type size_type; // gcc is complaining that this is not used, although this is not right
Chris@16 1263 typedef typename M::difference_type difference_type;
Chris@16 1264 typename M::iterator1 it1 (m.begin1 ());
Chris@16 1265 typename E::iterator1 it1e (e ().begin1 ());
Chris@101 1266 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (e ().end1 () - it1e)));
Chris@16 1267 while (-- size1 >= 0) {
Chris@16 1268 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1269 typename M::iterator2 it2 (it1.begin ());
Chris@16 1270 typename E::iterator2 it2e (it1e.begin ());
Chris@101 1271 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (it1e.end () - it2e)));
Chris@16 1272 #else
Chris@16 1273 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 1274 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@101 1275 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (end (it1e, iterator1_tag ()) - it2e)));
Chris@16 1276 #endif
Chris@16 1277 while (-- size2 >= 0)
Chris@16 1278 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
Chris@16 1279 ++ it1, ++ it1e;
Chris@16 1280 }
Chris@16 1281 }
Chris@16 1282 // Dense (proxy) column major case
Chris@16 1283 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1284 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 1285 void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, column_major_tag) {
Chris@16 1286 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
Chris@16 1287 // R unnecessary, make_conformant not required
Chris@101 1288 // typedef typename M::size_type size_type; // gcc is complaining that this is not used, although this is not right
Chris@16 1289 typedef typename M::difference_type difference_type;
Chris@16 1290 typename M::iterator2 it2 (m.begin2 ());
Chris@16 1291 typename E::iterator2 it2e (e ().begin2 ());
Chris@101 1292 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (e ().end2 () - it2e)));
Chris@16 1293 while (-- size2 >= 0) {
Chris@16 1294 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1295 typename M::iterator1 it1 (it2.begin ());
Chris@16 1296 typename E::iterator1 it1e (it2e.begin ());
Chris@101 1297 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (it2e.end () - it1e)));
Chris@16 1298 #else
Chris@16 1299 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 1300 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@101 1301 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (end (it2e, iterator2_tag ()) - it1e)));
Chris@16 1302 #endif
Chris@16 1303 while (-- size1 >= 0)
Chris@16 1304 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
Chris@16 1305 ++ it2, ++ it2e;
Chris@16 1306 }
Chris@16 1307 }
Chris@16 1308 // Packed (proxy) row major case
Chris@16 1309 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1310 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 1311 void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
Chris@16 1312 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
Chris@16 1313 // R unnecessary, make_conformant not required
Chris@16 1314 typedef typename M::difference_type difference_type;
Chris@16 1315 typename M::iterator1 it1 (m.begin1 ());
Chris@16 1316 typename E::iterator1 it1e (e ().begin1 ());
Chris@16 1317 difference_type size1 (BOOST_UBLAS_SAME (m.end1 () - it1, e ().end1 () - it1e));
Chris@16 1318 while (-- size1 >= 0) {
Chris@16 1319 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1320 typename M::iterator2 it2 (it1.begin ());
Chris@16 1321 typename E::iterator2 it2e (it1e.begin ());
Chris@16 1322 difference_type size2 (BOOST_UBLAS_SAME (it1.end () - it2, it1e.end () - it2e));
Chris@16 1323 #else
Chris@16 1324 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 1325 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 1326 difference_type size2 (BOOST_UBLAS_SAME (end (it1, iterator1_tag ()) - it2, end (it1e, iterator1_tag ()) - it2e));
Chris@16 1327 #endif
Chris@16 1328 while (-- size2 >= 0)
Chris@16 1329 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
Chris@16 1330 ++ it1, ++ it1e;
Chris@16 1331 }
Chris@16 1332 }
Chris@16 1333 // Packed (proxy) column major case
Chris@16 1334 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1335 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 1336 void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
Chris@16 1337 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
Chris@16 1338 // R unnecessary, make_conformant not required
Chris@16 1339 typedef typename M::difference_type difference_type;
Chris@16 1340 typename M::iterator2 it2 (m.begin2 ());
Chris@16 1341 typename E::iterator2 it2e (e ().begin2 ());
Chris@16 1342 difference_type size2 (BOOST_UBLAS_SAME (m.end2 () - it2, e ().end2 () - it2e));
Chris@16 1343 while (-- size2 >= 0) {
Chris@16 1344 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1345 typename M::iterator1 it1 (it2.begin ());
Chris@16 1346 typename E::iterator1 it1e (it2e.begin ());
Chris@16 1347 difference_type size1 (BOOST_UBLAS_SAME (it2.end () - it1, it2e.end () - it1e));
Chris@16 1348 #else
Chris@16 1349 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 1350 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 1351 difference_type size1 (BOOST_UBLAS_SAME (end (it2, iterator2_tag ()) - it1, end (it2e, iterator2_tag ()) - it1e));
Chris@16 1352 #endif
Chris@16 1353 while (-- size1 >= 0)
Chris@16 1354 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
Chris@16 1355 ++ it2, ++ it2e;
Chris@16 1356 }
Chris@16 1357 }
Chris@16 1358 // Sparse (proxy) row major case
Chris@16 1359 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1360 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 1361 void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
Chris@16 1362 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
Chris@16 1363 typedef R conformant_restrict_type;
Chris@16 1364 typedef typename M::size_type size_type;
Chris@16 1365 typedef typename M::difference_type difference_type;
Chris@16 1366 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 1367 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@16 1368
Chris@16 1369 detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
Chris@16 1370 // FIXME should be a seperate restriction for E
Chris@16 1371 detail::make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
Chris@16 1372
Chris@16 1373 typename M::iterator1 it1 (m.begin1 ());
Chris@16 1374 typename M::iterator1 it1_end (m.end1 ());
Chris@16 1375 typename E::iterator1 it1e (e ().begin1 ());
Chris@16 1376 typename E::iterator1 it1e_end (e ().end1 ());
Chris@16 1377 while (it1 != it1_end && it1e != it1e_end) {
Chris@16 1378 difference_type compare = it1.index1 () - it1e.index1 ();
Chris@16 1379 if (compare == 0) {
Chris@16 1380 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1381 typename M::iterator2 it2 (it1.begin ());
Chris@16 1382 typename M::iterator2 it2_end (it1.end ());
Chris@16 1383 typename E::iterator2 it2e (it1e.begin ());
Chris@16 1384 typename E::iterator2 it2e_end (it1e.end ());
Chris@16 1385 #else
Chris@16 1386 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 1387 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 1388 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 1389 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 1390 #endif
Chris@16 1391 if (it2 != it2_end && it2e != it2e_end) {
Chris@16 1392 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
Chris@16 1393 while (true) {
Chris@101 1394 difference_type compare2 = it2_index - it2e_index;
Chris@101 1395 if (compare2 == 0) {
Chris@16 1396 functor_type::apply (*it2, *it2e);
Chris@16 1397 ++ it2, ++ it2e;
Chris@16 1398 if (it2 != it2_end && it2e != it2e_end) {
Chris@16 1399 it2_index = it2.index2 ();
Chris@16 1400 it2e_index = it2e.index2 ();
Chris@16 1401 } else
Chris@16 1402 break;
Chris@101 1403 } else if (compare2 < 0) {
Chris@101 1404 increment (it2, it2_end, - compare2);
Chris@16 1405 if (it2 != it2_end)
Chris@16 1406 it2_index = it2.index2 ();
Chris@16 1407 else
Chris@16 1408 break;
Chris@101 1409 } else if (compare2 > 0) {
Chris@101 1410 increment (it2e, it2e_end, compare2);
Chris@16 1411 if (it2e != it2e_end)
Chris@16 1412 it2e_index = it2e.index2 ();
Chris@16 1413 else
Chris@16 1414 break;
Chris@16 1415 }
Chris@16 1416 }
Chris@16 1417 }
Chris@16 1418 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1419 increment (it2e, it2e_end);
Chris@16 1420 increment (it2, it2_end);
Chris@16 1421 #endif
Chris@16 1422 ++ it1, ++ it1e;
Chris@16 1423 } else if (compare < 0) {
Chris@16 1424 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1425 while (it1.index1 () < it1e.index1 ()) {
Chris@16 1426 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1427 typename M::iterator2 it2 (it1.begin ());
Chris@16 1428 typename M::iterator2 it2_end (it1.end ());
Chris@16 1429 #else
Chris@16 1430 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 1431 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 1432 #endif
Chris@16 1433 increment (it2, it2_end);
Chris@16 1434 ++ it1;
Chris@16 1435 }
Chris@16 1436 #else
Chris@16 1437 increment (it1, it1_end, - compare);
Chris@16 1438 #endif
Chris@16 1439 } else if (compare > 0) {
Chris@16 1440 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1441 while (it1e.index1 () < it1.index1 ()) {
Chris@16 1442 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1443 typename E::iterator2 it2e (it1e.begin ());
Chris@16 1444 typename E::iterator2 it2e_end (it1e.end ());
Chris@16 1445 #else
Chris@16 1446 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 1447 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 1448 #endif
Chris@16 1449 increment (it2e, it2e_end);
Chris@16 1450 ++ it1e;
Chris@16 1451 }
Chris@16 1452 #else
Chris@16 1453 increment (it1e, it1e_end, compare);
Chris@16 1454 #endif
Chris@16 1455 }
Chris@16 1456 }
Chris@16 1457 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1458 while (it1e != it1e_end) {
Chris@16 1459 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1460 typename E::iterator2 it2e (it1e.begin ());
Chris@16 1461 typename E::iterator2 it2e_end (it1e.end ());
Chris@16 1462 #else
Chris@16 1463 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
Chris@16 1464 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
Chris@16 1465 #endif
Chris@16 1466 increment (it2e, it2e_end);
Chris@16 1467 ++ it1e;
Chris@16 1468 }
Chris@16 1469 while (it1 != it1_end) {
Chris@16 1470 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1471 typename M::iterator2 it2 (it1.begin ());
Chris@16 1472 typename M::iterator2 it2_end (it1.end ());
Chris@16 1473 #else
Chris@16 1474 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
Chris@16 1475 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
Chris@16 1476 #endif
Chris@16 1477 increment (it2, it2_end);
Chris@16 1478 ++ it1;
Chris@16 1479 }
Chris@16 1480 #endif
Chris@16 1481 }
Chris@16 1482 // Sparse (proxy) column major case
Chris@16 1483 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1484 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
Chris@16 1485 void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
Chris@16 1486 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
Chris@16 1487 typedef R conformant_restrict_type;
Chris@16 1488 typedef typename M::size_type size_type;
Chris@16 1489 typedef typename M::difference_type difference_type;
Chris@101 1490
Chris@16 1491 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
Chris@16 1492 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
Chris@16 1493
Chris@16 1494 detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
Chris@16 1495 // FIXME should be a seperate restriction for E
Chris@16 1496 detail::make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
Chris@16 1497
Chris@16 1498 typename M::iterator2 it2 (m.begin2 ());
Chris@16 1499 typename M::iterator2 it2_end (m.end2 ());
Chris@16 1500 typename E::iterator2 it2e (e ().begin2 ());
Chris@16 1501 typename E::iterator2 it2e_end (e ().end2 ());
Chris@16 1502 while (it2 != it2_end && it2e != it2e_end) {
Chris@16 1503 difference_type compare = it2.index2 () - it2e.index2 ();
Chris@16 1504 if (compare == 0) {
Chris@16 1505 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1506 typename M::iterator1 it1 (it2.begin ());
Chris@16 1507 typename M::iterator1 it1_end (it2.end ());
Chris@16 1508 typename E::iterator1 it1e (it2e.begin ());
Chris@16 1509 typename E::iterator1 it1e_end (it2e.end ());
Chris@16 1510 #else
Chris@16 1511 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 1512 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 1513 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 1514 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 1515 #endif
Chris@16 1516 if (it1 != it1_end && it1e != it1e_end) {
Chris@16 1517 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
Chris@16 1518 while (true) {
Chris@101 1519 difference_type compare2 = it1_index - it1e_index;
Chris@101 1520 if (compare2 == 0) {
Chris@16 1521 functor_type::apply (*it1, *it1e);
Chris@16 1522 ++ it1, ++ it1e;
Chris@16 1523 if (it1 != it1_end && it1e != it1e_end) {
Chris@16 1524 it1_index = it1.index1 ();
Chris@16 1525 it1e_index = it1e.index1 ();
Chris@16 1526 } else
Chris@16 1527 break;
Chris@101 1528 } else if (compare2 < 0) {
Chris@101 1529 increment (it1, it1_end, - compare2);
Chris@16 1530 if (it1 != it1_end)
Chris@16 1531 it1_index = it1.index1 ();
Chris@16 1532 else
Chris@16 1533 break;
Chris@101 1534 } else if (compare2 > 0) {
Chris@101 1535 increment (it1e, it1e_end, compare2);
Chris@16 1536 if (it1e != it1e_end)
Chris@16 1537 it1e_index = it1e.index1 ();
Chris@16 1538 else
Chris@16 1539 break;
Chris@16 1540 }
Chris@16 1541 }
Chris@16 1542 }
Chris@16 1543 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1544 increment (it1e, it1e_end);
Chris@16 1545 increment (it1, it1_end);
Chris@16 1546 #endif
Chris@16 1547 ++ it2, ++ it2e;
Chris@16 1548 } else if (compare < 0) {
Chris@16 1549 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1550 while (it2.index2 () < it2e.index2 ()) {
Chris@16 1551 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1552 typename M::iterator1 it1 (it2.begin ());
Chris@16 1553 typename M::iterator1 it1_end (it2.end ());
Chris@16 1554 #else
Chris@16 1555 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 1556 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 1557 #endif
Chris@16 1558 increment (it1, it1_end);
Chris@16 1559 ++ it2;
Chris@16 1560 }
Chris@16 1561 #else
Chris@16 1562 increment (it2, it2_end, - compare);
Chris@16 1563 #endif
Chris@16 1564 } else if (compare > 0) {
Chris@16 1565 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1566 while (it2e.index2 () < it2.index2 ()) {
Chris@16 1567 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1568 typename E::iterator1 it1e (it2e.begin ());
Chris@16 1569 typename E::iterator1 it1e_end (it2e.end ());
Chris@16 1570 #else
Chris@16 1571 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 1572 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 1573 #endif
Chris@16 1574 increment (it1e, it1e_end);
Chris@16 1575 ++ it2e;
Chris@16 1576 }
Chris@16 1577 #else
Chris@16 1578 increment (it2e, it2e_end, compare);
Chris@16 1579 #endif
Chris@16 1580 }
Chris@16 1581 }
Chris@16 1582 #if BOOST_UBLAS_TYPE_CHECK
Chris@16 1583 while (it2e != it2e_end) {
Chris@16 1584 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1585 typename E::iterator1 it1e (it2e.begin ());
Chris@16 1586 typename E::iterator1 it1e_end (it2e.end ());
Chris@16 1587 #else
Chris@16 1588 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
Chris@16 1589 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
Chris@16 1590 #endif
Chris@16 1591 increment (it1e, it1e_end);
Chris@16 1592 ++ it2e;
Chris@16 1593 }
Chris@16 1594 while (it2 != it2_end) {
Chris@16 1595 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1596 typename M::iterator1 it1 (it2.begin ());
Chris@16 1597 typename M::iterator1 it1_end (it2.end ());
Chris@16 1598 #else
Chris@16 1599 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
Chris@16 1600 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
Chris@16 1601 #endif
Chris@16 1602 increment (it1, it1_end);
Chris@16 1603 ++ it2;
Chris@16 1604 }
Chris@16 1605 #endif
Chris@16 1606 }
Chris@16 1607
Chris@16 1608 // Dispatcher
Chris@16 1609 template<template <class T1, class T2> class F, class M, class E>
Chris@16 1610 BOOST_UBLAS_INLINE
Chris@16 1611 void matrix_swap (M &m, matrix_expression<E> &e) {
Chris@16 1612 typedef typename matrix_swap_traits<typename M::storage_category,
Chris@16 1613 typename E::const_iterator1::iterator_category,
Chris@16 1614 typename E::const_iterator2::iterator_category>::storage_category storage_category;
Chris@16 1615 // give preference to matrix M's orientation if known
Chris@16 1616 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
Chris@16 1617 typename E::orientation_category ,
Chris@16 1618 typename M::orientation_category >::type orientation_category;
Chris@16 1619 typedef basic_full<typename M::size_type> unrestricted;
Chris@16 1620 matrix_swap<F, unrestricted> (m, e, storage_category (), orientation_category ());
Chris@16 1621 }
Chris@16 1622 template<template <class T1, class T2> class F, class R, class M, class E>
Chris@16 1623 BOOST_UBLAS_INLINE
Chris@16 1624 void matrix_swap (M &m, matrix_expression<E> &e) {
Chris@16 1625 typedef R conformant_restrict_type;
Chris@16 1626 typedef typename matrix_swap_traits<typename M::storage_category,
Chris@16 1627 typename E::const_iterator1::iterator_category,
Chris@16 1628 typename E::const_iterator2::iterator_category>::storage_category storage_category;
Chris@16 1629 // give preference to matrix M's orientation if known
Chris@16 1630 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
Chris@16 1631 typename E::orientation_category ,
Chris@16 1632 typename M::orientation_category >::type orientation_category;
Chris@16 1633 matrix_swap<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
Chris@16 1634 }
Chris@16 1635
Chris@16 1636 }}}
Chris@16 1637
Chris@16 1638 #endif