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

base.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_BASE_HDR
00022 #define EXPRESSO_BASE_HDR
00023 
00024 #include "error.h"
00025 #include "index.h"
00026 
00027 #include <algorithm>
00028 
00030 namespace esso {
00031 
00032   // Array base template declaration
00033   template<int N, class Type>
00034   class Array;
00035 
00036   // Rank 0 not allowed:
00037   template<class Type>
00038   class Array<0,Type>;
00039 
00040   // Promotion template declaration
00041   template<class Op, class ST>
00042   struct UPromote;
00043   template<class Op, class LT, class RT>
00044   struct BPromote;
00045   template<class Op, class T0>
00046   struct RPromote;
00047 
00048   // Template used for calculation in binary operators
00049   template<class Op, class TL, class TR>
00050   struct BCalculate;
00051 
00052   // The general iterator type
00053   template<class Type>
00054   struct Iterator;
00055 
00056   template<int N, class Type>
00057   class Array<N,Iterator<Type> >;
00058 
00059   // The elementwize copy assignment operator
00060   template<int K>
00061   struct Assign {
00062     template<int N, class DType, class ST>
00063     static inline void DoScalar(Array<N,DType> &dst,
00064                                 const ST src, 
00065                                 const Ix<N> &len) {
00066       for(IXTYPE i=len[K-1]; i>0; --i) {
00067         // Note that 'i' is not an array index
00068         Assign<K-1>::DoScalar(dst,src,len);
00069         dst.Step(K-1);
00070       }
00071       dst.Step(K-1,-len[K-1]);
00072     }
00073     template<int N, class DType, class SType>
00074     static inline void Do(Array<N,DType> &dst,
00075                           Array<N,SType> &src, 
00076                           const Ix<N> &len) {
00077       for(IXTYPE i=len[K-1]; i>0; --i) {
00078         // Note that 'i' is not an array index
00079         Assign<K-1>::Do(dst,src,len);
00080         dst.Step(K-1);
00081         src.Step(K-1);
00082       }
00083       dst.Step(K-1,-len[K-1]);
00084       src.Step(K-1,-len[K-1]);
00085     }
00086     template<int N, class DType, class ST>
00087     static inline void AddScalar(Array<N,DType> &dst,
00088                                  const ST src, 
00089                                  const Ix<N> &len) {
00090       for(IXTYPE i=len[K-1]; i>0; --i) {
00091         // Note that 'i' is not an array index
00092         Assign<K-1>::AddScalar(dst,src,len);
00093         dst.Step(K-1);
00094       }
00095       dst.Step(K-1,-len[K-1]);
00096     }
00097     template<int N, class DType, class SType>
00098     static inline void Add(Array<N,DType> &dst,
00099                            Array<N,SType> &src, 
00100                           const Ix<N> &len) {
00101       for(IXTYPE i=len[K-1]; i>0; --i) {
00102         // Note that 'i' is not an array index
00103         Assign<K-1>::Add(dst,src,len);
00104         dst.Step(K-1);
00105         src.Step(K-1);
00106       }
00107       dst.Step(K-1,-len[K-1]);
00108       src.Step(K-1,-len[K-1]);
00109     }
00110     template<int N, class DType, class ST>
00111     static inline void SubScalar(Array<N,DType> &dst,
00112                                 const ST src, 
00113                                 const Ix<N> &len) {
00114       for(IXTYPE i=len[K-1]; i>0; --i) {
00115         // Note that 'i' is not an array index
00116         Assign<K-1>::SubScalar(dst,src,len);
00117         dst.Step(K-1);
00118       }
00119       dst.Step(K-1,-len[K-1]);
00120     }
00121     template<int N, class DType, class SType>
00122     static inline void Sub(Array<N,DType> &dst,
00123                           Array<N,SType> &src, 
00124                           const Ix<N> &len) {
00125       for(IXTYPE i=len[K-1]; i>0; --i) {
00126         // Note that 'i' is not an array index
00127         Assign<K-1>::Sub(dst,src,len);
00128         dst.Step(K-1);
00129         src.Step(K-1);
00130       }
00131       dst.Step(K-1,-len[K-1]);
00132       src.Step(K-1,-len[K-1]);
00133     }
00134     template<int N, class DType, class ST>
00135     static inline void MulScalar(Array<N,DType> &dst,
00136                                 const ST src, 
00137                                 const Ix<N> &len) {
00138       for(IXTYPE i=len[K-1]; i>0; --i) {
00139         // Note that 'i' is not an array index
00140         Assign<K-1>::MulScalar(dst,src,len);
00141         dst.Step(K-1);
00142       }
00143       dst.Step(K-1,-len[K-1]);
00144     }
00145     template<int N, class DType, class SType>
00146     static inline void Mul(Array<N,DType> &dst,
00147                           Array<N,SType> &src, 
00148                           const Ix<N> &len) {
00149       for(IXTYPE i=len[K-1]; i>0; --i) {
00150         // Note that 'i' is not an array index
00151         Assign<K-1>::Mul(dst,src,len);
00152         dst.Step(K-1);
00153         src.Step(K-1);
00154       }
00155       dst.Step(K-1,-len[K-1]);
00156       src.Step(K-1,-len[K-1]);
00157     }
00158     template<int N, class DType, class ST>
00159     static inline void DivScalar(Array<N,DType> &dst,
00160                                 const ST src, 
00161                                 const Ix<N> &len) {
00162       for(IXTYPE i=len[K-1]; i>0; --i) {
00163         // Note that 'i' is not an array index
00164         Assign<K-1>::DivScalar(dst,src,len);
00165         dst.Step(K-1);
00166       }
00167       dst.Step(K-1,-len[K-1]);
00168     }
00169     template<int N, class DType, class SType>
00170     static inline void Div(Array<N,DType> &dst,
00171                           Array<N,SType> &src, 
00172                           const Ix<N> &len) {
00173       for(IXTYPE i=len[K-1]; i>0; --i) {
00174         // Note that 'i' is not an array index
00175         Assign<K-1>::Div(dst,src,len);
00176         dst.Step(K-1);
00177         src.Step(K-1);
00178       }
00179       dst.Step(K-1,-len[K-1]);
00180       src.Step(K-1,-len[K-1]);
00181     }
00182   };
00183 
00184   template<>
00185   struct Assign<1> {
00186     template<int N, class DType, class ST>
00187     static inline void DoScalar(Array<N,DType> &dst, 
00188                                 const ST src, 
00189                                 const Ix<N> &len) {
00190       for(IXTYPE i=len[0]-1; i>=0; --i) {
00191         dst.Get(i)=src;
00192       }
00193     }
00194     template<int N, class DType, class SType>
00195     static inline void Do(const Array<N,DType> &dst,
00196                           const Array<N,SType> &src,
00197                           const Ix<N> &len) {
00198       for(IXTYPE i=len[0]-1; i>=0; --i) {
00199         dst.Get(i)=src.CGet(i);
00200       }
00201     }
00202     template<int N, class DType, class ST>
00203     static inline void AddScalar(Array<N,DType> &dst, 
00204                                  const ST src, 
00205                                  const Ix<N> &len) {
00206       for(IXTYPE i=len[0]-1; i>=0; --i) {
00207         dst.Get(i)+=src;
00208       }
00209     }
00210     template<int N, class DType, class SType>
00211     static inline void Add(const Array<N,DType> &dst,
00212                            const Array<N,SType> &src,
00213                            const Ix<N> &len) {
00214       for(IXTYPE i=len[0]-1; i>=0; --i) {
00215         dst.Get(i)+=src.CGet(i);
00216       }
00217     }
00218     template<int N, class DType, class ST>
00219     static inline void SubScalar(Array<N,DType> &dst, 
00220                                  const ST src, 
00221                                  const Ix<N> &len) {
00222       for(IXTYPE i=len[0]-1; i>=0; --i) {
00223         dst.Get(i)-=src;
00224       }
00225     }
00226     template<int N, class DType, class SType>
00227     static inline void Sub(const Array<N,DType> &dst,
00228                            const Array<N,SType> &src,
00229                            const Ix<N> &len) {
00230       for(IXTYPE i=len[0]-1; i>=0; --i) {
00231         dst.Get(i)-=src.CGet(i);
00232       }
00233     }
00234     template<int N, class DType, class ST>
00235     static inline void MulScalar(Array<N,DType> &dst, 
00236                                  const ST src, 
00237                                  const Ix<N> &len) {
00238       for(IXTYPE i=len[0]-1; i>=0; --i) {
00239         dst.Get(i)*=src;
00240       }
00241     }
00242     template<int N, class DType, class SType>
00243     static inline void Mul(const Array<N,DType> &dst,
00244                            const Array<N,SType> &src,
00245                            const Ix<N> &len) {
00246       for(IXTYPE i=len[0]-1; i>=0; --i) {
00247         dst.Get(i)*=src.CGet(i);
00248       }
00249     }
00250     template<int N, class DType, class ST>
00251     static inline void DivScalar(Array<N,DType> &dst, 
00252                                  const ST src, 
00253                                  const Ix<N> &len) {
00254       for(IXTYPE i=len[0]-1; i>=0; --i) {
00255         dst.Get(i)/=src;
00256       }
00257     }
00258     template<int N, class DType, class SType>
00259     static inline void Div(const Array<N,DType> &dst,
00260                            const Array<N,SType> &src,
00261                            const Ix<N> &len) {
00262       for(IXTYPE i=len[0]-1; i>=0; --i) {
00263         dst.Get(i)/=src.CGet(i);
00264       }
00265     }
00266   };
00267 
00268   template<int N, class DType, class SType>
00269   static inline void BeginAssign(Array<N,DType> &dst, 
00270                                  Array<N,SType> &src,
00271                                  Ix<N> & len) {
00272     for(DIMT k=0; k<N; k++) {
00273       IXTYPE l=std::max(dst.L(k),src.L(k));
00274       len[k]=std::min(dst.U(k),src.U(k))-l;
00275       EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(len[k]>0);
00276       dst.Step(k,l);
00277       src.Step(k,l);
00278     }
00279   }
00280   template<int N, class DType>
00281   static inline void BeginAssign(Array<N,DType> &dst,
00282                                  Ix<N> & len) {
00283     for(DIMT k=0; k<N; k++) {
00284       IXTYPE l=dst.L(k);
00285       len[k]=dst.U(k)-l;
00286       dst.Step(k,l);
00287     }
00288   }
00289 
00291 
00292 
00298   template<int N, class DType, class ST>
00299   inline const Array<N,DType> &
00300   operator <<=(const Array<N,DType> &dst, const ST & src) {
00301     Ix<N> len;
00302     typename Array<N,DType>::IteratorType dstit(dst);
00303     BeginAssign(dstit,len);
00304     Assign<N>::DoScalar(dstit,src,len);
00305     return dst;
00306   }
00327   template<int N, class DType, class SType>
00328   inline const Array<N,DType> &
00329   operator <<=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00330     Ix<N> len;
00331     typename Array<N,DType>::IteratorType dstit(dst);
00332     typename Array<N,SType>::IteratorType srcit(src);
00333     BeginAssign(dstit,srcit,len);
00334     Assign<N>::Do(dstit,srcit,len);
00335     return dst;
00336   }
00341   template<int N, class DType, class ST>
00342   inline const Array<N,DType> &
00343   operator +=(const Array<N,DType> &dst, const ST & src) {
00344     Ix<N> len;
00345     typename Array<N,DType>::IteratorType dstit(dst);
00346     BeginAssign(dstit,len);
00347     Assign<N>::AddScalar(dstit,src,len);
00348     return dst;
00349   }
00353   template<int N, class DType, class SType>
00354   inline const Array<N,DType> &
00355   operator +=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00356     Ix<N> len;
00357     typename Array<N,DType>::IteratorType dstit(dst);
00358     typename Array<N,SType>::IteratorType srcit(src);
00359     BeginAssign(dstit,srcit,len);
00360     Assign<N>::Add(dstit,srcit,len);
00361     return dst;
00362   }
00363 
00368   template<int N, class DType, class ST>
00369   inline const Array<N,DType> &
00370   operator -=(const Array<N,DType> &dst, const ST & src) {
00371     Ix<N> len;
00372     typename Array<N,DType>::IteratorType dstit(dst);
00373     BeginAssign(dstit,len);
00374     Assign<N>::SubScalar(dstit,src,len);
00375     return dst;
00376   }
00380   template<int N, class DType, class SType>
00381   inline const Array<N,DType> &
00382   operator -=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00383     Ix<N> len;
00384     typename Array<N,DType>::IteratorType dstit(dst);
00385     typename Array<N,SType>::IteratorType srcit(src);
00386     BeginAssign(dstit,srcit,len);
00387     Assign<N>::Sub(dstit,srcit,len);
00388     return dst;
00389   }
00390 
00395   template<int N, class DType, class ST>
00396   inline const Array<N,DType> &
00397   operator *=(const Array<N,DType> &dst, const ST & src) {
00398     Ix<N> len;
00399     typename Array<N,DType>::IteratorType dstit(dst);
00400     BeginAssign(dstit,len);
00401     Assign<N>::MulScalar(dstit,src,len);
00402     return dst;
00403   }
00407   template<int N, class DType, class SType>
00408   inline const Array<N,DType> &
00409   operator *=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00410     Ix<N> len;
00411     typename Array<N,DType>::IteratorType dstit(dst);
00412     typename Array<N,SType>::IteratorType srcit(src);
00413     BeginAssign(dstit,srcit,len);
00414     Assign<N>::Mul(dstit,srcit,len);
00415     return dst;
00416   }
00417 
00421   template<int N, class DType, class ST>
00422   inline const Array<N,DType> &
00423   operator /=(const Array<N,DType> &dst, const ST & src) {
00424     Ix<N> len;
00425     typename Array<N,DType>::IteratorType dstit(dst);
00426     BeginAssign(dstit,len);
00427     Assign<N>::DivScalar(dstit,src,len);
00428     return dst;
00429   }
00434   template<int N, class DType, class SType>
00435   inline const Array<N,DType> &
00436   operator /=(const Array<N,DType> &dst, const Array<N,SType> &src) {
00437     Ix<N> len;
00438     typename Array<N,DType>::IteratorType dstit(dst);
00439     typename Array<N,SType>::IteratorType srcit(src);
00440     BeginAssign(dstit,srcit,len);
00441     Assign<N>::Div(dstit,srcit,len);
00442     return dst;
00443   }
00445 }
00446 
00447 #endif

Generated on Tue May 11 16:15:55 2004 for Expresso by doxygen 1.3.3