2 // Copyright (c) 2010 Athanasios Iliopoulos
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)
10 #define ASSIGNMENT_HPP
11 #include <boost/numeric/ublas/vector_expression.hpp>
12 #include <boost/numeric/ublas/matrix_expression.hpp>
14 /*! \file assignment.hpp
15 \brief uBlas assignment operator <<=.
18 namespace boost { namespace numeric { namespace ublas {
20 /** \brief A CRTP and Barton-Nackman trick index manipulator wrapper class.
22 * This class is not meant to be used directly.
25 class index_manipulator {
29 const type &operator () () const {
30 return *static_cast<const type *> (this);
33 type &operator () () {
34 return *static_cast<type *> (this);
38 /** \brief A move_to vector index manipulator.
40 * When member function \c manip is called the referenced
41 * index will be set to the manipulators' index.
46 class vector_move_to_manip: public index_manipulator<vector_move_to_manip<T> > {
49 vector_move_to_manip(const T &k): i(k) { }
53 void manip(V &k) const { k=i; }
58 /** \brief An object generator that returns a move_to vector index manipulator
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
65 * vector<double> a(6, 0);
66 * a <<= 1, 2, move_to(5), 3;
77 BOOST_UBLAS_INLINE vector_move_to_manip<T> move_to(T i) {
78 return vector_move_to_manip<T>(i);
81 /** \brief A static move to vector manipulator.
83 * When member function \c manip is called the referenced
84 * index will be set to the manipulators' index
86 * \sa move_to(T i) and move_to()
88 template <std::size_t I>
89 class static_vector_move_to_manip: public index_manipulator<static_vector_move_to_manip<I> > {
93 void manip(V &k) const { k=I; }
96 /** \brief An object generator that returns a static move_to vector index manipulator.
98 * Typically faster than the dynamic version, but can be used only when the
99 * values are known at compile time.
101 * \return A static move_to vector manipulator
105 * vector<double> a(6, 0);
106 * a <<= 1, 2, move_to<5>(), 3;
113 * \tparam I The number of elements the manipulator will traverse the index when \c manip function is called
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>();
120 /** \brief A move vector index manipulator.
122 * When member function traverse is called the manipulators'
123 * index will be added to the referenced index.
127 template <typename T>
128 class vector_move_manip: public index_manipulator<vector_move_manip<T> > {
131 vector_move_manip(const T &k): i(k) { }
133 template <typename V>
134 BOOST_UBLAS_INLINE void manip(V &k) const { k+=i; }
140 * \brief An object generator that returns a move vector index manipulator
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
149 * vector<double> a(6, 0);
150 * a <<= 1, 2, move(3), 3;
158 template <typename T>
159 BOOST_UBLAS_INLINE vector_move_manip<T> move(T i) {
160 return vector_move_manip<T>(i);
164 * \brief A static move vector manipulator
166 * When member function \c manip is called the manipulators
167 * index will be added to the referenced index
171 * \todo Doxygen has some problems with similar template functions. Correct that.
173 template <std::ptrdiff_t I>
174 class static_vector_move_manip: public index_manipulator<static_vector_move_manip<I> > {
176 template <typename V>
177 BOOST_UBLAS_INLINE void manip(V &k) const { k+=I; }
181 * \brief An object generator that returns a static move vector index manipulator.
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
191 * vector<double> a(6, 0);
192 * a <<= 1, 2, move<3>(), 3;
199 * \todo Doxygen has some problems with similar template functions. Correct that.
201 template <std::ptrdiff_t I>
202 static_vector_move_manip<I> move() {
203 return static_vector_move_manip<I>();
207 * \brief A move_to matrix manipulator
209 * When member function \c manip is called the referenced
210 * index will be set to the manipulators' index
212 * \sa move_to(T i, T j)
214 * \todo Doxygen has some problems with similar template functions. Correct that.
216 template <typename T>
217 class matrix_move_to_manip: public index_manipulator<matrix_move_to_manip<T> > {
220 matrix_move_to_manip(T k, T l): i(k), j(l) { }
222 template <typename V1, typename V2>
224 void manip(V1 &k, V2 &l) const {
233 * \brief An object generator that returns a "move_to" matrix index manipulator
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
244 * matrix<double> A(3, 3, 0);
245 * A <<= 1, 2, move_to(A.size1()-1, A.size1()-1), 3;
253 * \sa move_to(T i, T j) and static_matrix_move_to_manip
255 * \todo Doxygen has some problems with similar template functions. Correct that.
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);
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
270 * \todo Doxygen has some problems with similar template functions. Correct that.
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> > {
275 template <typename V, typename K>
277 void manip(V &k, K &l) const {
284 * \brief An object generator that returns a static move_to matrix index manipulator.
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
294 * matrix<double> A(3, 3, 0);
295 * A <<= 1, 2, move_to<2,2>, 3;
303 * \sa move_to(T i, T j) and static_matrix_move_to_manip
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>();
311 * \brief A move matrix index manipulator.
313 * When member function \c manip is called the manipulator's
314 * index will be added to the referenced' index.
318 template <typename T>
319 class matrix_move_manip: public index_manipulator<matrix_move_manip<T> > {
322 matrix_move_manip(T k, T l): i(k), j(l) { }
324 template <typename V, typename K>
326 void manip(V &k, K &l) const {
335 * \brief An object generator that returns a move matrix index manipulator
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
346 * matrix<double> A(3, 3, 0);
347 * A <<= 1, 2, move(1,0),
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);
363 * \brief A static move matrix index manipulator.
365 * When member function traverse is called the manipulator's
366 * index will be added to the referenced' index.
370 * \todo Doxygen has some problems with similar template functions. Correct that.
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> > {
375 template <typename V, typename K>
377 void manip(V &k, K &l) const {
384 * \brief An object generator that returns a static "move" matrix index manipulator.
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.
391 * \return A static move matrix manipulator
395 * matrix<double> A(3, 3, 0);
396 * A <<= 1, 2, move<1,0>(),
408 * \todo Doxygen has some problems with similar template functions. Correct that.
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>();
416 * \brief A begining of row manipulator
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)
423 class begin1_manip: public index_manipulator<begin1_manip > {
425 template <typename V, typename K>
427 void manip(V & k, K &/*l*/) const {
433 * \brief An object generator that returns a begin1 manipulator.
435 * The resulted manipulator will traverse the index to the begining
436 * of the current column when its' \c manip member function is called.
438 * \return A begin1 matrix index manipulator
442 * matrix<double> A(3, 3, 0);
443 * A <<= 1, 2, next_row(),
454 inline begin1_manip begin1() {
455 return begin1_manip();
459 * \brief A begining of column manipulator
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).
467 class begin2_manip: public index_manipulator<begin2_manip > {
469 template <typename V, typename K>
471 void manip(V &/*k*/, K &l) const {
477 * \brief An object generator that returns a begin2 manipulator to be used to traverse a matrix.
479 * The resulted manipulator will traverse the index to the begining
480 * of the current row when its' \c manip member function is called.
482 * \return A begin2 matrix manipulator
486 * matrix<double> A(3, 3, 0);
487 * A <<= 1, 2, move<1,0>(),
496 * \sa begin1() begin2_manip
498 inline begin2_manip begin2() {
499 return begin2_manip();
504 * \brief A next row matrix manipulator.
506 * When member function traverse is called the referenced
507 * index will be traveresed to the begining of next row.
511 class next_row_manip: public index_manipulator<next_row_manip> {
513 template <typename V, typename K>
515 void manip(V &k, K &l) const {
522 * \brief An object generator that returns a next_row manipulator.
524 * The resulted manipulator will traverse the index to the begining
525 * of the next row when it's manip member function is called.
527 * \return A next_row matrix manipulator.
531 * matrix<double> A(3, 3, 0);
532 * A <<= 1, 2, next_row(),
543 inline next_row_manip next_row() {
544 return next_row_manip();
548 * \brief A next column matrix manipulator.
550 * When member function traverse is called the referenced
551 * index will be traveresed to the begining of next column.
555 class next_column_manip: public index_manipulator<next_column_manip> {
557 template <typename V, typename K>
559 void manip(V &k, K &l) const {
566 * \brief An object generator that returns a next_row manipulator.
568 * The resulted manipulator will traverse the index to the begining
569 * of the next column when it's manip member function is called.
571 * \return A next_column matrix manipulator.
575 * matrix<double> A(3, 3, 0);
577 * 3, next_column(), 4;
587 inline next_column_manip next_column() {
588 return next_column_manip();
592 * \brief A wrapper for fill policy classes
596 class fill_policy_wrapper {
601 // Collection of the fill policies
602 namespace fill_policy {
605 * \brief An index assign policy
607 * This policy is used to for the simplified ublas assign through
612 class index_assign :public fill_policy_wrapper<index_assign> {
614 template <class T, typename S, typename V>
616 static void apply(T &e, const S &i, const V &v) {
619 template <class T, typename S, typename V>
621 static void apply(T &e, const S &i, const S &j, const V &v) {
627 * \brief An index plus assign policy
629 * This policy is used when the assignment is desired to be followed
634 class index_plus_assign :public fill_policy_wrapper<index_plus_assign> {
636 template <class T, typename S, typename V>
638 static void apply(T &e, const S &i, const V &v) {
641 template <class T, typename S, typename V>
643 static void apply(T &e, const S &i, const S &j, const V &v) {
649 * \brief An index minus assign policy
651 * This policy is used when the assignment is desired to be followed
656 class index_minus_assign :public fill_policy_wrapper<index_minus_assign> {
658 template <class T, typename S, typename V>
660 static void apply(T &e, const S &i, const V &v) {
663 template <class T, typename S, typename V>
665 static void apply(T &e, const S &i, const S &j, const V &v) {
671 * \brief The sparse push_back fill policy.
673 * This policy is adequate for sparse types, when fast filling is required, where indexing
674 * assign is pretty slow.
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.
679 class sparse_push_back :public fill_policy_wrapper<sparse_push_back > {
681 template <class T, class S, class V>
683 static void apply(T &e, const S &i, const V &v) {
686 template <class T, class S, class V>
688 static void apply(T &e, const S &i, const S &j, const V &v) {
689 e().push_back(i,j, v);
694 * \brief The sparse insert fill policy.
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.
700 class sparse_insert :public fill_policy_wrapper<sparse_insert> {
702 template <class T, class S, class V>
704 static void apply(T &e, const S &i, const V &v) {
705 e().insert_element(i, v);
707 template <class T, class S, class V>
709 static void apply(T &e, const S &i, const S &j, const V &v) {
710 e().insert_element(i,j, v);
716 /** \brief A wrapper for traverse policy classes
720 class traverse_policy_wrapper {
725 // Collection of the traverse policies
726 namespace traverse_policy {
730 * \brief The no wrap policy.
732 * The no wrap policy does not allow wrapping when assigning to a matrix
736 * \brief Element wrap method
738 template <class S1, class S2, class S3>
740 static void apply1(const S1 &/*s*/, S2 &/*i*/, S3 &/*j*/) {
744 * \brief Matrix block wrap method
746 template <class S1, class S2, class S3>
748 static void apply2(const S1 &/*s1*/, const S1 &/*s2*/, S2 &/*i1*/, S3 &/*i2*/) {
753 * \brief The wrap policy.
755 * The wrap policy enables element wrapping when assigning to a matrix
759 * \brief Element wrap method
761 template <class S1, class S2, class S3>
763 static void apply1(const S1 &s, S2 &i1, S3 &i2) {
771 * \brief Matrix block wrap method
773 template <class S1, class S2, class S3>
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
782 * \brief The row_by_row traverse policy
784 * This policy is used when the assignment is desired to happen
785 * row_major wise for performance or other reasons.
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.
790 * Please see EXAMPLES_LINK for usage information.
792 * \todo Add examples link
794 template <class Wrap = wrap>
795 class by_row_policy :public traverse_policy_wrapper<by_row_policy<Wrap> > {
797 template <typename S1, typename S2>
799 static void advance(S1 &/*i*/, S2 &j) { j++;}
801 template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5>
803 static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &/*i0*/, const S3 &j0, S4 &k, S5 &l) {
805 if (l>=e().size2()) {
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()) {
813 Wrap::apply2(e().size1(), me().size2(), i, j);
820 template <class E, typename S1, typename S2>
822 static void apply_wrap(const E& e, S1 &i, S2 &j) {
823 Wrap::apply1(e().size2(), i, j);
828 * \brief The column_by_column traverse policy
830 * This policy is used when the assignment is desired to happen
831 * column_major wise, for performance or other reasons.
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.
836 * Please see EXAMPLES_LINK for usage information.
838 * \todo Add examples link
840 template <class Wrap = wrap>
841 class by_column_policy :public traverse_policy_wrapper<by_column_policy<Wrap> > {
843 template <typename S1, typename S2>
845 static void advance(S1 &i, S2 &/*j*/) { i++;}
847 template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5>
849 static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &i0, const S3 &/*j0*/, S4 &k, S5 &l) {
851 if (k>=e().size1()) {
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()) {
859 Wrap::apply2(e().size2(), me().size1(), j, i);
866 template <class E, typename S1, typename S2>
868 static void apply_wrap(const E& e, S1 &i, S2 &j) {
869 Wrap::apply1(e().size1(), j, i);
873 #ifndef BOOST_UBLAS_DEFAULT_NO_WRAP_POLICY
874 typedef traverse_policy::wrap DEFAULT_WRAP_POLICY;
876 typedef traverse_policy::no_wrap DEFAULT_WRAP_POLICY;
879 #ifndef BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN
880 typedef traverse_policy::by_row_policy<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY;
882 typedef traverse_policy::by_column<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY;
885 // Traverse policy namespace
886 namespace traverse_policy {
888 inline by_row_policy<DEFAULT_WRAP_POLICY> by_row() {
889 return by_row_policy<DEFAULT_WRAP_POLICY>();
892 inline by_row_policy<wrap> by_row_wrap() {
893 return by_row_policy<wrap>();
896 inline by_row_policy<no_wrap> by_row_no_wrap() {
897 return by_row_policy<no_wrap>();
900 inline by_column_policy<DEFAULT_WRAP_POLICY> by_column() {
901 return by_column_policy<DEFAULT_WRAP_POLICY>();
904 inline by_column_policy<wrap> by_column_wrap() {
905 return by_column_policy<wrap>();
908 inline by_column_policy<no_wrap> by_column_no_wrap() {
909 return by_column_policy<no_wrap>();
915 * \brief An assigner object used to fill a vector using operator <<= and operator, (comma)
917 * This object is meant to be created by appropriate object generators.
918 * Please see EXAMPLES_LINK for usage information.
920 * \todo Add examples link
922 template <class E, class Fill_Policy = fill_policy::index_assign>
923 class vector_expression_assigner {
925 typedef typename E::expression_type::value_type value_type;
926 typedef typename E::expression_type::size_type size_type;
929 vector_expression_assigner(E &e):ve(e), i(0) {
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.
939 vector_expression_assigner(E &e, value_type val):ve(e), i(0) {
945 vector_expression_assigner(E &e, const vector_expression<AE> &nve):ve(e), i(0) {
949 template <typename T>
951 vector_expression_assigner(E &e, const index_manipulator<T> &ta):ve(e), i(0) {
956 vector_expression_assigner &operator, (const value_type& val) {
963 vector_expression_assigner &operator, (const vector_expression<AE> &nve) {
964 for (typename AE::size_type k = 0; k!= nve().size(); k++)
969 template <typename T>
971 vector_expression_assigner &operator, (const index_manipulator<T> &ta) {
978 vector_expression_assigner<E, T> operator, (fill_policy_wrapper<T>) const {
979 return vector_expression_assigner<E, T>(i, ve);
984 vector_expression_assigner &apply(const typename E::expression_type::value_type& val) {
985 Fill_Policy::apply(ve, i++, val);
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.
998 template <class E, std::size_t I=0>
999 class static_vector_expression_assigner {
1001 typedef typename E::expression_type::value_type value_type;
1002 typedef typename E::expression_type::size_type size_type;
1005 static_vector_expression_assigner(E &e):ve(e) {
1009 static_vector_expression_assigner(E &e, value_type val):ve(e) {
1014 static_vector_expression_assigner<E, I+1> operator, (const value_type& val) {
1020 static_vector_expression_assigner<E, I+1> apply(const typename E::expression_type::value_type& val) {
1022 return static_vector_expression_assigner<E, I+1>(ve);
1031 static_vector_expression_assigner<vector_expression<E>, 1 > test_static(vector_expression<E> &v, const typename E::value_type &val) {
1033 return static_vector_expression_assigner<vector_expression<E>, 1 >(v);
1039 * \brief A vector_expression_assigner generator used with operator<<= for simple types
1041 * Please see EXAMPLES_LINK for usage information.
1043 * \todo Add examples link
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);
1052 * \brief ! A vector_expression_assigner generator used with operator<<= for vector expressions
1054 * Please see EXAMPLES_LINK for usage information.
1056 * \todo Add examples link
1058 template <class E1, class E2>
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);
1065 * \brief A vector_expression_assigner generator used with operator<<= for traverse manipulators
1067 * Please see EXAMPLES_LINK for usage information.
1069 * \todo Add examples link
1071 template <class E, typename T>
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);
1078 * \brief A vector_expression_assigner generator used with operator<<= for choice of fill policy
1080 * Please see EXAMPLES_LINK for usage information.
1082 * \todo Add examples link
1084 template <class E, typename T>
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);
1091 * \brief An assigner object used to fill a vector using operator <<= and operator, (comma)
1093 * This object is meant to be created by appropriate object generators.
1094 * Please see EXAMPLES_LINK for usage information.
1096 * \todo Add examples link
1098 template <class E, class Fill_Policy = fill_policy::index_assign, class Traverse_Policy = DEFAULT_TRAVERSE_POLICY >
1099 class matrix_expression_assigner {
1101 typedef typename E::expression_type::size_type size_type;
1104 matrix_expression_assigner(E &e): me(e), i(0), j(0) {
1108 matrix_expression_assigner(E &e, size_type k, size_type l): me(e), i(k), j(l) {
1112 matrix_expression_assigner(E &e, typename E::expression_type::value_type val): me(e), i(0), j(0) {
1118 matrix_expression_assigner(E &e, const vector_expression<AE> &nve):me(e), i(0), j(0) {
1124 matrix_expression_assigner(E &e, const matrix_expression<AE> &nme):me(e), i(0), j(0) {
1128 template <typename T>
1130 matrix_expression_assigner(E &e, const index_manipulator<T> &ta):me(e), i(0), j(0) {
1135 matrix_expression_assigner &operator, (const typename E::expression_type::value_type& val) {
1136 Traverse_Policy::apply_wrap(me, i ,j);
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));
1151 matrix_expression_assigner &operator, (const matrix_expression<AE> &nme) {
1155 template <typename T>
1157 matrix_expression_assigner &operator, (const index_manipulator<T> &ta) {
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);
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);
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);
1186 matrix_expression_assigner &apply(const matrix_expression<AE> &nme) {
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));
1202 * \brief A matrix_expression_assigner generator used with operator<<= for simple types
1204 * Please see EXAMPLES_LINK for usage information.
1206 * \todo Add examples link
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);
1215 * \brief A matrix_expression_assigner generator used with operator<<= for choice of fill policy
1217 * Please see EXAMPLES_LINK for usage information.
1219 * \todo Add examples link
1221 template <class E, typename T>
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);
1228 * \brief A matrix_expression_assigner generator used with operator<<= for traverse manipulators
1230 * Please see EXAMPLES_LINK for usage information.
1232 * \todo Add examples link
1234 template <class E, typename T>
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);
1241 * \brief A matrix_expression_assigner generator used with operator<<= for traverse manipulators
1243 * Please see EXAMPLES_LINK for usage information.
1245 * \todo Add examples link
1247 template <class E, typename T>
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);
1254 * \brief A matrix_expression_assigner generator used with operator<<= for vector expressions
1256 * Please see EXAMPLES_LINK for usage information.
1258 * \todo Add examples link
1260 template <class E1, class E2>
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);
1267 * \brief A matrix_expression_assigner generator used with operator<<= for matrix expressions
1269 * Please see EXAMPLES_LINK for usage information.
1271 * \todo Add examples link
1273 template <class E1, class E2>
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);
1281 #endif // ASSIGNMENT_HPP