00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00033 template<int N, class Type>
00034 class Array;
00035
00036
00037 template<class Type>
00038 class Array<0,Type>;
00039
00040
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
00049 template<class Op, class TL, class TR>
00050 struct BCalculate;
00051
00052
00053 template<class Type>
00054 struct Iterator;
00055
00056 template<int N, class Type>
00057 class Array<N,Iterator<Type> >;
00058
00059
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
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
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
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
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
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
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
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
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
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
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