00001 #ifndef VIENNAMATH_MANIPULATION_EVAL_HPP
00002 #define VIENNAMATH_MANIPULATION_EVAL_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "viennamath/forwards.h"
00021 #include "viennamath/compiletime/ct_variable.hpp"
00022 #include "viennamath/manipulation/simplify.hpp"
00023
00028 namespace viennamath
00029 {
00031
00032 namespace result_of
00033 {
00035 template <typename E>
00036 struct is_ct_evaluable
00037 {
00038 enum { value = 0 };
00039 };
00040
00042 template <typename LHS, typename OP, typename RHS>
00043 struct is_ct_evaluable< ct_binary_expr<LHS, OP, RHS> >
00044 {
00045 enum { value = is_ct_evaluable<LHS>::value * is_ct_evaluable<RHS>::value };
00046 };
00047
00049 template <long val>
00050 struct is_ct_evaluable< ct_constant<val> >
00051 {
00052 enum { value = 1 };
00053 };
00054
00056 template <id_type id>
00057 struct is_ct_evaluable< ct_variable<id> >
00058 {
00059 enum { value = 1 };
00060 };
00061
00063 template <typename VectorType>
00064 struct is_ct_vector
00065 {
00066 enum { value = 0 };
00067 };
00068
00070 template <typename T0>
00071 struct is_ct_vector< ct_vector_1<T0> >
00072 {
00073 enum { value = is_compiletime<T0>::value };
00074 };
00075
00077 template <typename T0, typename T1>
00078 struct is_ct_vector< ct_vector_2<T0, T1> >
00079 {
00080 enum { value = is_compiletime<T0>::value && is_compiletime<T1>::value };
00081 };
00082
00084 template <typename T0, typename T1, typename T2>
00085 struct is_ct_vector< ct_vector_3<T0, T1, T2> >
00086 {
00087 enum { value = is_compiletime<T0>::value && is_compiletime<T1>::value && is_compiletime<T2>::value };
00088 };
00089
00090
00091
00092
00093
00100 template <typename ExpressionType,
00101 typename VectorType,
00102 bool ct_evaluable = (is_ct_evaluable<ExpressionType>::value != 0)>
00103 struct eval
00104 {
00105 typedef typename ExpressionType::ERROR_INVALID_EXPRESSION_TYPE_FOR_COMPILETIME_EVALUATION error_type;
00106 };
00107
00108
00110 template <typename LHS, typename OP, typename RHS, typename VectorType>
00111 struct eval< ct_binary_expr<LHS, OP, RHS>, VectorType, true>
00112 {
00113 typedef ct_binary_expr< typename eval<LHS, VectorType>::type,
00114 OP,
00115 typename eval<RHS, VectorType>::type > intermediate_type;
00116
00117
00118 typedef typename result_of::simplify<intermediate_type>::type type;
00119 };
00120
00122 template <long value, typename VectorType>
00123 struct eval< ct_constant<value>, VectorType, true>
00124 {
00125 typedef ct_constant<value> type;
00126 };
00127
00129 template <id_type id, typename VectorType>
00130 struct eval< ct_variable<id>, VectorType, true>
00131 {
00132 typedef typename type_by_index<VectorType, id>::type type;
00133 };
00134
00136 template <long value>
00137 struct eval< ct_variable<0>, ct_constant<value>, true>
00138 {
00139 typedef ct_constant<value> type;
00140 };
00141
00142 }
00143
00144
00150 template <typename ExpressionType, typename VectorType>
00151 typename enable_if<result_of::is_ct_evaluable<ExpressionType>::value && result_of::is_ct_vector<VectorType>::value,
00152 default_numeric_type>::type
00153 eval(ExpressionType const & e, VectorType const & v)
00154 {
00155 return typename result_of::eval<ExpressionType, VectorType>::type()();
00156 }
00157
00158
00159
00161
00162
00163
00164
00165
00166
00167
00168
00170 template <typename VectorType>
00171 default_numeric_type eval(default_numeric_type value, VectorType const & v)
00172 {
00173
00174 return value;
00175 }
00176
00178 template <typename VectorType>
00179 long eval(long value, VectorType const & v)
00180 {
00181
00182 return value;
00183 }
00184
00186 template <typename T, typename InterfaceType, typename VectorType>
00187 typename InterfaceType::numeric_type
00188 eval(rt_constant<T, InterfaceType> c, VectorType const & v)
00189 {
00190
00191 return c();
00192 }
00193
00199 template <typename InterfaceType, typename VectorType>
00200 typename InterfaceType::numeric_type
00201 eval(rt_expr< InterfaceType> e, VectorType const & v)
00202 {
00203 return e(v);
00204 }
00205
00211 template <typename InterfaceType, typename VectorType>
00212 typename InterfaceType::numeric_type
00213 eval(rt_binary_expr< InterfaceType> e, VectorType const & v)
00214 {
00215 return e(v);
00216 }
00217
00223 template <typename InterfaceType, typename VectorType>
00224 typename InterfaceType::numeric_type
00225 eval(rt_unary_expr< InterfaceType> e, VectorType const & v)
00226 {
00227 return e(v);
00228 }
00229
00235 template <typename InterfaceType, typename VectorType>
00236 typename InterfaceType::numeric_type
00237 eval(rt_variable< InterfaceType> e, VectorType const & v)
00238 {
00239 return e(v);
00240 }
00241
00242
00243
00249 template <typename LHS, typename OP, typename RHS, typename VectorType>
00250 typename enable_if<!result_of::is_ct_evaluable< ct_binary_expr<LHS, OP, RHS> >::value || !result_of::is_ct_vector<VectorType>::value,
00251 default_numeric_type>::type
00252 eval(ct_binary_expr<LHS, OP, RHS> ex, VectorType const & v)
00253 {
00254 return ex(v);
00255 }
00256
00262 template <typename LHS, typename OP, typename VectorType>
00263 typename enable_if<!result_of::is_ct_evaluable< ct_unary_expr<LHS, OP> >::value || !result_of::is_ct_vector<VectorType>::value,
00264 default_numeric_type>::type
00265 eval(ct_unary_expr<LHS, OP> ex, VectorType const & v)
00266 {
00267 return ex(v);
00268 }
00269
00275 template <long value, typename VectorType>
00276 default_numeric_type eval(ct_constant<value> c, VectorType const & v)
00277 {
00278 return value;
00279 }
00280
00286 template <id_type id, typename VectorType>
00287 default_numeric_type eval(ct_variable<id> c, VectorType const & v)
00288 {
00289 return v[id];
00290 }
00291
00293 template <id_type id, typename T0>
00294 default_numeric_type eval(ct_variable<id> c, ct_vector_1<T0> const & v)
00295 {
00296 return v[ct_index<id>()];
00297 }
00298
00300 template <id_type id, typename T0, typename T1>
00301 default_numeric_type eval(ct_variable<id> c, ct_vector_2<T0, T1> const & v)
00302 {
00303 return v[ct_index<id>()];
00304 }
00305
00307 template <id_type id, typename T0, typename T1, typename T2>
00308 default_numeric_type eval(ct_variable<id> c, ct_vector_3<T0, T1, T2> const & v)
00309 {
00310 return v[ct_index<id>()];
00311 }
00312
00313 }
00314
00315 #endif