00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_CRTP_BASE_VECTOR_INCLUDE
00013 #define MTL_CRTP_BASE_VECTOR_INCLUDE
00014
00015 #include <boost/utility/enable_if.hpp>
00016 #include <boost/numeric/mtl/mtl_fwd.hpp>
00017 #include <boost/numeric/mtl/vector/all_vec_expr.hpp>
00018 #include <boost/numeric/mtl/operation/mat_cvec_times_expr.hpp>
00019 #include <boost/numeric/mtl/operation/mult.hpp>
00020 #include <boost/numeric/mtl/operation/mat_vec_mult.hpp>
00021 #include <boost/numeric/mtl/operation/mult_assign_mode.hpp>
00022 #include <boost/numeric/mtl/operation/right_scale_inplace.hpp>
00023 #include <boost/numeric/mtl/utility/ashape.hpp>
00024
00025 #include <boost/numeric/itl/itl_fwd.hpp>
00026
00027 namespace mtl { namespace vector {
00028
00029
00030 namespace detail {
00031
00032 template <typename Vector, typename Source, typename SCat, typename VCat>
00033 struct crtp_assign {};
00034
00036 template <typename Vector, typename Source, typename VCat>
00037 struct crtp_assign<Vector, Source, VCat, ashape::scal>
00038 {
00039 typedef vec_scal_asgn_expr<Vector, Source> type;
00040 type operator()(Vector& vector, const Source& src)
00041 {
00042 return type(vector, src);
00043 }
00044 };
00045
00047 template <typename Vector, typename Source, typename Cat>
00048 struct crtp_assign<Vector, Source, Cat, Cat>
00049 {
00050 typedef vec_vec_asgn_expr<Vector, Source> type;
00051 type operator()(Vector& vector, const Source& src)
00052 {
00053 return type(vector, src);
00054 }
00055 };
00056 }
00057
00058 template <typename Vector, typename Source>
00059 struct crtp_assign
00060 : public detail::crtp_assign<Vector, Source, typename ashape::ashape<Vector>::type,
00061 typename ashape::ashape<Source>::type>
00062 {};
00063
00065
00066 template <typename Vector, typename E1, typename E2>
00067 struct crtp_assign<Vector, mat_cvec_times_expr<E1, E2> >
00068 {
00069 typedef Vector& type;
00070 type operator()(Vector& vector, const mat_cvec_times_expr<E1, E2>& src)
00071 {
00072 vector.checked_change_dim(num_rows(src.first));
00073 mult(src.first, src.second, vector);
00074 return vector;
00075 }
00076 };
00077
00079 template <typename Vector, typename Value, unsigned Rows>
00080 struct crtp_assign<Vector, Value[Rows]>
00081 {
00082 typedef Vector& type;
00083 type operator()(Vector& vector, const Value src[Rows])
00084 {
00085 typedef typename Collection<Vector>::size_type size_type;
00086
00087 vector.checked_change_dim(Rows);
00088
00089 for (size_type r= 0; r < Rows; ++r)
00090 vector[r]= src[r];
00091 return vector;
00092 }
00093 };
00094
00095
00096 namespace detail {
00097
00098 template <typename Vector, typename Source, typename SCat, typename VCat>
00099 struct crtp_plus_assign {};
00100
00102 template <typename Vector, typename Source, typename Cat>
00103 struct crtp_plus_assign<Vector, Source, Cat, Cat>
00104 {
00105 typedef vec_vec_plus_asgn_expr<Vector, Source> type;
00106 type operator()(Vector& vector, const Source& src)
00107 {
00108 return type( vector, src );
00109 }
00110 };
00111 }
00112
00113 template <typename Vector, typename Source>
00114 struct crtp_plus_assign
00115 : public detail::crtp_plus_assign<Vector, Source, typename ashape::ashape<Vector>::type,
00116 typename ashape::ashape<Source>::type>
00117 {};
00118
00120
00121 template <typename Vector, typename E1, typename E2>
00122 struct crtp_plus_assign<Vector, mat_cvec_times_expr<E1, E2> >
00123 {
00124 typedef Vector& type;
00125 type operator()(Vector& vector, const mat_cvec_times_expr<E1, E2>& src)
00126 {
00127 gen_mult(src.first, src.second, vector,
00128 assign::plus_sum(), tag::matrix(), tag::vector(), tag::vector());
00129 return vector;
00130 }
00131 };
00132
00133
00134
00135
00136 namespace detail {
00137
00138 template <typename Vector, typename Source, typename VCat, typename SCat>
00139 struct crtp_minus_assign {};
00140
00142 template <typename Vector, typename Source, typename Cat>
00143 struct crtp_minus_assign<Vector, Source, Cat, Cat>
00144 {
00145 typedef vec_vec_minus_asgn_expr<Vector, Source> type;
00146 type operator()(Vector& vector, const Source& src)
00147 {
00148 return type(vector, src);
00149 }
00150 };
00151 }
00152
00153 template <typename Vector, typename Source>
00154 struct crtp_minus_assign
00155 : public detail::crtp_minus_assign<Vector, Source, typename ashape::ashape<Vector>::type,
00156 typename ashape::ashape<Source>::type>
00157 {};
00158
00160
00161 template <typename Vector, typename E1, typename E2>
00162 struct crtp_minus_assign<Vector, mat_cvec_times_expr<E1, E2> >
00163 {
00164 typedef Vector& type;
00165 type operator()(Vector& vector, const mat_cvec_times_expr<E1, E2>& src)
00166 {
00167 gen_mult(src.first, src.second, vector,
00168 assign::minus_sum(), tag::matrix(), tag::vector(), tag::vector());
00169 return vector;
00170 }
00171 };
00172
00173
00174
00175
00176
00178 template <typename Vector, typename ValueType, typename SizeType>
00179 struct crtp_vector_assign
00180 {
00182 template <typename E>
00183 typename boost::disable_if<boost::is_same<Vector, E>,
00184 typename crtp_assign<Vector, E>::type>::type
00185 operator=(const E& e)
00186 {
00187 return crtp_assign<Vector, E>()(static_cast<Vector&>(*this), e);
00188 }
00189
00191 template <class E>
00192 typename crtp_plus_assign<Vector, E>::type operator+=(const E& e)
00193 {
00194 return crtp_plus_assign<Vector, E>()(static_cast<Vector&>(*this), e);
00195 }
00196
00198 template <class E>
00199 typename crtp_minus_assign<Vector, E>::type operator-=(const E& e)
00200 {
00201 return crtp_minus_assign<Vector, E>()(static_cast<Vector&>(*this), e);
00202 }
00203
00205
00206 template <typename Factor>
00207 vec_scal_times_asgn_expr<Vector, Factor> operator*=(const Factor& alpha)
00208 {
00209 return vec_scal_times_asgn_expr<Vector, Factor>( static_cast<Vector&>(*this), alpha );
00210 }
00211
00213
00214 template <typename Factor>
00215 vec_scal_div_asgn_expr<Vector, Factor> operator/=(const Factor& alpha)
00216 {
00217 return vec_scal_div_asgn_expr<Vector, Factor>( static_cast<Vector&>(*this), alpha );
00218 }
00219
00221 void checked_change_dim(SizeType s)
00222 {
00223 Vector& vector= static_cast<Vector&>(*this);
00224 vector.check_dim(s);
00225 vector.change_dim(s);
00226 }
00227 };
00228
00229
00230 template <typename Vector, typename ValueType, typename SizeType>
00231 struct const_crtp_base_vector
00232 {};
00233
00234 template <typename Vector, typename ValueType, typename SizeType>
00235 struct mutable_crtp_base_vector
00236 : public crtp_vector_assign<Vector, ValueType, SizeType>
00237 {};
00238
00239
00240
00241 template <typename Vector, typename ValueType, typename SizeType>
00242 struct crtp_base_vector
00243 : boost::mpl::if_<boost::is_const<Vector>,
00244 const_crtp_base_vector<Vector, ValueType, SizeType>,
00245 mutable_crtp_base_vector<Vector, ValueType, SizeType>
00246 >::type
00247 {};
00248
00249
00250 }}
00251
00252 #endif // MTL_CRTP_BASE_VECTOR_INCLUDE