00001
00002
00003
00004
00005
00006 #ifndef SYNAPS_ARITHM_REF_H
00007 #define SYNAPS_ARITHM_REF_H
00008
00009 #include <synaps/init.h>
00010 #include <synaps/arithm/let.h>
00011 #include <synaps/arithm/GENERIC.h>
00012
00013 __BEGIN_NAMESPACE_SYNAPS
00014
00015
00020 template<class R>
00021 struct VAL {
00022 R _rep;
00023
00024 const R & rep() const { return _rep;}
00025
00026 VAL() {}
00027 VAL(const R & r): _rep(r){}
00028 VAL(const VAL<R> & r): _rep(r._rep){ }
00029
00030 };
00031
00032 template<class R> inline
00033 R * operator&( const VAL<R*> & x) {return x.rep();}
00034
00035 template<class R> inline
00036 VAL<R> Convert(const R & r) {return VAL<R>(r);}
00037
00038 template<class R> inline
00039 VAL<R> Eval (const R & r) {return VAL<R>(r);}
00040
00041 template<class R> inline
00042 VAL<R> Eval (const VAL<R> & r) {return r;}
00043
00044 namespace let {
00045 template<class R,class T> void assign(R & r, const VAL<T> & x)
00046 { assign(r,x.rep()); }
00047 }
00048
00049 template<class R> inline
00050 std::ostream & operator<<(std::ostream & os, const VAL<R*> & x)
00051 {
00052 return (os<<*(x.rep()));
00053 }
00054
00055 template <class R,class S> inline
00056 VAL< OP<'+',R,VAL<S> > >
00057 operator+(const R & a, const VAL<S>& b)
00058 {
00059 return VAL<OP<'+',R,VAL<S> > >(OP<'+',R,VAL<S> >(a,b));
00060 }
00061 template <class R,class S> inline
00062 VAL<OP<'+',VAL<R>,S> >
00063 operator+(const VAL<R> & a, const S & b)
00064 {
00065 return VAL<OP<'+',VAL<R>,S> >(OP<'+',VAL<R>,S>(a,b));
00066 }
00067 template <class R,class S> inline
00068 VAL< OP<'+',VAL<R>,VAL<S> > >
00069 operator+(const VAL<R> & a, const VAL<S>& b)
00070 {
00071 return VAL<OP<'+',VAL<R>,VAL<S> > >(OP<'+',VAL<R>,VAL<S> >(a,b));
00072 }
00073
00074 template <class R,class S> inline
00075 VAL<OP<'-',R,VAL<S> > >
00076 operator-(const R & a, const VAL<S>& b)
00077 {
00078 return VAL<OP<'-',R,VAL<S> > >(OP<'-',R,VAL<S> >(a,b));
00079 }
00080 template <class R,class S> inline
00081 VAL<OP<'-',VAL<R>,S> >
00082 operator-(const VAL<R> & a, const S & b)
00083 {
00084 return VAL<OP<'-',VAL<R>,S> >(OP<'-',VAL<R>,S>(a,b));
00085 }
00086 template <class R,class S> inline
00087 VAL<OP<'-',VAL<R>,VAL<S> > >
00088 operator-(const VAL<R> & a, const VAL<S>& b)
00089 {
00090 return VAL<OP<'-',VAL<R>,VAL<S> > >(OP<'-',VAL<R>,VAL<S> >(a,b));
00091 }
00092
00093 template <class R,class S> inline
00094 VAL<OP<'*',R,VAL<S> > >
00095 operator*(const R & a, const VAL<S>& b)
00096 {
00097 return VAL<OP<'*',R,VAL<S> > >(OP<'*',R,VAL<S> >(a,b));
00098 }
00099 template <class R,class S> inline
00100 VAL<OP<'*',VAL<R>,S> >
00101 operator*(const VAL<R> & a, const S & b)
00102 {
00103 return VAL<OP<'*',VAL<R>,S> >(OP<'*',VAL<R>,S>(a,b));
00104 }
00105 template <class R,class S> inline
00106 VAL<OP<'*',VAL<R>,VAL<S> > >
00107 operator*(const VAL<R> & a, const VAL<S>& b)
00108 {
00109 return VAL<OP<'*',VAL<R>,VAL<S> > >(OP<'*',VAL<R>,VAL<S> >(a,b));
00110 }
00111
00112 template <class R,class S> inline
00113 VAL<OP<'/',R,VAL<S> > >
00114 operator/(const R & a, const VAL<S>& b)
00115 {
00116 return VAL<OP<'/',R,VAL<S> > >(OP<'/',R,VAL<S> >(a,b));
00117 }
00118 template <class R,class S> inline
00119 VAL<OP<'/',VAL<R>,S> >
00120 operator/(const VAL<R> & a, const S & b)
00121 {
00122 return VAL<OP<'/',VAL<R>,S> >(OP<'/',VAL<R>,S>(a,b));
00123 }
00124 template <class R,class S> inline
00125 VAL<OP<'/',VAL<R>,VAL<S> > >
00126 operator/(const VAL<R> & a, const VAL<S>& b)
00127 {
00128 return VAL<OP<'/',VAL<R>,VAL<S> > >(OP<'/',VAL<R>,VAL<S> >(a,b));
00129 }
00130
00131 template <class R,class S> inline
00132 VAL<OP<'^',VAL<R>,S> >
00133 operator^(const VAL<R> & a, const S & b)
00134 {
00135 return VAL<OP<'^',VAL<R>,S> >(OP<'^',VAL<R>,S>(a,b));
00136 }
00137
00138 template<class R> inline
00139 std::ostream & operator << (std::ostream & os,const VAL<R> & M)
00140 {
00141 os <<M.rep(); return os;
00142 }
00143
00144 namespace let {
00145 template<class R,class X> inline
00146 void assign(R & r,const OP<'+',X,int> & x) {add(r,x.op1.rep(),x.op2);}
00147
00148 template<class R,class X,class Y> inline
00149 void assign(R & r,const OP<'+',X,Y> & x)
00150 {add(r.rep(),x.op1.rep(),x.op2.rep());}
00151
00152 template<class R,class X> inline
00153 void assign(R & r,const OP<'-',X,int> & x) {sub(r,x.op1.rep(),x.op2);}
00154 template<class R,class X,class Y> inline
00155 void assign(R & r,const OP<'-',X,Y> & x)
00156 {sub(r.rep(),x.op1.rep(),x.op2.rep());}
00157
00158 template<class R,class X> inline
00159 void assign(R & r,const OP<'*',X,int> & x) {mul(r,x.op1.rep(),x.op2);}
00160 template<class R,class X,class Y> inline
00161 void assign(R & r,const OP<'*',X,Y> & x) {mul(r.rep(),x.op1.rep(),x.op2.rep());}
00162
00163 template<class R,class X> inline
00164 void assign(R & r,const OP<'/',X,int> & x) {div(r,x.op1.rep(),x.op2);}
00165 template<class R,class X,class Y> inline
00166 void assign(R & r,const OP<'/',X,Y> & x) {div(r.rep(),x.op1.rep(),x.op2.rep());}
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 template<class V, class S>
00204 void assign(V & r, const OP<'*',VAL<S>,V> M)
00205 {
00206 V a=M.op1; r=a*M.op2;
00207 }
00208 template<class V, class S>
00209 void assign(V & r, const OP<'*',V,VAL<S> > M)
00210 {
00211 V b=M.op2; r=M.op1*b;
00212 }
00213 template<class V, class S, class T>
00214 void assign(V & r, const OP<'*',VAL<S>,VAL<T> > M)
00215 {
00216 V a=M.op1, b=M.op2; r=a*b;
00217 }
00218
00219 template<class V, class S>
00220 void assign(V & r, const OP<'.',VAL<S>,V> & M)
00221 {
00222 V a=M.op1; r=a*M.op2;
00223 }
00224 template<class V, class S>
00225 void assign(V & r, const OP<'.',V,VAL<S> > & M)
00226 {
00227 V b=M.op2; r=M.op1*b;
00228 }
00229 template<class V, class S, class T>
00230 void assign(V & r, const OP<'.',VAL<S>,VAL<T> > & M)
00231 {
00232 V a=M.op1, b=M.op2; r=a*b;
00233 }
00234
00235 template<class V, class S>
00236 void assign(V & r, const OP<'/',VAL<S>,V> & M)
00237 {
00238 V a=M.op1; r=a/M.op2;
00239 }
00240 template<class V, class S>
00241 void assign(V & r, const OP<'/',V,VAL<S> > & M)
00242 {
00243 V b=M.op2; r=M.op1/b;
00244 }
00245 template<class V, class S, class T>
00246 void assign(V & r, const OP<'/',VAL<S>,VAL<T> > & M)
00247 {
00248 V a=M.op1, b=M.op2; r=a/b;
00249 }
00250 }
00251
00252 template<class A>
00253 struct Promote {typedef A TYPE;};
00254
00255 template<char c,class A,class B>
00256 struct Promote<OP<c,A,B> > {typedef typename Promote<A>::TYPE TYPE;};
00257
00258 template<class A>
00259 struct Promote<VAL<A> > {typedef typename Promote<A>::TYPE TYPE;};
00260
00261
00262
00263
00264 __END_NAMESPACE_SYNAPS
00265
00266
00267 #endif // SYNAPS_ARITHM_REF_H
00268