00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef vector_expr_h
00014 #define vector_expr_h
00015
00016 #include <cmath>
00017 #include <cml/et/size_checking.h>
00018 #include <cml/vector/vector_traits.h>
00019 #include <cml/vector/vector_promotions.h>
00020
00021
00022
00023
00024
00025
00026 #define VECXPR_ARG_TYPE const et::VectorXpr<XprT>&
00027 #define VECXPR_ARG_TYPE_N(_N_) const et::VectorXpr<XprT##_N_>&
00028
00029
00030
00031
00032 namespace cml {
00033 namespace et {
00034
00036 template<class ExprT>
00037 class VectorXpr
00038 {
00039 public:
00040
00041 typedef VectorXpr<ExprT> expr_type;
00042
00043
00044 typedef typename ExprT::expr_ary expr_ary;
00045
00046
00047 typedef expr_type expr_const_reference;
00048
00049 typedef typename ExprT::value_type value_type;
00050 typedef vector_result_tag result_tag;
00051 typedef typename ExprT::size_tag size_tag;
00052
00053
00054 typedef ExprTraits<ExprT> expr_traits;
00055
00056
00057 typedef typename expr_traits::const_reference expr_reference;
00058
00059
00060 typedef typename expr_traits::result_type result_type;
00061
00062
00063 typedef cml::et::not_assignable_tag assignable_tag;
00064
00065
00066 typedef typename result_type::temporary_type temporary_type;
00067
00068
00069 public:
00070
00072 enum { array_size = ExprT::array_size };
00073
00074
00075 public:
00076
00078 value_type length_squared() const {
00079 return m_expr.length_squared();
00080 }
00081
00083 value_type length() const {
00084 return m_expr.length();
00085 }
00086
00088 result_type normalize() const {
00089 return m_expr.normalize();
00090 }
00091
00093 value_type operator[](size_t i) const {
00094 return m_expr[i];
00095 }
00096
00097
00098 public:
00099
00101 size_t size() const {
00102 return m_expr.size();
00103 }
00104
00106 expr_reference expression() const { return m_expr; }
00107
00108
00109 public:
00110
00112 explicit VectorXpr(expr_reference expr) : m_expr(expr) {}
00113
00115 VectorXpr(const expr_type& e) : m_expr(e.m_expr) {}
00116
00117
00118 protected:
00119
00120 expr_reference m_expr;
00121
00122
00123 private:
00124
00125
00126 expr_type& operator=(const expr_type&);
00127 };
00128
00130 template<class ExprT>
00131 struct ExprTraits< VectorXpr<ExprT> >
00132 {
00133 typedef VectorXpr<ExprT> expr_type;
00134 typedef ExprT arg_type;
00135 typedef typename expr_type::value_type value_type;
00136 typedef typename expr_type::expr_const_reference const_reference;
00137 typedef typename expr_type::result_tag result_tag;
00138 typedef typename expr_type::size_tag size_tag;
00139 typedef typename expr_type::result_type result_type;
00140 typedef typename expr_type::assignable_tag assignable_tag;
00141 typedef expr_node_tag node_tag;
00142
00143 value_type get(const expr_type& v, size_t i) const { return v[i]; }
00144 size_t size(const expr_type& e) const { return e.size(); }
00145 };
00146
00147
00152 template<class ExprT, class OpT>
00153 class UnaryVectorOp
00154 {
00155 public:
00156
00157 typedef UnaryVectorOp<ExprT,OpT> expr_type;
00158
00159
00160 typedef unary_expression expr_ary;
00161
00162
00163 typedef expr_type expr_const_reference;
00164
00165 typedef typename OpT::value_type value_type;
00166 typedef vector_result_tag result_tag;
00167 typedef typename ExprT::size_tag size_tag;
00168
00169
00170 typedef ExprTraits<ExprT> expr_traits;
00171
00172
00173 typedef typename expr_traits::const_reference expr_reference;
00174
00175
00176 typedef typename expr_traits::result_type result_type;
00177
00178
00179 typedef cml::et::not_assignable_tag assignable_tag;
00180
00181
00182 typedef typename result_type::temporary_type temporary_type;
00183
00184
00185 public:
00186
00188 enum { array_size = ExprT::array_size };
00189
00190
00191 public:
00192
00194 value_type length_squared() const {
00195 return dot(
00196 VectorXpr<expr_type>(*this),
00197 VectorXpr<expr_type>(*this));
00198 }
00199
00201 value_type length() const {
00202 return std::sqrt(length_squared());
00203 }
00204
00206 result_type normalize() const {
00207 result_type v(VectorXpr<expr_type>(*this));
00208 return v.normalize();
00209 }
00210
00212 value_type operator[](size_t i) const {
00213
00214
00215
00216
00217 return OpT().apply(expr_traits().get(m_expr,i));
00218 }
00219
00220
00221 public:
00222
00224 size_t size() const {
00225 return m_expr.size();
00226 }
00227
00229 expr_reference expression() const { return m_expr; }
00230
00231
00232 public:
00233
00235 explicit UnaryVectorOp(expr_reference expr) : m_expr(expr) {}
00236
00238 UnaryVectorOp(const expr_type& e) : m_expr(e.m_expr) {}
00239
00240
00241 protected:
00242
00243 expr_reference m_expr;
00244
00245
00246 private:
00247
00248
00249 expr_type& operator=(const expr_type&);
00250 };
00251
00253 template<class ExprT, class OpT>
00254 struct ExprTraits< UnaryVectorOp<ExprT,OpT> >
00255 {
00256 typedef UnaryVectorOp<ExprT,OpT> expr_type;
00257 typedef ExprT arg_type;
00258
00259 typedef typename expr_type::value_type value_type;
00260 typedef typename expr_type::expr_const_reference const_reference;
00261 typedef typename expr_type::result_tag result_tag;
00262 typedef typename expr_type::size_tag size_tag;
00263 typedef typename expr_type::result_type result_type;
00264 typedef typename expr_type::assignable_tag assignable_tag;
00265 typedef expr_node_tag node_tag;
00266
00267 value_type get(const expr_type& v, size_t i) const { return v[i]; }
00268 size_t size(const expr_type& e) const { return e.size(); }
00269 };
00270
00271
00276 template<class LeftT, class RightT, class OpT>
00277 class BinaryVectorOp
00278 {
00279 public:
00280
00281 typedef BinaryVectorOp<LeftT,RightT,OpT> expr_type;
00282
00283
00284 typedef binary_expression expr_ary;
00285
00286
00287 typedef expr_type expr_const_reference;
00288
00289 typedef typename OpT::value_type value_type;
00290 typedef vector_result_tag result_tag;
00291
00292
00293 typedef ExprTraits<LeftT> left_traits;
00294 typedef ExprTraits<RightT> right_traits;
00295
00296
00297 typedef typename left_traits::const_reference left_reference;
00298 typedef typename right_traits::const_reference right_reference;
00299
00300
00301 typedef typename left_traits::result_type left_result;
00302 typedef typename right_traits::result_type right_result;
00303 typedef typename VectorPromote<left_result,right_result>::type result_type;
00304 typedef typename result_type::size_tag size_tag;
00305
00306
00307 typedef cml::et::not_assignable_tag assignable_tag;
00308
00309
00310 typedef typename result_type::temporary_type temporary_type;
00311
00312
00313 typedef GetCheckedSize<LeftT,RightT,size_tag> checked_size;
00314
00315
00316 public:
00317
00319 enum { array_size = result_type::array_size };
00320
00321
00322 public:
00323
00325 value_type length_squared() const {
00326 return dot(
00327 VectorXpr<expr_type>(*this),
00328 VectorXpr<expr_type>(*this));
00329 }
00330
00332 value_type length() const {
00333 return std::sqrt(length_squared());
00334 }
00335
00337 result_type normalize() const {
00338 result_type v(VectorXpr<expr_type>(*this));
00339 return v.normalize();
00340 }
00341
00343 value_type operator[](size_t i) const {
00344
00345
00346
00347
00348 return OpT().apply(
00349 left_traits().get(m_left,i),
00350 right_traits().get(m_right,i));
00351 }
00352
00353
00354 public:
00355
00361 size_t size() const {
00362
00363
00364
00365 return CheckedSize(m_left,m_right,size_tag());
00366 }
00367
00369 left_reference left_expression() const { return m_left; }
00370
00372 right_reference right_expression() const { return m_right; }
00373
00374
00375 public:
00376
00378 explicit BinaryVectorOp(left_reference left, right_reference right)
00379 : m_left(left), m_right(right) {}
00380
00382 BinaryVectorOp(const expr_type& e)
00383 : m_left(e.m_left), m_right(e.m_right) {}
00384
00385
00386 protected:
00387
00388 left_reference m_left;
00389 right_reference m_right;
00390
00391
00392 private:
00393
00394
00395 typename checked_size::check_type _dummy;
00396
00397
00398 private:
00399
00400
00401 expr_type& operator=(const expr_type&);
00402 };
00403
00405 template<class LeftT, class RightT, class OpT>
00406 struct ExprTraits< BinaryVectorOp<LeftT,RightT,OpT> >
00407 {
00408 typedef BinaryVectorOp<LeftT,RightT,OpT> expr_type;
00409 typedef LeftT left_type;
00410 typedef RightT right_type;
00411
00412 typedef typename expr_type::value_type value_type;
00413 typedef typename expr_type::expr_const_reference const_reference;
00414 typedef typename expr_type::result_tag result_tag;
00415 typedef typename expr_type::size_tag size_tag;
00416 typedef typename expr_type::result_type result_type;
00417 typedef typename expr_type::assignable_tag assignable_tag;
00418 typedef expr_node_tag node_tag;
00419
00420 value_type get(const expr_type& v, size_t i) const { return v[i]; }
00421 size_t size(const expr_type& e) const { return e.size(); }
00422 };
00423
00424
00425 template<typename LeftTraits, typename RightTraits>
00426 struct VectorExpressions
00427 {
00428
00429 typedef typename LeftTraits::result_tag left_result;
00430 typedef typename RightTraits::result_tag right_result;
00431 enum { is_true = (same_type<left_result,et::vector_result_tag>::is_true
00432 && same_type<right_result,et::vector_result_tag>::is_true) };
00433 };
00434
00435 namespace detail {
00436
00437 template<typename VecT, typename RT, typename MT> inline
00438 void Resize(VecT&,size_t,RT,MT) {}
00439
00440 template<typename VecT> inline
00441 void Resize(VecT& v, size_t S, resizable_tag, dynamic_memory_tag) {
00442 v.resize(S);
00443 }
00444
00445 template<typename VecT> inline
00446 void Resize(VecT& v, size_t S) {
00447 Resize(v, S, typename VecT::resizing_tag(), typename VecT::memory_tag());
00448 }
00449
00450 }
00451
00452 }
00453 }
00454
00455 #endif
00456
00457
00458