Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members

assign.h

00001 /* -*- c++ -*- */
00002 /*
00003  * Expresso, a C++ Array template class library
00004  * Copyright (C) 1998 Oskar Enoksson (enok@lysator.liu.se)
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public
00017  * License along with this library; if not, write to the
00018  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019  * Boston, MA  02111-1307, USA.
00020  */
00021 #ifndef EXPRESSO_ASSIGN_HDR
00022 #define EXPRESSO_ASSIGN_HDR
00023 
00024 #include "ix.h"
00025 #include <algorithm>
00026 
00028 namespace esso {
00029 
00030   // Array base template declaration
00031   template<int N, class Type>
00032   class Array;
00033 
00034   // Promotion template declarations
00035   template<class Op, class ST>
00036   struct UPromote;
00037   template<class Op, class LT, class RT>
00038   struct BPromote;
00039   template<class Op, class T0>
00040   struct RPromote;
00041 
00042   // Template used for calculation in binary operators
00043   template<class Op, class TL, class TR>
00044   struct BCalculate;
00045 
00046   // The general iterator type
00047   template<class Type>
00048   struct Iterator;
00049 
00050   // The actual array iterator is an array template specialization (!)
00051   template<int N, class Type>
00052   class Array<N,Iterator<Type> >;
00053 
00054   // Template magic needed for recursion in 
00055   // elementwize assignment operator
00056   template<int K>
00057   struct Assign {
00058     template<int N, class DType, class ST>
00059     static inline void CopyScalar(Array<N,DType> &dst,
00060                                 const ST src, 
00061                                 const Ix<N> &len) {
00062       for(IXTYPE i=len[K-1]; i!=0; --i) {
00063         // Note that 'i' is not an array index
00064         Assign<K-1>::CopyScalar(dst,src,len);
00065         dst.Step(K-1);
00066       }
00067       dst.Step(K-1,-len[K-1]);
00068     }
00069     template<int N, class DType, class SType>
00070     static inline void Copy(Array<N,DType> &dst,
00071                           Array<N,SType> &src, 
00072                           const Ix<N> &len) {
00073       for(IXTYPE i=len[K-1]; i!=0; --i) {
00074         // Note that 'i' is not an array index
00075         Assign<K-1>::Copy(dst,src,len);
00076         dst.Step(K-1);
00077         src.Step(K-1);
00078       }
00079       dst.Step(K-1,-len[K-1]);
00080       src.Step(K-1,-len[K-1]);
00081     }
00082     template<int N, class DType, class ST>
00083     static inline void AddScalar(Array<N,DType> &dst,
00084                                  const ST src, 
00085                                  const Ix<N> &len) {
00086       for(IXTYPE i=len[K-1]; i!=0; --i) {
00087         // Note that 'i' is not an array index
00088         Assign<K-1>::AddScalar(dst,src,len);
00089         dst.Step(K-1);
00090       }
00091       dst.Step(K-1,-len[K-1]);
00092     }
00093     template<int N, class DType, class SType>
00094     static inline void Add(Array<N,DType> &dst,
00095                            Array<N,SType> &src, 
00096                           const Ix<N> &len) {
00097       for(IXTYPE i=len[K-1]; i!=0; --i) {
00098         // Note that 'i' is not an array index
00099         Assign<K-1>::Add(dst,src,len);
00100         dst.Step(K-1);
00101         src.Step(K-1);
00102       }
00103       dst.Step(K-1,-len[K-1]);
00104       src.Step(K-1,-len[K-1]);
00105     }
00106     template<int N, class DType, class ST>
00107     static inline void SubScalar(Array<N,DType> &dst,
00108                                 const ST src, 
00109                                 const Ix<N> &len) {
00110       for(IXTYPE i=len[K-1]; i!=0; --i) {
00111         // Note that 'i' is not an array index
00112         Assign<K-1>::SubScalar(dst,src,len);
00113         dst.Step(K-1);
00114       }
00115       dst.Step(K-1,-len[K-1]);
00116     }
00117     template<int N, class DType, class SType>
00118     static inline void Sub(Array<N,DType> &dst,
00119                           Array<N,SType> &src, 
00120                           const Ix<N> &len) {
00121       for(IXTYPE i=len[K-1]; i!=0; --i) {
00122         // Note that 'i' is not an array index
00123         Assign<K-1>::Sub(dst,src,len);
00124         dst.Step(K-1);
00125         src.Step(K-1);
00126       }
00127       dst.Step(K-1,-len[K-1]);
00128       src.Step(K-1,-len[K-1]);
00129     }
00130     template<int N, class DType, class ST>
00131     static inline void MulScalar(Array<N,DType> &dst,
00132                                 const ST src, 
00133                                 const Ix<N> &len) {
00134       for(IXTYPE i=len[K-1]; i!=0; --i) {
00135         // Note that 'i' is not an array index
00136         Assign<K-1>::MulScalar(dst,src,len);
00137         dst.Step(K-1);
00138       }
00139       dst.Step(K-1,-len[K-1]);
00140     }
00141     template<int N, class DType, class SType>
00142     static inline void Mul(Array<N,DType> &dst,
00143                           Array<N,SType> &src, 
00144                           const Ix<N> &len) {
00145       for(IXTYPE i=len[K-1]; i!=0; --i) {
00146         // Note that 'i' is not an array index
00147         Assign<K-1>::Mul(dst,src,len);
00148         dst.Step(K-1);
00149         src.Step(K-1);
00150       }
00151       dst.Step(K-1,-len[K-1]);
00152       src.Step(K-1,-len[K-1]);
00153     }
00154     template<int N, class DType, class ST>
00155     static inline void DivScalar(Array<N,DType> &dst,
00156                                 const ST src, 
00157                                 const Ix<N> &len) {
00158       for(IXTYPE i=len[K-1]; i!=0; --i) {
00159         // Note that 'i' is not an array index
00160         Assign<K-1>::DivScalar(dst,src,len);
00161         dst.Step(K-1);
00162       }
00163       dst.Step(K-1,-len[K-1]);
00164     }
00165     template<int N, class DType, class SType>
00166     static inline void Div(Array<N,DType> &dst,
00167                           Array<N,SType> &src, 
00168                           const Ix<N> &len) {
00169       for(IXTYPE i=len[K-1]; i!=0; --i) {
00170         // Note that 'i' is not an array index
00171         Assign<K-1>::Div(dst,src,len);
00172         dst.Step(K-1);
00173         src.Step(K-1);
00174       }
00175       dst.Step(K-1,-len[K-1]);
00176       src.Step(K-1,-len[K-1]);
00177     }
00178   };
00179 
00180   template<>
00181   struct Assign<1> {
00182     template<int N, class DType, class ST>
00183     static inline void CopyScalar(Array<N,DType> &dst, 
00184                                 const ST src, 
00185                                 const Ix<N> &len) {
00186       for(IXTYPE i=len[0]; --i>=0;) {
00187         dst.Get(i)=src;
00188       }
00189     }
00190     template<int N, class DType, class SType>
00191     static inline void Copy(const Array<N,DType> &dst,
00192                           const Array<N,SType> &src,
00193                           const Ix<N> &len) {
00194       for(IXTYPE i=len[0]; --i>=0;) {
00195         dst.Get(i)=src.CGet(i);
00196       }
00197     }
00198     template<int N, class DType, class ST>
00199     static inline void AddScalar(Array<N,DType> &dst, 
00200                                  const ST src, 
00201                                  const Ix<N> &len) {
00202       for(IXTYPE i=len[0]; --i>=0;) {
00203         dst.Get(i)+=src;
00204       }
00205     }
00206     template<int N, class DType, class SType>
00207     static inline void Add(const Array<N,DType> &dst,
00208                            const Array<N,SType> &src,
00209                            const Ix<N> &len) {
00210       for(IXTYPE i=len[0]; --i>=0;) {
00211         dst.Get(i)+=src.CGet(i);
00212       }
00213     }
00214     template<int N, class DType, class ST>
00215     static inline void SubScalar(Array<N,DType> &dst, 
00216                                  const ST src, 
00217                                  const Ix<N> &len) {
00218       for(IXTYPE i=len[0]; --i>=0;) {
00219         dst.Get(i)-=src;
00220       }
00221     }
00222     template<int N, class DType, class SType>
00223     static inline void Sub(const Array<N,DType> &dst,
00224                            const Array<N,SType> &src,
00225                            const Ix<N> &len) {
00226       for(IXTYPE i=len[0]; --i>=0;) {
00227         dst.Get(i)-=src.CGet(i);
00228       }
00229     }
00230     template<int N, class DType, class ST>
00231     static inline void MulScalar(Array<N,DType> &dst, 
00232                                  const ST src, 
00233                                  const Ix<N> &len) {
00234       for(IXTYPE i=len[0]; --i>=0;) {
00235         dst.Get(i)*=src;
00236       }
00237     }
00238     template<int N, class DType, class SType>
00239     static inline void Mul(const Array<N,DType> &dst,
00240                            const Array<N,SType> &src,
00241                            const Ix<N> &len) {
00242       for(IXTYPE i=len[0]; --i>=0;) {
00243         dst.Get(i)*=src.CGet(i);
00244       }
00245     }
00246     template<int N, class DType, class ST>
00247     static inline void DivScalar(Array<N,DType> &dst, 
00248                                  const ST src, 
00249                                  const Ix<N> &len) {
00250       for(IXTYPE i=len[0]; --i>=0;) {
00251         dst.Get(i)/=src;
00252       }
00253     }
00254     template<int N, class DType, class SType>
00255     static inline void Div(const Array<N,DType> &dst,
00256                            const Array<N,SType> &src,
00257                            const Ix<N> &len) {
00258       for(IXTYPE i=len[0]; --i>=0;) {
00259         dst.Get(i)/=src.CGet(i);
00260       }
00261     }
00262   };
00263 
00264   template<int N, class DType, class SType>
00265   static inline void BeginAssign(Array<N,DType> &dst, 
00266                                  Array<N,SType> &src,
00267                                  Ix<N> & len) {
00268     for(DIMT k=0; k<N; k++) {
00269       IXTYPE l=std::max(dst.L(k),src.L(k));
00270       len[k]=std::min(dst.U(k),src.U(k))-l;
00271       EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(len[k]>0);
00272       dst.Step(k,l);
00273       src.Step(k,l);
00274     }
00275   }
00276   template<int N, class DType>
00277   static inline void BeginAssign(Array<N,DType> &dst,
00278                                  Ix<N> & len) {
00279     for(DIMT k=0; k<N; k++) {
00280       IXTYPE l=dst.L(k);
00281       len[k]=dst.U(k)-l;
00282       dst.Step(k,l);
00283     }
00284   }
00285 
00287 
00288 
00294   template<int N, class DType, class ST>
00295   inline const Array<N,DType> &
00296   operator <<=(const Array<N,DType> &dst, const ST & src) {
00297     Ix<N> len;
00298     typename Array<N,DType>::IteratorType dstit(dst);
00299     BeginAssign(dstit,len);
00300     Assign<N>::CopyScalar(dstit,src,len);
00301     return dst;
00302   }
00323   template<int N, class DType, class SType>
00324   inline const Array<N,DType> &
00325   operator <<=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00326     Ix<N> len;
00327     typename Array<N,DType>::IteratorType dstit(dst);
00328     typename Array<N,SType>::IteratorType srcit(src);
00329     BeginAssign(dstit,srcit,len);
00330     Assign<N>::Copy(dstit,srcit,len);
00331     return dst;
00332   }
00337   template<int N, class DType, class ST>
00338   inline const Array<N,DType> &
00339   operator +=(const Array<N,DType> &dst, const ST & src) {
00340     Ix<N> len;
00341     typename Array<N,DType>::IteratorType dstit(dst);
00342     BeginAssign(dstit,len);
00343     Assign<N>::AddScalar(dstit,src,len);
00344     return dst;
00345   }
00349   template<int N, class DType, class SType>
00350   inline const Array<N,DType> &
00351   operator +=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00352     Ix<N> len;
00353     typename Array<N,DType>::IteratorType dstit(dst);
00354     typename Array<N,SType>::IteratorType srcit(src);
00355     BeginAssign(dstit,srcit,len);
00356     Assign<N>::Add(dstit,srcit,len);
00357     return dst;
00358   }
00359 
00364   template<int N, class DType, class ST>
00365   inline const Array<N,DType> &
00366   operator -=(const Array<N,DType> &dst, const ST & src) {
00367     Ix<N> len;
00368     typename Array<N,DType>::IteratorType dstit(dst);
00369     BeginAssign(dstit,len);
00370     Assign<N>::SubScalar(dstit,src,len);
00371     return dst;
00372   }
00376   template<int N, class DType, class SType>
00377   inline const Array<N,DType> &
00378   operator -=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00379     Ix<N> len;
00380     typename Array<N,DType>::IteratorType dstit(dst);
00381     typename Array<N,SType>::IteratorType srcit(src);
00382     BeginAssign(dstit,srcit,len);
00383     Assign<N>::Sub(dstit,srcit,len);
00384     return dst;
00385   }
00386 
00391   template<int N, class DType, class ST>
00392   inline const Array<N,DType> &
00393   operator *=(const Array<N,DType> &dst, const ST & src) {
00394     Ix<N> len;
00395     typename Array<N,DType>::IteratorType dstit(dst);
00396     BeginAssign(dstit,len);
00397     Assign<N>::MulScalar(dstit,src,len);
00398     return dst;
00399   }
00403   template<int N, class DType, class SType>
00404   inline const Array<N,DType> &
00405   operator *=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00406     Ix<N> len;
00407     typename Array<N,DType>::IteratorType dstit(dst);
00408     typename Array<N,SType>::IteratorType srcit(src);
00409     BeginAssign(dstit,srcit,len);
00410     Assign<N>::Mul(dstit,srcit,len);
00411     return dst;
00412   }
00413 
00417   template<int N, class DType, class ST>
00418   inline const Array<N,DType> &
00419   operator /=(const Array<N,DType> &dst, const ST & src) {
00420     Ix<N> len;
00421     typename Array<N,DType>::IteratorType dstit(dst);
00422     BeginAssign(dstit,len);
00423     Assign<N>::DivScalar(dstit,src,len);
00424     return dst;
00425   }
00430   template<int N, class DType, class SType>
00431   inline const Array<N,DType> &
00432   operator /=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00433     Ix<N> len;
00434     typename Array<N,DType>::IteratorType dstit(dst);
00435     typename Array<N,SType>::IteratorType srcit(src);
00436     BeginAssign(dstit,srcit,len);
00437     Assign<N>::Div(dstit,srcit,len);
00438     return dst;
00439   }
00441 }
00442 
00443 #endif

Generated on Wed May 12 13:34:34 2004 for Expresso by doxygen 1.3.3