Go to the documentation of this file.00001 #ifndef VIENNAMATH_RUNTIME_EXPR_HPP
00002 #define VIENNAMATH_RUNTIME_EXPR_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <ostream>
00021 #include <sstream>
00022 #include <memory>
00023 #include "viennamath/forwards.h"
00024 #include "viennamath/runtime/constant.hpp"
00025 #include "viennamath/compiletime/ct_constant.hpp"
00026 #include "viennamath/compiletime/ct_binary_expr.hpp"
00027 #include "viennamath/compiletime/ct_unary_expr.hpp"
00028
00033 namespace viennamath
00034 {
00035
00042 template <typename InterfaceType >
00043 class rt_expr
00044 {
00045 public:
00046 typedef typename InterfaceType::numeric_type numeric_type;
00047 typedef InterfaceType interface_type;
00048
00049 rt_expr() {}
00050
00051 explicit rt_expr(const InterfaceType * e) : rt_expr_(e) {}
00052
00053 rt_expr(rt_binary_expr<InterfaceType> const & other)
00054 {
00055 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00056 }
00057
00058 rt_expr(rt_unary_expr<InterfaceType> const & other)
00059 {
00060 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00061 }
00062
00063 template <typename LHS, typename OP, typename RHS>
00064 rt_expr(ct_binary_expr<LHS, OP, RHS> const & other)
00065 {
00066 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_binary_expr<InterfaceType>(other));
00067 }
00068
00069 template <typename LHS, typename OP>
00070 rt_expr(ct_unary_expr<LHS, OP> const & other)
00071 {
00072 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_unary_expr<InterfaceType>(other));
00073 }
00074
00075 rt_expr<InterfaceType>(rt_variable<InterfaceType> const & other)
00076 {
00077 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00078 }
00079
00080 template <id_type id>
00081 rt_expr<InterfaceType>(ct_variable<id> const & other)
00082 {
00083 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_variable<InterfaceType>(id));
00084 }
00085
00086 template <typename T>
00087 rt_expr(rt_constant<T, InterfaceType> const & other)
00088 {
00089 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00090 }
00091
00092 rt_expr(rt_function_symbol<InterfaceType> const & other)
00093 {
00094 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00095 }
00096
00097 rt_expr(rt_vector_expr<InterfaceType> const & other)
00098 {
00099 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00100 }
00101
00102 template <long value>
00103 rt_expr(ct_constant<value> const & other)
00104 {
00105 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_constant<numeric_type>(value));
00106 }
00107
00108 rt_expr(numeric_type const & other)
00109 {
00110 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_constant<numeric_type, InterfaceType>(other));
00111 }
00112
00113
00114 rt_expr(rt_expr const & other)
00115 {
00116 if (other.get() != NULL)
00117 rt_expr_ = std::auto_ptr<InterfaceType>(other.get()->clone());
00118 }
00119
00120
00121
00122
00123 rt_expr & operator=(InterfaceType * other)
00124 {
00125 rt_expr_ = std::auto_ptr<InterfaceType>(other);
00126 return *this;
00127 }
00128
00129 rt_expr & operator=(rt_expr const & other)
00130 {
00131 rt_expr_ = std::auto_ptr<InterfaceType>(other.get()->clone());
00132 return *this;
00133 }
00134
00135 template <typename LHS, typename OP, typename RHS>
00136 rt_expr & operator=(ct_binary_expr<LHS, OP, RHS> const & other)
00137 {
00138 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_binary_expr<InterfaceType>(other));
00139 return *this;
00140 }
00141
00142 template <typename LHS, typename OP>
00143 rt_expr & operator=(ct_unary_expr<LHS, OP> const & other)
00144 {
00145 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_unary_expr<InterfaceType>(other));
00146 return *this;
00147 }
00148
00149 rt_expr & operator=(rt_binary_expr<InterfaceType> const & other)
00150 {
00151 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00152 return *this;
00153 }
00154
00155 rt_expr & operator=(rt_variable<InterfaceType> const & other)
00156 {
00157 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00158 return *this;
00159 }
00160
00161 template <id_type id>
00162 rt_expr & operator=(ct_variable<id> const & other)
00163 {
00164 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_constant<InterfaceType>(id));
00165 return *this;
00166 }
00167
00168
00169 template <typename ScalarType>
00170 rt_expr & operator=(rt_constant<ScalarType, InterfaceType> const & other)
00171 {
00172 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00173 return *this;
00174 }
00175
00176 template <long value>
00177 rt_expr & operator=(ct_constant<value> const & other)
00178 {
00179 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_constant<numeric_type>(value));
00180 return *this;
00181 }
00182
00183 rt_expr & operator=(rt_function_symbol<InterfaceType> const & other)
00184 {
00185 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00186 return *this;
00187 }
00188
00189 rt_expr & operator=(rt_vector_expr<InterfaceType> const & other)
00190 {
00191 rt_expr_ = std::auto_ptr<InterfaceType>(other.clone());
00192 return *this;
00193 }
00194
00195 rt_expr & operator=(numeric_type value)
00196 {
00197 rt_expr_ = std::auto_ptr<InterfaceType>(new rt_constant<numeric_type>(value));
00198 return *this;
00199 }
00200
00201 const InterfaceType * get() const { return rt_expr_.get(); }
00202
00204
00205
00206 numeric_type operator()(numeric_type val) const
00207 {
00208 return rt_expr_.get()->eval(val);
00209 }
00210
00211 template <typename ScalarType>
00212 numeric_type operator()(rt_constant<ScalarType, InterfaceType> val) const
00213 {
00214 return rt_expr_.get()->eval(static_cast<numeric_type>(val));
00215 }
00216
00217 template <long value>
00218 numeric_type operator()(ct_constant<value> val) const
00219 {
00220 return rt_expr_.get()->eval(value);
00221 }
00222
00223 template <typename VectorType>
00224 numeric_type operator()(VectorType const & v) const
00225 {
00226 std::vector<double> stl_v(v.size());
00227 for (size_t i=0; i<v.size(); ++i)
00228 stl_v[i] = v[i];
00229
00230 return rt_expr_.get()->eval(stl_v);
00231 }
00232
00233 numeric_type operator()(std::vector<numeric_type> const & stl_v) const
00234 {
00235
00236 return rt_expr_.get()->eval(stl_v);
00237 }
00238
00239 template <typename T0>
00240 numeric_type operator()(viennamath::ct_vector_1<T0> const & v) const
00241 {
00242 std::vector<double> stl_v(1);
00243 stl_v[0] = v[ct_index<0>()];
00244 return rt_expr_.get()->eval(stl_v);
00245 }
00246
00247 template <typename T0, typename T1>
00248 numeric_type operator()(viennamath::ct_vector_2<T0, T1> const & v) const
00249 {
00250 std::vector<double> stl_v(2);
00251 stl_v[0] = v[ct_index<0>()];
00252 stl_v[1] = v[ct_index<1>()];
00253 return rt_expr_.get()->eval(stl_v);
00254 }
00255
00256 template <typename T0, typename T1, typename T2>
00257 numeric_type operator()(viennamath::ct_vector_3<T0, T1, T2> const & v) const
00258 {
00259 std::vector<double> stl_v(3);
00260 stl_v[0] = v[ct_index<0>()];
00261 stl_v[1] = v[ct_index<1>()];
00262 stl_v[2] = v[ct_index<2>()];
00263 return rt_expr_.get()->eval(stl_v);
00264 }
00265
00266 private:
00267 std::auto_ptr<const InterfaceType> rt_expr_;
00268 };
00269
00270
00271 template <typename InterfaceType>
00272 std::ostream& operator<<(std::ostream & stream, rt_expr<InterfaceType> const & e)
00273 {
00274 if (e.get()->is_unary())
00275 {
00276 stream << "expr"
00277 << "("
00278 << e.get()->deep_str()
00279 << ")";
00280 }
00281 else
00282 {
00283 stream << "expr"
00284 << e.get()->deep_str();
00285 }
00286
00287 return stream;
00288 }
00289
00290 }
00291
00292 #endif