]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // Copyright (c) 2010 Athanasios Iliopoulos | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0. (See | |
5 | // accompanying file LICENSE_1_0.txt or copy at | |
6 | // http://www.boost.org/LICENSE_1_0.txt) | |
7 | // | |
8 | ||
9 | #ifndef ASSIGNMENT_HPP | |
10 | #define ASSIGNMENT_HPP | |
11 | #include <boost/numeric/ublas/vector_expression.hpp> | |
12 | #include <boost/numeric/ublas/matrix_expression.hpp> | |
13 | ||
14 | /*! \file assignment.hpp | |
15 | \brief uBlas assignment operator <<=. | |
16 | */ | |
17 | ||
18 | namespace boost { namespace numeric { namespace ublas { | |
19 | ||
20 | /** \brief A CRTP and Barton-Nackman trick index manipulator wrapper class. | |
21 | * | |
22 | * This class is not meant to be used directly. | |
23 | */ | |
24 | template <class TV> | |
25 | class index_manipulator { | |
26 | public: | |
27 | typedef TV type; | |
28 | BOOST_UBLAS_INLINE | |
29 | const type &operator () () const { | |
30 | return *static_cast<const type *> (this); | |
31 | } | |
32 | BOOST_UBLAS_INLINE | |
33 | type &operator () () { | |
34 | return *static_cast<type *> (this); | |
35 | } | |
36 | }; | |
37 | ||
38 | /** \brief A move_to vector index manipulator. | |
39 | * | |
40 | * When member function \c manip is called the referenced | |
41 | * index will be set to the manipulators' index. | |
42 | * | |
43 | * \sa move_to(T i) | |
44 | */ | |
45 | template <typename T> | |
46 | class vector_move_to_manip: public index_manipulator<vector_move_to_manip<T> > { | |
47 | public: | |
48 | BOOST_UBLAS_INLINE | |
49 | vector_move_to_manip(const T &k): i(k) { } | |
50 | ||
51 | template <typename V> | |
52 | BOOST_UBLAS_INLINE | |
53 | void manip(V &k) const { k=i; } | |
54 | private: | |
55 | T i; | |
56 | }; | |
57 | ||
58 | /** \brief An object generator that returns a move_to vector index manipulator | |
59 | * | |
60 | * \param i The element number the manipulator will move to when \c manip member function is called | |
61 | * \return A move_to vector manipulator | |
62 | * | |
63 | * Example usage: | |
64 | * \code | |
65 | * vector<double> a(6, 0); | |
66 | * a <<= 1, 2, move_to(5), 3; | |
67 | * \endcode | |
68 | * will result in: | |
69 | * \code | |
70 | * 1 2 0 0 0 3 | |
71 | * \endcode | |
72 | * | |
73 | * \tparam T Size type | |
74 | * \sa move_to() | |
75 | */ | |
76 | template <typename T> | |
77 | BOOST_UBLAS_INLINE vector_move_to_manip<T> move_to(T i) { | |
78 | return vector_move_to_manip<T>(i); | |
79 | } | |
80 | ||
81 | /** \brief A static move to vector manipulator. | |
82 | * | |
83 | * When member function \c manip is called the referenced | |
84 | * index will be set to the manipulators' index | |
85 | * | |
86 | * \sa move_to(T i) and move_to() | |
87 | */ | |
88 | template <std::size_t I> | |
89 | class static_vector_move_to_manip: public index_manipulator<static_vector_move_to_manip<I> > { | |
90 | public: | |
91 | template <typename V> | |
92 | BOOST_UBLAS_INLINE | |
93 | void manip(V &k) const { k=I; } | |
94 | }; | |
95 | ||
96 | /** \brief An object generator that returns a static move_to vector index manipulator. | |
97 | * | |
98 | * Typically faster than the dynamic version, but can be used only when the | |
99 | * values are known at compile time. | |
100 | * | |
101 | * \return A static move_to vector manipulator | |
102 | * | |
103 | * Example usage: | |
104 | * \code | |
105 | * vector<double> a(6, 0); | |
106 | * a <<= 1, 2, move_to<5>(), 3; | |
107 | * \endcode | |
108 | * will result in: | |
109 | * \code | |
110 | * 1 2 0 0 0 3 | |
111 | * \endcode | |
112 | * | |
113 | * \tparam I The number of elements the manipulator will traverse the index when \c manip function is called | |
114 | */ | |
115 | template <std::size_t I> | |
116 | BOOST_UBLAS_INLINE static_vector_move_to_manip<I> move_to() { | |
117 | return static_vector_move_to_manip<I>(); | |
118 | } | |
119 | ||
120 | /** \brief A move vector index manipulator. | |
121 | * | |
122 | * When member function traverse is called the manipulators' | |
123 | * index will be added to the referenced index. | |
124 | * | |
125 | * \see move(T i) | |
126 | */ | |
127 | template <typename T> | |
128 | class vector_move_manip: public index_manipulator<vector_move_manip<T> > { | |
129 | public: | |
130 | BOOST_UBLAS_INLINE | |
131 | vector_move_manip(const T &k): i(k) { } | |
132 | ||
133 | template <typename V> | |
134 | BOOST_UBLAS_INLINE void manip(V &k) const { k+=i; } | |
135 | private: | |
136 | T i; | |
137 | }; | |
138 | ||
139 | /** | |
140 | * \brief An object generator that returns a move vector index manipulator | |
141 | * | |
142 | * \tparam T Size type | |
143 | * \param i The number of elements the manipulator will traverse the index when \c manip | |
144 | * member function is called. Negative values can be used. | |
145 | * \return A move vector manipulator | |
146 | * | |
147 | * Example usage: | |
148 | * \code | |
149 | * vector<double> a(6, 0); | |
150 | * a <<= 1, 2, move(3), 3; | |
151 | * \endcode | |
152 | * will result in: | |
153 | * \code | |
154 | * 1 2 0 0 0 3 | |
155 | * \endcode | |
156 | * | |
157 | */ | |
158 | template <typename T> | |
159 | BOOST_UBLAS_INLINE vector_move_manip<T> move(T i) { | |
160 | return vector_move_manip<T>(i); | |
161 | } | |
162 | ||
163 | /** | |
164 | * \brief A static move vector manipulator | |
165 | * | |
166 | * When member function \c manip is called the manipulators | |
167 | * index will be added to the referenced index | |
168 | * | |
169 | * \sa move() | |
170 | * | |
171 | * \todo Doxygen has some problems with similar template functions. Correct that. | |
172 | */ | |
173 | template <std::ptrdiff_t I> | |
174 | class static_vector_move_manip: public index_manipulator<static_vector_move_manip<I> > { | |
175 | public: | |
176 | template <typename V> | |
177 | BOOST_UBLAS_INLINE void manip(V &k) const { k+=I; } | |
178 | }; | |
179 | ||
180 | /** | |
181 | * \brief An object generator that returns a static move vector index manipulator. | |
182 | * | |
183 | * Typically faster than the dynamic version, but can be used only when the | |
184 | * values are known at compile time. | |
185 | * \tparam I The Number of elements the manipulator will traverse the index when \c manip | |
186 | * function is called.Negative values can be used. | |
187 | * \return A static move vector manipulator | |
188 | * | |
189 | * Example usage: | |
190 | * \code | |
191 | * vector<double> a(6, 0); | |
192 | * a <<= 1, 2, move<3>(), 3; | |
193 | * \endcode | |
194 | * will result in: | |
195 | * \code | |
196 | * 1 2 0 0 0 3 | |
197 | * \endcode | |
198 | * | |
199 | * \todo Doxygen has some problems with similar template functions. Correct that. | |
200 | */ | |
201 | template <std::ptrdiff_t I> | |
202 | static_vector_move_manip<I> move() { | |
203 | return static_vector_move_manip<I>(); | |
204 | } | |
205 | ||
206 | /** | |
207 | * \brief A move_to matrix manipulator | |
208 | * | |
209 | * When member function \c manip is called the referenced | |
210 | * index will be set to the manipulators' index | |
211 | * | |
212 | * \sa move_to(T i, T j) | |
213 | * | |
214 | * \todo Doxygen has some problems with similar template functions. Correct that. | |
215 | */ | |
216 | template <typename T> | |
217 | class matrix_move_to_manip: public index_manipulator<matrix_move_to_manip<T> > { | |
218 | public: | |
219 | BOOST_UBLAS_INLINE | |
220 | matrix_move_to_manip(T k, T l): i(k), j(l) { } | |
221 | ||
222 | template <typename V1, typename V2> | |
223 | BOOST_UBLAS_INLINE | |
224 | void manip(V1 &k, V2 &l) const { | |
225 | k=i; | |
226 | l=j; | |
227 | } | |
228 | private: | |
229 | T i, j; | |
230 | }; | |
231 | ||
232 | /** | |
233 | * \brief An object generator that returns a "move_to" matrix index manipulator | |
234 | * | |
235 | * \tparam size type | |
236 | * \param i The row number the manipulator will move to when \c manip | |
237 | * member function is called | |
238 | * \param j The column number the manipulator will move to when \c manip | |
239 | * member function is called | |
240 | * \return A move matrix manipulator | |
241 | * | |
242 | * Example usage: | |
243 | * \code: | |
244 | * matrix<double> A(3, 3, 0); | |
245 | * A <<= 1, 2, move_to(A.size1()-1, A.size1()-1), 3; | |
246 | * \endcode | |
247 | * will result in: | |
248 | * \code | |
249 | * 1 2 0 | |
250 | * 0 0 0 | |
251 | * 0 0 3 | |
252 | * \endcode | |
253 | * \sa move_to(T i, T j) and static_matrix_move_to_manip | |
254 | * | |
255 | * \todo Doxygen has some problems with similar template functions. Correct that. | |
256 | */ | |
257 | template <typename T> | |
258 | BOOST_UBLAS_INLINE matrix_move_to_manip<T> move_to(T i, T j) { | |
259 | return matrix_move_to_manip<T>(i, j); | |
260 | } | |
261 | ||
262 | ||
263 | /** | |
264 | * \brief A static move_to matrix manipulator | |
265 | * When member function traverse is called the referenced | |
266 | * index will be set to the manipulators' index | |
267 | * | |
268 | * \sa move_to() | |
269 | * | |
270 | * \todo Doxygen has some problems with similar template functions. Correct that. | |
271 | */ | |
272 | template <std::size_t I,std::size_t J> | |
273 | class static_matrix_move_to_manip: public index_manipulator<static_matrix_move_to_manip<I, J> > { | |
274 | public: | |
275 | template <typename V, typename K> | |
276 | BOOST_UBLAS_INLINE | |
277 | void manip(V &k, K &l) const { | |
278 | k=I; | |
279 | l=J; | |
280 | } | |
281 | }; | |
282 | ||
283 | /** | |
284 | * \brief An object generator that returns a static move_to matrix index manipulator. | |
285 | * | |
286 | * Typically faster than the dynamic version, but can be used only when the | |
287 | * values are known at compile time. | |
288 | * \tparam I The row number the manipulator will set the matrix assigner index to. | |
289 | * \tparam J The column number the manipulator will set the matrix assigner index to. | |
290 | * \return A static move_to matrix manipulator | |
291 | * | |
292 | * Example usage: | |
293 | * \code: | |
294 | * matrix<double> A(3, 3, 0); | |
295 | * A <<= 1, 2, move_to<2,2>, 3; | |
296 | * \endcode | |
297 | * will result in: | |
298 | * \code | |
299 | * 1 2 0 | |
300 | * 0 0 0 | |
301 | * 0 0 3 | |
302 | * \endcode | |
303 | * \sa move_to(T i, T j) and static_matrix_move_to_manip | |
304 | */ | |
305 | template <std::size_t I, std::size_t J> | |
306 | BOOST_UBLAS_INLINE static_matrix_move_to_manip<I, J> move_to() { | |
307 | return static_matrix_move_to_manip<I, J>(); | |
308 | } | |
309 | ||
310 | /** | |
311 | * \brief A move matrix index manipulator. | |
312 | * | |
313 | * When member function \c manip is called the manipulator's | |
314 | * index will be added to the referenced' index. | |
315 | * | |
316 | * \sa move(T i, T j) | |
317 | */ | |
318 | template <typename T> | |
319 | class matrix_move_manip: public index_manipulator<matrix_move_manip<T> > { | |
320 | public: | |
321 | BOOST_UBLAS_INLINE | |
322 | matrix_move_manip(T k, T l): i(k), j(l) { } | |
323 | ||
324 | template <typename V, typename K> | |
325 | BOOST_UBLAS_INLINE | |
326 | void manip(V &k, K &l) const { | |
327 | k+=i; | |
328 | l+=j; | |
329 | } | |
330 | private: | |
331 | T i, j; | |
332 | }; | |
333 | ||
334 | /** | |
335 | * \brief An object generator that returns a move matrix index manipulator | |
336 | * | |
337 | * \tparam size type | |
338 | * \param i The number of rows the manipulator will traverse the index when "manip" | |
339 | * member function is called | |
340 | * \param j The number of columns the manipulator will traverse the index when "manip" | |
341 | * member function is called | |
342 | * \return A move matrix manipulator | |
343 | * | |
344 | * Example: | |
345 | * \code: | |
346 | * matrix<double> A(3, 3, 0); | |
347 | * A <<= 1, 2, move(1,0), | |
348 | * 3,; | |
349 | * \endcode | |
350 | * will result in: | |
351 | * \code | |
352 | * 1 2 0 | |
353 | * 0 0 3 | |
354 | * 0 0 0 | |
355 | * \endcode | |
356 | */ | |
357 | template <typename T> | |
358 | BOOST_UBLAS_INLINE matrix_move_manip<T> move(T i, T j) { | |
359 | return matrix_move_manip<T>(i, j); | |
360 | } | |
361 | ||
362 | /** | |
363 | * \brief A static move matrix index manipulator. | |
364 | * | |
365 | * When member function traverse is called the manipulator's | |
366 | * index will be added to the referenced' index. | |
367 | * | |
368 | * \sa move() | |
369 | * | |
370 | * \todo Doxygen has some problems with similar template functions. Correct that. | |
371 | */ | |
372 | template <std::ptrdiff_t I, std::ptrdiff_t J> | |
373 | class static_matrix_move_manip: public index_manipulator<static_matrix_move_manip<I, J> > { | |
374 | public: | |
375 | template <typename V, typename K> | |
376 | BOOST_UBLAS_INLINE | |
377 | void manip(V &k, K &l) const { | |
378 | k+=I; | |
379 | l+=J; | |
380 | } | |
381 | }; | |
382 | ||
383 | /** | |
384 | * \brief An object generator that returns a static "move" matrix index manipulator. | |
385 | * | |
386 | * Typically faster than the dynamic version, but can be used only when the | |
387 | * values are known at compile time. Negative values can be used. | |
388 | * \tparam I The number of rows the manipulator will trasverse the matrix assigner index. | |
389 | * \tparam J The number of columns the manipulator will trasverse the matrix assigner index. | |
390 | * \tparam size type | |
391 | * \return A static move matrix manipulator | |
392 | * | |
393 | * Example: | |
394 | * \code: | |
395 | * matrix<double> A(3, 3, 0); | |
396 | * A <<= 1, 2, move<1,0>(), | |
397 | * 3,; | |
398 | * \endcode | |
399 | * will result in: | |
400 | * \code | |
401 | * 1 2 0 | |
402 | * 0 0 3 | |
403 | * 0 0 0 | |
404 | * \endcode | |
405 | * | |
406 | * \sa move_to() | |
407 | * | |
408 | * \todo Doxygen has some problems with similar template functions. Correct that. | |
409 | */ | |
410 | template <std::ptrdiff_t I, std::ptrdiff_t J> | |
411 | BOOST_UBLAS_INLINE static_matrix_move_manip<I, J> move() { | |
412 | return static_matrix_move_manip<I, J>(); | |
413 | } | |
414 | ||
415 | /** | |
416 | * \brief A begining of row manipulator | |
417 | * | |
418 | * When member function \c manip is called the referenced | |
419 | * index will be be set to the begining of the row (i.e. column = 0) | |
420 | * | |
421 | * \sa begin1() | |
422 | */ | |
423 | class begin1_manip: public index_manipulator<begin1_manip > { | |
424 | public: | |
425 | template <typename V, typename K> | |
426 | BOOST_UBLAS_INLINE | |
427 | void manip(V & k, K &/*l*/) const { | |
428 | k=0; | |
429 | } | |
430 | }; | |
431 | ||
432 | /** | |
433 | * \brief An object generator that returns a begin1 manipulator. | |
434 | * | |
435 | * The resulted manipulator will traverse the index to the begining | |
436 | * of the current column when its' \c manip member function is called. | |
437 | * | |
438 | * \return A begin1 matrix index manipulator | |
439 | * | |
440 | * Example usage: | |
441 | * \code: | |
442 | * matrix<double> A(3, 3, 0); | |
443 | * A <<= 1, 2, next_row(), | |
444 | * 3, 4, begin1(), 1; | |
445 | * \endcode | |
446 | * will result in: | |
447 | * \code | |
448 | * 1 2 1 | |
449 | * 3 4 0 | |
450 | * 0 0 0 | |
451 | * \endcode | |
452 | * \sa begin2() | |
453 | */ | |
454 | inline begin1_manip begin1() { | |
455 | return begin1_manip(); | |
456 | } | |
457 | ||
458 | /** | |
459 | * \brief A begining of column manipulator | |
460 | * | |
461 | * When member function \c manip is called the referenced | |
462 | * index will be be set to the begining of the column (i.e. row = 0). | |
463 | * | |
464 | * | |
465 | * \sa begin2() | |
466 | */ | |
467 | class begin2_manip: public index_manipulator<begin2_manip > { | |
468 | public: | |
469 | template <typename V, typename K> | |
470 | BOOST_UBLAS_INLINE | |
471 | void manip(V &/*k*/, K &l) const { | |
472 | l=0; | |
473 | } | |
474 | }; | |
475 | ||
476 | /** | |
477 | * \brief An object generator that returns a begin2 manipulator to be used to traverse a matrix. | |
478 | * | |
479 | * The resulted manipulator will traverse the index to the begining | |
480 | * of the current row when its' \c manip member function is called. | |
481 | * | |
482 | * \return A begin2 matrix manipulator | |
483 | * | |
484 | * Example: | |
485 | * \code: | |
486 | * matrix<double> A(3, 3, 0); | |
487 | * A <<= 1, 2, move<1,0>(), | |
488 | * 3, begin2(), 1; | |
489 | * \endcode | |
490 | * will result in: | |
491 | * \code | |
492 | * 1 2 0 | |
493 | * 1 0 3 | |
494 | * 0 0 0 | |
495 | * \endcode | |
496 | * \sa begin1() begin2_manip | |
497 | */ | |
498 | inline begin2_manip begin2() { | |
499 | return begin2_manip(); | |
500 | } | |
501 | ||
502 | ||
503 | /** | |
504 | * \brief A next row matrix manipulator. | |
505 | * | |
506 | * When member function traverse is called the referenced | |
507 | * index will be traveresed to the begining of next row. | |
508 | * | |
509 | * \sa next_row() | |
510 | */ | |
511 | class next_row_manip: public index_manipulator<next_row_manip> { | |
512 | public: | |
513 | template <typename V, typename K> | |
514 | BOOST_UBLAS_INLINE | |
515 | void manip(V &k, K &l) const { | |
516 | k++; | |
517 | l=0; | |
518 | } | |
519 | }; | |
520 | ||
521 | /** | |
522 | * \brief An object generator that returns a next_row manipulator. | |
523 | * | |
524 | * The resulted manipulator will traverse the index to the begining | |
525 | * of the next row when it's manip member function is called. | |
526 | * | |
527 | * \return A next_row matrix manipulator. | |
528 | * | |
529 | * Example: | |
530 | * \code: | |
531 | * matrix<double> A(3, 3, 0); | |
532 | * A <<= 1, 2, next_row(), | |
533 | * 3, 4; | |
534 | * \endcode | |
535 | * will result in: | |
536 | * \code | |
537 | * 1 2 0 | |
538 | * 3 4 0 | |
539 | * 0 0 0 | |
540 | * \endcode | |
541 | * \sa next_column() | |
542 | */ | |
543 | inline next_row_manip next_row() { | |
544 | return next_row_manip(); | |
545 | } | |
546 | ||
547 | /** | |
548 | * \brief A next column matrix manipulator. | |
549 | * | |
550 | * When member function traverse is called the referenced | |
551 | * index will be traveresed to the begining of next column. | |
552 | * | |
553 | * \sa next_column() | |
554 | */ | |
555 | class next_column_manip: public index_manipulator<next_column_manip> { | |
556 | public: | |
557 | template <typename V, typename K> | |
558 | BOOST_UBLAS_INLINE | |
559 | void manip(V &k, K &l) const { | |
560 | k=0; | |
561 | l++; | |
562 | } | |
563 | }; | |
564 | ||
565 | /** | |
566 | * \brief An object generator that returns a next_row manipulator. | |
567 | * | |
568 | * The resulted manipulator will traverse the index to the begining | |
569 | * of the next column when it's manip member function is called. | |
570 | * | |
571 | * \return A next_column matrix manipulator. | |
572 | * | |
573 | * Example: | |
574 | * \code: | |
575 | * matrix<double> A(3, 3, 0); | |
576 | * A <<= 1, 2, 0, | |
577 | * 3, next_column(), 4; | |
578 | * \endcode | |
579 | * will result in: | |
580 | * \code | |
581 | * 1 2 4 | |
582 | * 3 0 0 | |
583 | * 0 0 0 | |
584 | * \endcode | |
585 | * | |
586 | */ | |
587 | inline next_column_manip next_column() { | |
588 | return next_column_manip(); | |
589 | } | |
590 | ||
591 | /** | |
592 | * \brief A wrapper for fill policy classes | |
593 | * | |
594 | */ | |
595 | template <class T> | |
596 | class fill_policy_wrapper { | |
597 | public: | |
598 | typedef T type; | |
599 | }; | |
600 | ||
601 | // Collection of the fill policies | |
602 | namespace fill_policy { | |
603 | ||
604 | /** | |
605 | * \brief An index assign policy | |
606 | * | |
607 | * This policy is used to for the simplified ublas assign through | |
608 | * normal indexing. | |
609 | * | |
610 | * | |
611 | */ | |
612 | class index_assign :public fill_policy_wrapper<index_assign> { | |
613 | public: | |
614 | template <class T, typename S, typename V> | |
615 | BOOST_UBLAS_INLINE | |
616 | static void apply(T &e, const S &i, const V &v) { | |
617 | e()(i) = v; | |
618 | } | |
619 | template <class T, typename S, typename V> | |
620 | BOOST_UBLAS_INLINE | |
621 | static void apply(T &e, const S &i, const S &j, const V &v) { | |
622 | e()(i, j) = v; | |
623 | } | |
624 | }; | |
625 | ||
626 | /** | |
627 | * \brief An index plus assign policy | |
628 | * | |
629 | * This policy is used when the assignment is desired to be followed | |
630 | * by an addition. | |
631 | * | |
632 | * | |
633 | */ | |
634 | class index_plus_assign :public fill_policy_wrapper<index_plus_assign> { | |
635 | public: | |
636 | template <class T, typename S, typename V> | |
637 | BOOST_UBLAS_INLINE | |
638 | static void apply(T &e, const S &i, const V &v) { | |
639 | e()(i) += v; | |
640 | } | |
641 | template <class T, typename S, typename V> | |
642 | BOOST_UBLAS_INLINE | |
643 | static void apply(T &e, const S &i, const S &j, const V &v) { | |
644 | e()(i, j) += v; | |
645 | } | |
646 | }; | |
647 | ||
648 | /** | |
649 | * \brief An index minus assign policy | |
650 | * | |
651 | * This policy is used when the assignment is desired to be followed | |
652 | * by a substraction. | |
653 | * | |
654 | * | |
655 | */ | |
656 | class index_minus_assign :public fill_policy_wrapper<index_minus_assign> { | |
657 | public: | |
658 | template <class T, typename S, typename V> | |
659 | BOOST_UBLAS_INLINE | |
660 | static void apply(T &e, const S &i, const V &v) { | |
661 | e()(i) -= v; | |
662 | } | |
663 | template <class T, typename S, typename V> | |
664 | BOOST_UBLAS_INLINE | |
665 | static void apply(T &e, const S &i, const S &j, const V &v) { | |
666 | e()(i, j) -= v; | |
667 | } | |
668 | }; | |
669 | ||
670 | /** | |
671 | * \brief The sparse push_back fill policy. | |
672 | * | |
673 | * This policy is adequate for sparse types, when fast filling is required, where indexing | |
674 | * assign is pretty slow. | |
675 | ||
676 | * It is important to note that push_back assign cannot be used to add elements before elements | |
677 | * already existing in a sparse container. To achieve that please use the sparse_insert fill policy. | |
678 | */ | |
679 | class sparse_push_back :public fill_policy_wrapper<sparse_push_back > { | |
680 | public: | |
681 | template <class T, class S, class V> | |
682 | BOOST_UBLAS_INLINE | |
683 | static void apply(T &e, const S &i, const V &v) { | |
684 | e().push_back(i, v); | |
685 | } | |
686 | template <class T, class S, class V> | |
687 | BOOST_UBLAS_INLINE | |
688 | static void apply(T &e, const S &i, const S &j, const V &v) { | |
689 | e().push_back(i,j, v); | |
690 | } | |
691 | }; | |
692 | ||
693 | /** | |
694 | * \brief The sparse insert fill policy. | |
695 | * | |
696 | * This policy is adequate for sparse types, when fast filling is required, where indexing | |
697 | * assign is pretty slow. It is slower than sparse_push_back fill policy, but it can be used to | |
698 | * insert elements anywhere inside the container. | |
699 | */ | |
700 | class sparse_insert :public fill_policy_wrapper<sparse_insert> { | |
701 | public: | |
702 | template <class T, class S, class V> | |
703 | BOOST_UBLAS_INLINE | |
704 | static void apply(T &e, const S &i, const V &v) { | |
705 | e().insert_element(i, v); | |
706 | } | |
707 | template <class T, class S, class V> | |
708 | BOOST_UBLAS_INLINE | |
709 | static void apply(T &e, const S &i, const S &j, const V &v) { | |
710 | e().insert_element(i,j, v); | |
711 | } | |
712 | }; | |
713 | ||
714 | } | |
715 | ||
716 | /** \brief A wrapper for traverse policy classes | |
717 | * | |
718 | */ | |
719 | template <class T> | |
720 | class traverse_policy_wrapper { | |
721 | public: | |
722 | typedef T type; | |
723 | }; | |
724 | ||
725 | // Collection of the traverse policies | |
726 | namespace traverse_policy { | |
727 | ||
728 | ||
729 | /** | |
730 | * \brief The no wrap policy. | |
731 | * | |
732 | * The no wrap policy does not allow wrapping when assigning to a matrix | |
733 | */ | |
734 | struct no_wrap { | |
735 | /** | |
736 | * \brief Element wrap method | |
737 | */ | |
738 | template <class S1, class S2, class S3> | |
739 | BOOST_UBLAS_INLINE | |
740 | static void apply1(const S1 &/*s*/, S2 &/*i*/, S3 &/*j*/) { | |
741 | } | |
742 | ||
743 | /** | |
744 | * \brief Matrix block wrap method | |
745 | */ | |
746 | template <class S1, class S2, class S3> | |
747 | BOOST_UBLAS_INLINE | |
748 | static void apply2(const S1 &/*s1*/, const S1 &/*s2*/, S2 &/*i1*/, S3 &/*i2*/) { | |
749 | } | |
750 | }; | |
751 | ||
752 | /** | |
753 | * \brief The wrap policy. | |
754 | * | |
755 | * The wrap policy enables element wrapping when assigning to a matrix | |
756 | */ | |
757 | struct wrap { | |
758 | /** | |
759 | * \brief Element wrap method | |
760 | */ | |
761 | template <class S1, class S2, class S3> | |
762 | BOOST_UBLAS_INLINE | |
763 | static void apply1(const S1 &s, S2 &i1, S3 &i2) { | |
764 | if (i2>=s) { | |
765 | i1++; | |
766 | i2=0; | |
767 | } | |
768 | } | |
769 | ||
770 | /** | |
771 | * \brief Matrix block wrap method | |
772 | */ | |
773 | template <class S1, class S2, class S3> | |
774 | BOOST_UBLAS_INLINE | |
775 | static void apply2(const S1 &s1, const S1 &s2, S2 &i1, S3 &i2) { | |
776 | if (i2>=s2) i2=0; // Wrap to the next block | |
777 | else i1-=s1; // Move up (or right) one block | |
778 | } | |
779 | }; | |
780 | ||
781 | /** | |
782 | * \brief The row_by_row traverse policy | |
783 | * | |
784 | * This policy is used when the assignment is desired to happen | |
785 | * row_major wise for performance or other reasons. | |
786 | * | |
787 | * This is the default behaviour. To change it globally please define BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN | |
788 | * in the compilation options or in an adequate header file. | |
789 | * | |
790 | * Please see EXAMPLES_LINK for usage information. | |
791 | * | |
792 | * \todo Add examples link | |
793 | */ | |
794 | template <class Wrap = wrap> | |
795 | class by_row_policy :public traverse_policy_wrapper<by_row_policy<Wrap> > { | |
796 | public: | |
797 | template <typename S1, typename S2> | |
798 | BOOST_UBLAS_INLINE | |
799 | static void advance(S1 &/*i*/, S2 &j) { j++;} | |
800 | ||
801 | template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5> | |
802 | BOOST_UBLAS_INLINE | |
803 | static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &/*i0*/, const S3 &j0, S4 &k, S5 &l) { | |
804 | l++; j++; | |
805 | if (l>=e().size2()) { | |
806 | l=0; k++; j=j0; i++; | |
807 | // It is assumed that the iteration starts from 0 and progresses only using this function from within | |
808 | // an assigner object. | |
809 | // Otherwise (i.e. if it is called outside the assigner object) apply2 should have been | |
810 | // outside the if statement. | |
811 | if (k>=e().size1()) { | |
812 | j=j0+e().size2(); | |
813 | Wrap::apply2(e().size1(), me().size2(), i, j); | |
814 | return false; | |
815 | } | |
816 | } | |
817 | return true; | |
818 | } | |
819 | ||
820 | template <class E, typename S1, typename S2> | |
821 | BOOST_UBLAS_INLINE | |
822 | static void apply_wrap(const E& e, S1 &i, S2 &j) { | |
823 | Wrap::apply1(e().size2(), i, j); | |
824 | } | |
825 | }; | |
826 | ||
827 | /** | |
828 | * \brief The column_by_column traverse policy | |
829 | * | |
830 | * This policy is used when the assignment is desired to happen | |
831 | * column_major wise, for performance or other reasons. | |
832 | * | |
833 | * This is the NOT the default behaviour. To set this as the default define BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN | |
834 | * in the compilation options or in an adequate header file. | |
835 | * | |
836 | * Please see EXAMPLES_LINK for usage information. | |
837 | * | |
838 | * \todo Add examples link | |
839 | */ | |
840 | template <class Wrap = wrap> | |
841 | class by_column_policy :public traverse_policy_wrapper<by_column_policy<Wrap> > { | |
842 | public: | |
843 | template <typename S1, typename S2> | |
844 | BOOST_UBLAS_INLINE | |
845 | static void advance(S1 &i, S2 &/*j*/) { i++;} | |
846 | ||
847 | template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5> | |
848 | BOOST_UBLAS_INLINE | |
849 | static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &i0, const S3 &/*j0*/, S4 &k, S5 &l) { | |
850 | k++; i++; | |
851 | if (k>=e().size1()) { | |
852 | k=0; l++; i=i0; j++; | |
853 | // It is assumed that the iteration starts from 0 and progresses only using this function from within | |
854 | // an assigner object. | |
855 | // Otherwise (i.e. if it is called outside the assigner object) apply2 should have been | |
856 | // outside the if statement. | |
857 | if (l>=e().size2()) { | |
858 | i=i0+e().size1(); | |
859 | Wrap::apply2(e().size2(), me().size1(), j, i); | |
860 | return false; | |
861 | } | |
862 | } | |
863 | return true; | |
864 | } | |
865 | ||
866 | template <class E, typename S1, typename S2> | |
867 | BOOST_UBLAS_INLINE | |
868 | static void apply_wrap(const E& e, S1 &i, S2 &j) { | |
869 | Wrap::apply1(e().size1(), j, i); | |
870 | } | |
871 | }; | |
872 | } | |
873 | #ifndef BOOST_UBLAS_DEFAULT_NO_WRAP_POLICY | |
874 | typedef traverse_policy::wrap DEFAULT_WRAP_POLICY; | |
875 | #else | |
876 | typedef traverse_policy::no_wrap DEFAULT_WRAP_POLICY; | |
877 | #endif | |
878 | ||
879 | #ifndef BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN | |
880 | typedef traverse_policy::by_row_policy<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY; | |
881 | #else | |
882 | typedef traverse_policy::by_column<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY; | |
883 | #endif | |
884 | ||
885 | // Traverse policy namespace | |
886 | namespace traverse_policy { | |
887 | ||
888 | inline by_row_policy<DEFAULT_WRAP_POLICY> by_row() { | |
889 | return by_row_policy<DEFAULT_WRAP_POLICY>(); | |
890 | } | |
891 | ||
892 | inline by_row_policy<wrap> by_row_wrap() { | |
893 | return by_row_policy<wrap>(); | |
894 | } | |
895 | ||
896 | inline by_row_policy<no_wrap> by_row_no_wrap() { | |
897 | return by_row_policy<no_wrap>(); | |
898 | } | |
899 | ||
900 | inline by_column_policy<DEFAULT_WRAP_POLICY> by_column() { | |
901 | return by_column_policy<DEFAULT_WRAP_POLICY>(); | |
902 | } | |
903 | ||
904 | inline by_column_policy<wrap> by_column_wrap() { | |
905 | return by_column_policy<wrap>(); | |
906 | } | |
907 | ||
908 | inline by_column_policy<no_wrap> by_column_no_wrap() { | |
909 | return by_column_policy<no_wrap>(); | |
910 | } | |
911 | ||
912 | } | |
913 | ||
914 | /** | |
915 | * \brief An assigner object used to fill a vector using operator <<= and operator, (comma) | |
916 | * | |
917 | * This object is meant to be created by appropriate object generators. | |
918 | * Please see EXAMPLES_LINK for usage information. | |
919 | * | |
920 | * \todo Add examples link | |
921 | */ | |
922 | template <class E, class Fill_Policy = fill_policy::index_assign> | |
923 | class vector_expression_assigner { | |
924 | public: | |
925 | typedef typename E::expression_type::value_type value_type; | |
926 | typedef typename E::expression_type::size_type size_type; | |
927 | ||
928 | BOOST_UBLAS_INLINE | |
929 | vector_expression_assigner(E &e):ve(e), i(0) { | |
930 | } | |
931 | ||
932 | BOOST_UBLAS_INLINE | |
933 | vector_expression_assigner(size_type k, E &e):ve(e), i(k) { | |
934 | // Overloaded like that so it can be differentiated from (E, val). | |
935 | // Otherwise there would be an ambiquity when value_type == size_type. | |
936 | } | |
937 | ||
938 | BOOST_UBLAS_INLINE | |
939 | vector_expression_assigner(E &e, value_type val):ve(e), i(0) { | |
940 | operator,(val); | |
941 | } | |
942 | ||
943 | template <class AE> | |
944 | BOOST_UBLAS_INLINE | |
945 | vector_expression_assigner(E &e, const vector_expression<AE> &nve):ve(e), i(0) { | |
946 | operator,(nve); | |
947 | } | |
948 | ||
949 | template <typename T> | |
950 | BOOST_UBLAS_INLINE | |
951 | vector_expression_assigner(E &e, const index_manipulator<T> &ta):ve(e), i(0) { | |
952 | operator,(ta); | |
953 | } | |
954 | ||
955 | BOOST_UBLAS_INLINE | |
956 | vector_expression_assigner &operator, (const value_type& val) { | |
957 | apply(val); | |
958 | return *this; | |
959 | } | |
960 | ||
961 | template <class AE> | |
962 | BOOST_UBLAS_INLINE | |
963 | vector_expression_assigner &operator, (const vector_expression<AE> &nve) { | |
964 | for (typename AE::size_type k = 0; k!= nve().size(); k++) | |
965 | operator,(nve()(k)); | |
966 | return *this; | |
967 | } | |
968 | ||
969 | template <typename T> | |
970 | BOOST_UBLAS_INLINE | |
971 | vector_expression_assigner &operator, (const index_manipulator<T> &ta) { | |
972 | ta().manip(i); | |
973 | return *this; | |
974 | } | |
975 | ||
976 | template <class T> | |
977 | BOOST_UBLAS_INLINE | |
978 | vector_expression_assigner<E, T> operator, (fill_policy_wrapper<T>) const { | |
979 | return vector_expression_assigner<E, T>(i, ve); | |
980 | } | |
981 | ||
982 | private: | |
983 | BOOST_UBLAS_INLINE | |
984 | vector_expression_assigner &apply(const typename E::expression_type::value_type& val) { | |
985 | Fill_Policy::apply(ve, i++, val); | |
986 | return *this; | |
987 | } | |
988 | ||
989 | private: | |
990 | E &ve; | |
991 | size_type i; | |
992 | }; | |
993 | ||
994 | /* | |
995 | // The following static assigner is about 30% slower than the dynamic one, probably due to the recursive creation of assigner objects. | |
996 | // It remains commented here for future reference. | |
997 | ||
998 | template <class E, std::size_t I=0> | |
999 | class static_vector_expression_assigner { | |
1000 | public: | |
1001 | typedef typename E::expression_type::value_type value_type; | |
1002 | typedef typename E::expression_type::size_type size_type; | |
1003 | ||
1004 | BOOST_UBLAS_INLINE | |
1005 | static_vector_expression_assigner(E &e):ve(e) { | |
1006 | } | |
1007 | ||
1008 | BOOST_UBLAS_INLINE | |
1009 | static_vector_expression_assigner(E &e, value_type val):ve(e) { | |
1010 | operator,(val); | |
1011 | } | |
1012 | ||
1013 | BOOST_UBLAS_INLINE | |
1014 | static_vector_expression_assigner<E, I+1> operator, (const value_type& val) { | |
1015 | return apply(val); | |
1016 | } | |
1017 | ||
1018 | private: | |
1019 | BOOST_UBLAS_INLINE | |
1020 | static_vector_expression_assigner<E, I+1> apply(const typename E::expression_type::value_type& val) { | |
1021 | ve()(I)=val; | |
1022 | return static_vector_expression_assigner<E, I+1>(ve); | |
1023 | } | |
1024 | ||
1025 | private: | |
1026 | E &ve; | |
1027 | }; | |
1028 | ||
1029 | template <class E> | |
1030 | BOOST_UBLAS_INLINE | |
1031 | static_vector_expression_assigner<vector_expression<E>, 1 > test_static(vector_expression<E> &v, const typename E::value_type &val) { | |
1032 | v()(0)=val; | |
1033 | return static_vector_expression_assigner<vector_expression<E>, 1 >(v); | |
1034 | } | |
1035 | */ | |
1036 | ||
1037 | ||
1038 | /** | |
1039 | * \brief A vector_expression_assigner generator used with operator<<= for simple types | |
1040 | * | |
1041 | * Please see EXAMPLES_LINK for usage information. | |
1042 | * | |
1043 | * \todo Add examples link | |
1044 | */ | |
1045 | template <class E> | |
1046 | BOOST_UBLAS_INLINE | |
1047 | vector_expression_assigner<vector_expression<E> > operator<<=(vector_expression<E> &v, const typename E::value_type &val) { | |
1048 | return vector_expression_assigner<vector_expression<E> >(v,val); | |
1049 | } | |
1050 | ||
1051 | /** | |
1052 | * \brief ! A vector_expression_assigner generator used with operator<<= for vector expressions | |
1053 | * | |
1054 | * Please see EXAMPLES_LINK for usage information. | |
1055 | * | |
1056 | * \todo Add examples link | |
1057 | */ | |
1058 | template <class E1, class E2> | |
1059 | BOOST_UBLAS_INLINE | |
1060 | vector_expression_assigner<vector_expression<E1> > operator<<=(vector_expression<E1> &v, const vector_expression<E2> &ve) { | |
1061 | return vector_expression_assigner<vector_expression<E1> >(v,ve); | |
1062 | } | |
1063 | ||
1064 | /** | |
1065 | * \brief A vector_expression_assigner generator used with operator<<= for traverse manipulators | |
1066 | * | |
1067 | * Please see EXAMPLES_LINK for usage information. | |
1068 | * | |
1069 | * \todo Add examples link | |
1070 | */ | |
1071 | template <class E, typename T> | |
1072 | BOOST_UBLAS_INLINE | |
1073 | vector_expression_assigner<vector_expression<E> > operator<<=(vector_expression<E> &v, const index_manipulator<T> &nv) { | |
1074 | return vector_expression_assigner<vector_expression<E> >(v,nv); | |
1075 | } | |
1076 | ||
1077 | /** | |
1078 | * \brief A vector_expression_assigner generator used with operator<<= for choice of fill policy | |
1079 | * | |
1080 | * Please see EXAMPLES_LINK for usage information. | |
1081 | * | |
1082 | * \todo Add examples link | |
1083 | */ | |
1084 | template <class E, typename T> | |
1085 | BOOST_UBLAS_INLINE | |
1086 | vector_expression_assigner<vector_expression<E>, T> operator<<=(vector_expression<E> &v, fill_policy_wrapper<T>) { | |
1087 | return vector_expression_assigner<vector_expression<E>, T>(v); | |
1088 | } | |
1089 | ||
1090 | /** | |
1091 | * \brief An assigner object used to fill a vector using operator <<= and operator, (comma) | |
1092 | * | |
1093 | * This object is meant to be created by appropriate object generators. | |
1094 | * Please see EXAMPLES_LINK for usage information. | |
1095 | * | |
1096 | * \todo Add examples link | |
1097 | */ | |
1098 | template <class E, class Fill_Policy = fill_policy::index_assign, class Traverse_Policy = DEFAULT_TRAVERSE_POLICY > | |
1099 | class matrix_expression_assigner { | |
1100 | public: | |
1101 | typedef typename E::expression_type::size_type size_type; | |
1102 | ||
1103 | BOOST_UBLAS_INLINE | |
1104 | matrix_expression_assigner(E &e): me(e), i(0), j(0) { | |
1105 | } | |
1106 | ||
1107 | BOOST_UBLAS_INLINE | |
1108 | matrix_expression_assigner(E &e, size_type k, size_type l): me(e), i(k), j(l) { | |
1109 | } | |
1110 | ||
1111 | BOOST_UBLAS_INLINE | |
1112 | matrix_expression_assigner(E &e, typename E::expression_type::value_type val): me(e), i(0), j(0) { | |
1113 | operator,(val); | |
1114 | } | |
1115 | ||
1116 | template <class AE> | |
1117 | BOOST_UBLAS_INLINE | |
1118 | matrix_expression_assigner(E &e, const vector_expression<AE> &nve):me(e), i(0), j(0) { | |
1119 | operator,(nve); | |
1120 | } | |
1121 | ||
1122 | template <class AE> | |
1123 | BOOST_UBLAS_INLINE | |
1124 | matrix_expression_assigner(E &e, const matrix_expression<AE> &nme):me(e), i(0), j(0) { | |
1125 | operator,(nme); | |
1126 | } | |
1127 | ||
1128 | template <typename T> | |
1129 | BOOST_UBLAS_INLINE | |
1130 | matrix_expression_assigner(E &e, const index_manipulator<T> &ta):me(e), i(0), j(0) { | |
1131 | operator,(ta); | |
1132 | } | |
1133 | ||
1134 | BOOST_UBLAS_INLINE | |
1135 | matrix_expression_assigner &operator, (const typename E::expression_type::value_type& val) { | |
1136 | Traverse_Policy::apply_wrap(me, i ,j); | |
1137 | return apply(val); | |
1138 | } | |
1139 | ||
1140 | template <class AE> | |
1141 | BOOST_UBLAS_INLINE | |
1142 | matrix_expression_assigner &operator, (const vector_expression<AE> &nve) { | |
1143 | for (typename AE::size_type k = 0; k!= nve().size(); k++) { | |
1144 | operator,(nve()(k)); | |
1145 | } | |
1146 | return *this; | |
1147 | } | |
1148 | ||
1149 | template <class AE> | |
1150 | BOOST_UBLAS_INLINE | |
1151 | matrix_expression_assigner &operator, (const matrix_expression<AE> &nme) { | |
1152 | return apply(nme); | |
1153 | } | |
1154 | ||
1155 | template <typename T> | |
1156 | BOOST_UBLAS_INLINE | |
1157 | matrix_expression_assigner &operator, (const index_manipulator<T> &ta) { | |
1158 | ta().manip(i, j); | |
1159 | return *this; | |
1160 | } | |
1161 | ||
1162 | template <class T> | |
1163 | BOOST_UBLAS_INLINE | |
1164 | matrix_expression_assigner<E, T, Traverse_Policy> operator, (fill_policy_wrapper<T>) const { | |
1165 | return matrix_expression_assigner<E, T, Traverse_Policy>(me, i, j); | |
1166 | } | |
1167 | ||
1168 | ||
1169 | template <class T> | |
1170 | BOOST_UBLAS_INLINE | |
1171 | matrix_expression_assigner<E, Fill_Policy, T> operator, (traverse_policy_wrapper<T>) { | |
1172 | Traverse_Policy::apply_wrap(me, i ,j); | |
1173 | return matrix_expression_assigner<E, Fill_Policy, T>(me, i, j); | |
1174 | } | |
1175 | ||
1176 | private: | |
1177 | BOOST_UBLAS_INLINE | |
1178 | matrix_expression_assigner &apply(const typename E::expression_type::value_type& val) { | |
1179 | Fill_Policy::apply(me, i, j, val); | |
1180 | Traverse_Policy::advance(i,j); | |
1181 | return *this; | |
1182 | } | |
1183 | ||
1184 | template <class AE> | |
1185 | BOOST_UBLAS_INLINE | |
1186 | matrix_expression_assigner &apply(const matrix_expression<AE> &nme) { | |
1187 | size_type bi = i; | |
1188 | size_type bj = j; | |
1189 | typename AE::size_type k=0, l=0; | |
1190 | Fill_Policy::apply(me, i, j, nme()(k, l)); | |
1191 | while (Traverse_Policy::next(nme, me, i, j, bi, bj, k, l)) | |
1192 | Fill_Policy::apply(me, i, j, nme()(k, l)); | |
1193 | return *this; | |
1194 | } | |
1195 | ||
1196 | private: | |
1197 | E &me; | |
1198 | size_type i, j; | |
1199 | }; | |
1200 | ||
1201 | /** | |
1202 | * \brief A matrix_expression_assigner generator used with operator<<= for simple types | |
1203 | * | |
1204 | * Please see EXAMPLES_LINK for usage information. | |
1205 | * | |
1206 | * \todo Add examples link | |
1207 | */ | |
1208 | template <class E> | |
1209 | BOOST_UBLAS_INLINE | |
1210 | matrix_expression_assigner<matrix_expression<E> > operator<<=(matrix_expression<E> &me, const typename E::value_type &val) { | |
1211 | return matrix_expression_assigner<matrix_expression<E> >(me,val); | |
1212 | } | |
1213 | ||
1214 | /** | |
1215 | * \brief A matrix_expression_assigner generator used with operator<<= for choice of fill policy | |
1216 | * | |
1217 | * Please see EXAMPLES_LINK for usage information. | |
1218 | * | |
1219 | * \todo Add examples link | |
1220 | */ | |
1221 | template <class E, typename T> | |
1222 | BOOST_UBLAS_INLINE | |
1223 | matrix_expression_assigner<matrix_expression<E>, T> operator<<=(matrix_expression<E> &me, fill_policy_wrapper<T>) { | |
1224 | return matrix_expression_assigner<matrix_expression<E>, T>(me); | |
1225 | } | |
1226 | ||
1227 | /** | |
1228 | * \brief A matrix_expression_assigner generator used with operator<<= for traverse manipulators | |
1229 | * | |
1230 | * Please see EXAMPLES_LINK for usage information. | |
1231 | * | |
1232 | * \todo Add examples link | |
1233 | */ | |
1234 | template <class E, typename T> | |
1235 | BOOST_UBLAS_INLINE | |
1236 | matrix_expression_assigner<matrix_expression<E> > operator<<=(matrix_expression<E> &me, const index_manipulator<T> &ta) { | |
1237 | return matrix_expression_assigner<matrix_expression<E> >(me,ta); | |
1238 | } | |
1239 | ||
1240 | /** | |
1241 | * \brief A matrix_expression_assigner generator used with operator<<= for traverse manipulators | |
1242 | * | |
1243 | * Please see EXAMPLES_LINK for usage information. | |
1244 | * | |
1245 | * \todo Add examples link | |
1246 | */ | |
1247 | template <class E, typename T> | |
1248 | BOOST_UBLAS_INLINE | |
1249 | matrix_expression_assigner<matrix_expression<E>, fill_policy::index_assign, T> operator<<=(matrix_expression<E> &me, traverse_policy_wrapper<T>) { | |
1250 | return matrix_expression_assigner<matrix_expression<E>, fill_policy::index_assign, T>(me); | |
1251 | } | |
1252 | ||
1253 | /** | |
1254 | * \brief A matrix_expression_assigner generator used with operator<<= for vector expressions | |
1255 | * | |
1256 | * Please see EXAMPLES_LINK for usage information. | |
1257 | * | |
1258 | * \todo Add examples link | |
1259 | */ | |
1260 | template <class E1, class E2> | |
1261 | BOOST_UBLAS_INLINE | |
1262 | matrix_expression_assigner<matrix_expression<E1> > operator<<=(matrix_expression<E1> &me, const vector_expression<E2> &ve) { | |
1263 | return matrix_expression_assigner<matrix_expression<E1> >(me,ve); | |
1264 | } | |
1265 | ||
1266 | /** | |
1267 | * \brief A matrix_expression_assigner generator used with operator<<= for matrix expressions | |
1268 | * | |
1269 | * Please see EXAMPLES_LINK for usage information. | |
1270 | * | |
1271 | * \todo Add examples link | |
1272 | */ | |
1273 | template <class E1, class E2> | |
1274 | BOOST_UBLAS_INLINE | |
1275 | matrix_expression_assigner<matrix_expression<E1> > operator<<=(matrix_expression<E1> &me1, const matrix_expression<E2> &me2) { | |
1276 | return matrix_expression_assigner<matrix_expression<E1> >(me1,me2); | |
1277 | } | |
1278 | ||
1279 | } } } | |
1280 | ||
1281 | #endif // ASSIGNMENT_HPP |