00001 #ifndef VIENNAMATH_RUNTIME_OPERATIONS_RT_RT_HPP
00002 #define VIENNAMATH_RUNTIME_OPERATIONS_RT_RT_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <ostream>
00021 #include "viennamath/forwards.h"
00022 #include "viennamath/runtime/binary_expr.hpp"
00023
00028 namespace viennamath
00029 {
00030
00032 namespace traits
00033 {
00034 template <typename InterfaceType, typename NumericT>
00035 InterfaceType * clone(rt_constant<NumericT, InterfaceType> const & c) { return c.clone(); }
00036
00037 template <typename InterfaceType>
00038 InterfaceType * clone(default_numeric_type d) { return new rt_constant<default_numeric_type, InterfaceType>(d); }
00039
00040 template <typename InterfaceType, long value>
00041 InterfaceType * clone(ct_constant<value> const & c) { return new rt_constant<default_numeric_type, InterfaceType>(value); }
00042
00043 template <typename InterfaceType>
00044 InterfaceType * clone(rt_variable<InterfaceType> const & v) { return v.clone(); }
00045
00046 template <typename InterfaceType, id_type id>
00047 InterfaceType * clone(ct_variable<id> const & v) { return new rt_variable<InterfaceType>(id); }
00048
00049 template <typename InterfaceType>
00050 InterfaceType * clone(rt_function_symbol<InterfaceType> const & fs) { return fs.clone(); }
00051
00052 template <typename InterfaceType>
00053 InterfaceType * clone(rt_unary_expr<InterfaceType> const & e) { return e.clone(); }
00054
00055 template <typename InterfaceType>
00056 InterfaceType * clone(rt_binary_expr<InterfaceType> const & e) { return e.clone(); }
00057
00058 template <typename InterfaceType>
00059 InterfaceType * clone(rt_expr<InterfaceType> const & e) { return e.get()->clone(); }
00060
00061 template <typename InterfaceType, typename LHS, typename OP, typename RHS>
00062 InterfaceType * clone(ct_binary_expr<LHS, OP, RHS> const & e) { return new rt_binary_expr<InterfaceType>(e); }
00063
00064 template <typename InterfaceType, typename LHS, typename OP>
00065 InterfaceType * clone(ct_unary_expr<LHS, OP> const & e) { return new rt_unary_expr<InterfaceType>(e); }
00066
00067 }
00068
00069
00070 namespace result_of
00071 {
00073 template <typename LHS, typename RHS, bool b1, bool b2>
00074 struct add
00075 {
00076 typedef typename interface<LHS, RHS>::type iface_type;
00077 typedef typename iface_type::numeric_type numeric_type;
00078 typedef rt_binary_expr<iface_type> type;
00079
00080 static type instance(LHS const & lhs, RHS const & rhs) { return type(traits::clone<iface_type>(lhs), new op_binary<op_plus<numeric_type>, iface_type>(), traits::clone<iface_type>(rhs)); }
00081 };
00082
00084 template <typename LHS, typename RHS, bool b1, bool b2>
00085 struct subtract
00086 {
00087 typedef typename interface<LHS, RHS>::type iface_type;
00088 typedef typename iface_type::numeric_type numeric_type;
00089 typedef rt_binary_expr<iface_type> type;
00090
00091 static type instance(LHS const & lhs, RHS const & rhs) { return type(traits::clone<iface_type>(lhs), new op_binary<op_minus<numeric_type>, iface_type>(), traits::clone<iface_type>(rhs)); }
00092 };
00093
00095 template <typename LHS, typename RHS, bool b1, bool b2>
00096 struct mult
00097 {
00098 typedef typename interface<LHS, RHS>::type iface_type;
00099 typedef typename iface_type::numeric_type numeric_type;
00100 typedef rt_binary_expr<iface_type> type;
00101
00102 static type instance(LHS const & lhs, RHS const & rhs) { return type(traits::clone<iface_type>(lhs), new op_binary<op_mult<numeric_type>, iface_type>(), traits::clone<iface_type>(rhs)); }
00103 };
00104
00106 template <typename LHS, typename RHS, bool b1, bool b2>
00107 struct div
00108 {
00109 typedef typename interface<LHS, RHS>::type iface_type;
00110 typedef typename iface_type::numeric_type numeric_type;
00111 typedef rt_binary_expr<iface_type> type;
00112
00113 static type instance(LHS const & lhs, RHS const & rhs) { return type(traits::clone<iface_type>(lhs), new op_binary<op_div<numeric_type>, iface_type>(), traits::clone<iface_type>(rhs)); }
00114 };
00115
00116 }
00117
00118
00119
00120
00121 }
00122
00123 #endif