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