00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00031 template<int N, class Type>
00032 class Array;
00033
00034
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
00043 template<class Op, class TL, class TR>
00044 struct BCalculate;
00045
00046
00047 template<class Type>
00048 struct Iterator;
00049
00050
00051 template<int N, class Type>
00052 class Array<N,Iterator<Type> >;
00053
00054
00055
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
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
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
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
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
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
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
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
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
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
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