00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef EXPRESSO_FIXED_HDR
00022 #define EXPRESSO_FIXED_HDR
00023
00024 #include "debug.h"
00025 #include "tmpltool.h"
00026 #include "multiptr.h"
00027 #include "assign.h"
00028 #include "iterator.h"
00029 #include "permutation.h"
00030
00031 namespace esso {
00032
00034
00035 namespace FixInternal {
00036
00037 template<class T0, int M, bool Method>
00038 class FixInfo;
00039
00040 template<class T0, int M>
00041 class FixInfo<T0,M,true> {
00042 public:
00043 enum { rank = TmplTools::ArrayInfo<T0>::rank };
00044
00045 template<int N>
00046 static inline void FillStride(Ix<N> &stride) {
00047 stride[M] = TmplTools::ArrayInfoIndex<T0,M>::stride;
00048 FixInfo<T0,M+1,(M+1<=rank && M+1<N) >::FillStride(stride);
00049 }
00050 template<int N>
00051 static inline void FillLen(Ix<N> &len) {
00052 len[M] = TmplTools::ArrayInfoIndex<T0,M>::len;
00053 FixInfo<T0,M+1,(M+1<rank)>::FillLen(len);
00054 }
00055 template<int N>
00056 static inline IXTYPE Stride(const Ix<N> &stride) {
00057 return TmplTools::ArrayInfoIndex<T0,M>::stride;
00058 }
00059 template<int N>
00060 static inline IXTYPE Offset(const Ix<N> &ix) {
00061 return TmplTools::ArrayInfoIndex<T0,M>::stride*ix[M]+
00062 FixInfo<T0,M+1,(M+1<=rank && M+1<N) >::Offset(ix);
00063 }
00064 };
00065 template<class T0, int M>
00066 class FixInfo<T0,M,false> {
00067 public:
00068 template<int N>
00069 static inline void FillStride(Ix<N> &stride) {}
00070
00071 template<int N>
00072 static inline void FillLen(Ix<N> &len) {}
00073
00074 template<int N>
00075 static inline IXTYPE Stride(const Ix<N> &stride) {
00076 return stride[M];
00077 }
00078 template<int N>
00079 static inline IXTYPE Offset(const Ix<N> &l) { return 0; }
00080 };
00081
00082 template<bool Method>
00083 class Assign {
00084 public:
00085 template<int N, class T0, class TypeS>
00086 static inline bool Do(Array<N,Fix<T0> >&dest, const Array<N,TypeS> &src) {
00087 return dest.Refer(src);
00088 }
00089 };
00090
00091 template<>
00092 class Assign<false> {
00093 public:
00094 template<int N, class T0, class TypeS>
00095 static inline bool Do(Array<N,Fix<T0> >&dest, const Array<N,TypeS> &src) {
00096 return dest.Clone(src);
00097 }
00098 };
00099 }
00100
00102
00134 template<int N, class T0>
00135 class Array<N,Fix<T0> > {
00136 public:
00137 friend class Array<N,Fix<typename TmplTools::FlipConst<T0>::T> >;
00139
00140 typedef T0 FixType;
00141 typedef typename TmplTools::ArrayInfo<T0>::T T;
00142 enum { hasdata=1 };
00143 enum { fixrank=TmplTools::ArrayInfo<T0>::rank };
00144 enum { fixtotlen=TmplTools::ArrayInfo<T0>::totlen };
00145 enum { varrank=N-fixrank };
00146 typedef Fix<T0> Type;
00147 typedef Array<N,Iterator<Type> > IteratorType;
00148 typedef TmplTools::TAssert<(varrank>0)> check;
00149
00152
00154 inline Array(): data(), origo(0) ,l(0) ,u(0) {
00155 FixInternal::FixInfo<FixType,0,true>::FillStride(stride);
00156 }
00158 inline Array(const Ix<varrank> &len0);
00161 inline Array(const Ix<varrank> &len0, const Ix<N> &l0);
00164 inline Array(const Array &src):
00165 data(src.data), origo(src.origo), l(src.l), u(src.u), stride(src.stride)
00166 {}
00171 template<class TypeS>
00172 inline Array(const Array<N,TypeS> &src) {
00173 FixInternal::FixInfo<FixType,0,true>::FillStride(stride);
00174 FixInternal::Assign
00175 <(Array<N,TypeS>::hasdata &&
00176 (TmplTools::IsSame<T,
00177 typename Array<N,TypeS>::T>::check ||
00178 TmplTools::IsSame<typename TmplTools::UnConst<T>::T,
00179 typename Array<N,TypeS>::T>::check))>
00180 ::Do(*this,src);
00181 }
00184 inline Array(IXTYPE i0):
00185 data(fixtotlen*i0), origo(data.Data()),l(0) {
00186 TmplTools::TAssert<(varrank==1)>();
00187 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0);
00188 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00189 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00190 u[fixrank]=i0;
00191 }
00194 inline Array(IXTYPE i0, IXTYPE i1):
00195 data(fixtotlen*i0*i1), origo(data.Data()),l(0) {
00196 TmplTools::TAssert<(varrank==2)>();
00197 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1);
00198 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00199 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00200 u[fixrank]=i0;
00201 u[fixrank+1]=i1;
00202 stride[fixrank+1]=stride[fixrank]*i0;
00203 }
00206 inline Array(IXTYPE i0, IXTYPE i1, IXTYPE i2):
00207 data(fixtotlen*i0*i1*i2), origo(data.Data()),l(0) {
00208 TmplTools::TAssert<(varrank==3)>();
00209 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1 && 0<=i2);
00210 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00211 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00212 u[fixrank]=i0;
00213 u[fixrank+1]=i1;
00214 u[fixrank+2]=i2;
00215 stride[fixrank+1]=stride[fixrank]*i0;
00216 stride[fixrank+2]=stride[fixrank+1]*i1;
00217 }
00220 inline Array(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3):
00221 data(fixtotlen*i0*i1*i2*i3), origo(data.Data()),l(0) {
00222 TmplTools::TAssert<(varrank==4)>();
00223 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1 && 0<=i2 && 0<=i3);
00224 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00225 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00226 u[fixrank]=i0;
00227 u[fixrank+1]=i1;
00228 u[fixrank+2]=i2;
00229 u[fixrank+3]=i3;
00230 stride[fixrank+1]=stride[fixrank]*i0;
00231 stride[fixrank+2]=stride[fixrank+1]*i1;
00232 stride[fixrank+3]=stride[fixrank+2]*i2;
00233 }
00236 inline Array(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3, IXTYPE i4):
00237 data(fixtotlen*i0*i1*i2*i3*i4), origo(data.Data()),l(0) {
00238 TmplTools::TAssert<(varrank==5)>();
00239 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1 && 0<=i2 && 0<=i3 && 0<=i4);
00240 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00241 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00242 u[fixrank]=i0;
00243 u[fixrank+1]=i1;
00244 u[fixrank+2]=i2;
00245 u[fixrank+3]=i3;
00246 u[fixrank+4]=i4;
00247 stride[fixrank+1]=stride[fixrank]*i0;
00248 stride[fixrank+2]=stride[fixrank+1]*i1;
00249 stride[fixrank+3]=stride[fixrank+2]*i2;
00250 stride[fixrank+4]=stride[fixrank+3]*i3;
00251 }
00254 inline Array(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3, IXTYPE i4, IXTYPE i5):
00255 data(fixtotlen*i0*i1*i2*i3*i4*i5), origo(data.Data()),l(0) {
00256 TmplTools::TAssert<(varrank==6)>();
00257 EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=i0 && 0<=i1 && 0<=i2 && 0<=i3 && 0<=i4 && 0<=i5);
00258 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00259 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00260 u[fixrank]=i0;
00261 u[fixrank+1]=i1;
00262 u[fixrank+2]=i2;
00263 u[fixrank+3]=i3;
00264 u[fixrank+4]=i4;
00265 u[fixrank+5]=i5;
00266 stride[fixrank+1]=stride[fixrank]*i0;
00267 stride[fixrank+2]=stride[fixrank+1]*i1;
00268 stride[fixrank+3]=stride[fixrank+2]*i2;
00269 stride[fixrank+4]=stride[fixrank+3]*i3;
00270 stride[fixrank+5]=stride[fixrank+4]*i4;
00271 }
00275
00278 inline IXTYPE L(DIMT n) const {
00279 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00280 return l[n];
00281 }
00285 inline IXTYPE U(DIMT n) const {
00286 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00287 return u[n];
00288 }
00293 inline IXTYPE Len(DIMT n) const {
00294 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00295 return u[n]-l[n];
00296 }
00301 inline IXTYPE Stride(DIMT n) const {
00302 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00303 return stride[n];
00304 }
00309 inline T * Origo() const { return origo; }
00314 inline T * Start() const { return & operator [](l); }
00318 inline const MultiPtr<T> &Data() const { return data; }
00320 inline bool IsNull() const { return data.Data()==0; }
00324
00327 inline bool Dealloc();
00331 inline bool Realloc(const Ix<varrank> &len0);
00335 inline bool Realloc(const Ix<varrank> &len0, const Ix<N> &l0);
00341 inline bool Realloc(const Ix<varrank> &len0, const Ix<N> &l0,
00342 const MultiPtr<T> &data0, T * origo0);
00347 template<class TypeS>
00348 inline bool Realloc(const Array<N,TypeS> &src);
00352 template<class TypeS>
00353 inline bool Refer(const Array<N,TypeS> &src);
00356 inline bool Clone();
00364 template<class TypeS>
00365 inline bool Clone(const Array<N,TypeS> &src);
00369 template<class TypeS>
00370 inline Array & operator =(const Array<N,TypeS> &src) {
00371 FixInternal::Assign
00372 <(Array<N,TypeS>::hasdata &&
00373 (TmplTools::IsSame<T,typename Array<N,TypeS>::T>::check ||
00374 TmplTools::IsSame<typename TmplTools::UnConst<T>::T,
00375 typename Array<N,TypeS>::T>::check))>
00376 ::Do(*this,src);
00377 return *this;
00378 }
00380 inline Array & operator =(const Array &src) {
00381 data=src.data;
00382 origo=src.origo;
00383 l=src.l;
00384 u=src.u;
00385 stride=src.stride;
00386 return *this;
00387 }
00389 inline Array & Shift(DIMT n, IXTYPE i);
00391 inline Array & Shift(const Ix<N> &ix);
00396 inline Array & Restrict(DIMT n, IXTYPE l0, IXTYPE u0);
00398 inline Array & Restrict(const Ix<N> &l0, const Ix<N> &u0);
00400 inline Array & RestrictL(DIMT n, IXTYPE l0);
00402 inline Array & RestrictL(const Ix<N> &l0);
00404 inline Array & RestrictU(DIMT n, IXTYPE u0);
00406 inline Array & RestrictU(const Ix<N> &u0);
00408
00409 inline T & operator ()(IXTYPE i0) const {
00410 TmplTools::TAssert<(N==1)>();
00411 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]);
00412 return *(origo+
00413 i0);
00414 }
00416 inline T & operator ()(IXTYPE i0, IXTYPE i1) const {
00417 TmplTools::TAssert<(N==2)>();
00418 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00419 && l[1]<=i1 && i1<u[1]);
00420 return *(origo+
00421 FixInternal::FixInfo<T0,1,(fixrank>=1)>::Stride(stride)*i1+
00422 i0);
00423 }
00425 inline T & operator ()(IXTYPE i0, IXTYPE i1, IXTYPE i2) const {
00426 TmplTools::TAssert<(N==3)>();
00427 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00428 && l[1]<=i1 && i1<u[1]
00429 && l[2]<=i2 && i2<u[2]);
00430 return *(origo+
00431 FixInternal::FixInfo<T0,2,(fixrank>=2)>::Stride(stride)*i2+
00432 FixInternal::FixInfo<T0,1,(fixrank>=1)>::Stride(stride)*i1+
00433 i0);
00434 }
00436 inline T & operator ()(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3) const {
00437 TmplTools::TAssert<(N==4)>();
00438 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00439 && l[1]<=i1 && i1<u[1]
00440 && l[2]<=i2 && i2<u[2]
00441 && l[3]<=i3 && i3<u[3]);
00442 return *(origo+
00443 FixInternal::FixInfo<T0,3,(fixrank>=3)>::Stride(stride)*i3+
00444 FixInternal::FixInfo<T0,2,(fixrank>=2)>::Stride(stride)*i2+
00445 FixInternal::FixInfo<T0,1,(fixrank>=1)>::Stride(stride)*i1+
00446 i0);
00447 }
00449 inline T & operator ()(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3, IXTYPE i4) const {
00450 TmplTools::TAssert<(N==5)>();
00451 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00452 && l[1]<=i1 && i1<u[1]
00453 && l[2]<=i2 && i2<u[2]
00454 && l[3]<=i3 && i3<u[3]
00455 && l[4]<=i4 && i4<u[4]);
00456 return *(origo+
00457 FixInternal::FixInfo<T0,4,(fixrank>=4)>::Stride(stride)*i4+
00458 FixInternal::FixInfo<T0,3,(fixrank>=3)>::Stride(stride)*i3+
00459 FixInternal::FixInfo<T0,2,(fixrank>=2)>::Stride(stride)*i2+
00460 FixInternal::FixInfo<T0,1,(fixrank>=1)>::Stride(stride)*i1+
00461 i0);
00462 }
00464 inline T & operator ()(IXTYPE i0, IXTYPE i1, IXTYPE i2, IXTYPE i3, IXTYPE i4, IXTYPE i5) const {
00465 TmplTools::TAssert<(N==6)>();
00466 EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[0]<=i0 && i0<u[0]
00467 && l[1]<=i1 && i1<u[1]
00468 && l[2]<=i2 && i2<u[2]
00469 && l[3]<=i3 && i3<u[3]
00470 && l[4]<=i4 && i4<u[4]
00471 && l[5]<=i5 && i5<u[5]);
00472 return *(origo+
00473 FixInternal::FixInfo<T0,5,(fixrank>=5)>::Stride(stride)*i5+
00474 FixInternal::FixInfo<T0,4,(fixrank>=4)>::Stride(stride)*i4+
00475 FixInternal::FixInfo<T0,3,(fixrank>=3)>::Stride(stride)*i3+
00476 FixInternal::FixInfo<T0,2,(fixrank>=2)>::Stride(stride)*i2+
00477 FixInternal::FixInfo<T0,1,(fixrank>=1)>::Stride(stride)*i1+
00478 i0);
00479 }
00481 inline T & operator [](const Ix<N> &ix) const {
00482 #ifdef EXPRESSO_DEBUG_CHECK_INDEXING_RANGE
00483 for(int k=0; k<N; k++) EXPRESSO_DEBUG_CHECK_INDEXING_RANGE(l[k]<=ix[k] && ix[k]<u[k]);
00484 #endif
00485 return *(origo+
00486 IndexInternal::Recurse<fixrank+1,N>::SumProd(stride,ix)+
00487 FixInternal::FixInfo<FixType,0,true>::Offset(ix));
00488 }
00489
00491
00492
00494
00495
00497
00498 private:
00500 MultiPtr<T> data;
00502 T *origo;
00504 Ix<N> l;
00506 Ix<N> u;
00509 Ix<N> stride;
00510 };
00511
00512 template<int N, class T0>
00513 inline bool
00514 Array<N,Fix<T0> >::Dealloc() {
00515 data=MultiPtr<T>();
00516 origo=data.Data();
00517 l=0;
00518 u=0;
00519 for(int n=fixrank+1; n<N; n++)
00520 stride[n]=stride[fixrank];
00521 return true;
00522 }
00523
00524 template<int N, class T0>
00525 inline bool
00526 Array<N,Fix<T0> >::Clone() {
00527 return Clone(*this);
00528 }
00529
00530 template<int N, class T0>
00531 inline bool
00532 Array<N,Fix<T0> >::Realloc(const Ix<varrank> &len0) {
00533 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00534 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00535 #endif
00536 data=MultiPtr<T>(fixtotlen*IndexInternal::Recurse<0,varrank>::Prod(len0));
00537 origo=data.Data();
00538 l=0;
00539 FixInternal::FixInfo<FixType,0,0<fixrank>::FillLen(u);
00540 for(int n=fixrank; n<N; n++)
00541 u[n]=len0[n-fixrank];
00542 for(int n=fixrank+1; n<N; n++)
00543 stride[n]=stride[n-1]*len0[n-1-fixrank];
00544 return true;
00545 }
00546
00547 template<int N, class T0>
00548 inline bool
00549 Array<N,Fix<T0> >::Realloc(const Ix<varrank> &len0, const Ix<N> &l0) {
00550 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00551 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00552 #endif
00553 Realloc(len0);
00554 l=l0;
00555 for(int n=0; n<N; n++)
00556 u[n]+=l0[n];
00557 origo=origo-IndexInternal::Recurse<fixrank+1,N>::SumProd(stride,l)
00558 -FixInternal::FixInfo<FixType,0,true>::Offset(l);
00559 return true;
00560 }
00561
00562 template<int N, class T0>
00563 inline bool
00564 Array<N,Fix<T0> >::Realloc(const Ix<varrank> &len0, const Ix<N> &l0,
00565 const MultiPtr<T> &data0, T *origo0) {
00566 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00567 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00568 #endif
00569 data=data0;
00570 origo=origo0;
00571 l=l0;
00572 FixInternal::FixInfo<FixType,0,0<fixrank>::FillLen(u);
00573 for(int n=0; n<fixrank; n++)
00574 u[n]+=l[n];
00575 for(int n=fixrank; n<N; n++)
00576 u[n]=len0[n-fixrank]+l[n];
00577 for(int n=fixrank+1; n<N; n++)
00578 stride[n]=stride[n-1]*len0[n-1-fixrank];
00579 return true;
00580 }
00581
00582 template<int N, class T0>
00583 template<class TypeS>
00584 inline bool
00585 Array<N,Fix<T0> >::Refer(const Array<N,TypeS> &src) {
00586 if(src.IsNull())
00587 Dealloc();
00588 else {
00589 for(int n=0; n<=fixrank; n++)
00590 if(src.Stride(n)!=stride[n]) {
00591 Dealloc();
00592 return false;
00593 }
00594 data=src.Data();
00595 origo=src.Origo();
00596 for(int n=0; n<N; n++) {
00597 l[n]=src.L(n);
00598 u[n]=src.U(n);
00599 stride[n]=src.Stride(n);
00600 }
00601 }
00602 return true;
00603 }
00604
00605 template<int N, class T0>
00606 template<class TypeS>
00607 inline bool
00608 Array<N,Fix<T0> >::Realloc(const Array<N,TypeS> &src) {
00609 int totsize;
00610 for(int n=0; n<fixrank; n++)
00611 if(src.Len(n)!=0 && src.Len(n)*stride[n]!=stride[n+1]) {
00612 return false;
00613 }
00614 for(int n=0; n<N; n++) {
00615 l[n]=src.L(n);
00616 u[n]=src.U(n);
00617 }
00618 totsize=stride[fixrank]*Len(fixrank);
00619 for(int n=fixrank+1; n<N; n++) {
00620 stride[n]=totsize;
00621 totsize*=Len(n);
00622 }
00623 data=MultiPtr<T>(totsize);
00624 origo=data.Data()-IndexInternal::Recurse<fixrank+1,N>::SumProd(stride,l)-
00625 FixInternal::FixInfo<FixType,0,true>::Offset(l);
00626 return true;
00627 }
00628
00629 template<int N, class T0>
00630 template<class TypeS>
00631 inline bool
00632 Array<N,Fix<T0> >::Clone(const Array<N,TypeS> &src) {
00633 Array<N,Fix<T0> > foo;
00634 if(!foo.Realloc(src))
00635 return false;
00636 foo<<=src;
00637 *this=foo;
00638 return true;
00639 }
00640
00641 template<int N, class T0>
00642 inline Array<N,Fix<T0> > &
00643 Array<N,Fix<T0> >::Shift(DIMT n, IXTYPE i) {
00644 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00645 l[n]+=i;
00646 u[n]+=i;
00647 origo-=i*stride[n];
00648 return *this;
00649 }
00650
00651 template<int N, class T0>
00652 inline Array<N,Fix<T0> > &
00653 Array<N,Fix<T0> >::Shift(const Ix<N> &ix) {
00654 for(int n=0; n<N; n++)
00655 Shift(n,ix[n]);
00656 return *this;
00657 }
00658
00659 template<int N, class T0>
00660 inline Array<N,Fix<T0> > &
00661 Array<N,Fix<T0> >::RestrictL(DIMT n, IXTYPE l0) {
00662 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00663 l[n]=std::max(l[n],l0);
00664 if(l[n]>=u[n]) {
00665 l[n]=u[n];
00666 data.clear();
00667 }
00668 return *this;
00669 }
00670
00671 template<int N, class T0>
00672 inline Array<N,Fix<T0> > &
00673 Array<N,Fix<T0> >::RestrictL(const Ix<N> &l0) {
00674 for(int n=0; n<N; n++) {
00675 l[n]=std::max(l[n],l0[n]);
00676 if(l[n]>=u[n]) {
00677 l[n]=u[n];
00678 data.clear();
00679 break;
00680 }
00681 }
00682 return *this;
00683 }
00684
00685 template<int N, class T0>
00686 inline Array<N,Fix<T0> > &
00687 Array<N,Fix<T0> >::RestrictU(DIMT n, IXTYPE u0) {
00688 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00689 u[n]=std::min(u[n],u0);
00690 if(u[n]<=l[n]) {
00691 u[n]=l[n];
00692 data.clear();
00693 }
00694 return *this;
00695 }
00696
00697 template<int N, class T0>
00698 inline Array<N,Fix<T0> > &
00699 Array<N,Fix<T0> >::RestrictU(const Ix<N> &u0) {
00700 for(int n=0; n<N; n++) {
00701 u[n]=std::min(u[n],u0[n]);
00702 if(u[n]<=l[n]) {
00703 u[n]=l[n];
00704 data.clear();
00705 break;
00706 }
00707 }
00708 return *this;
00709 }
00710
00711 template<int N, class T0>
00712 inline Array<N,Fix<T0> > &
00713 Array<N,Fix<T0> >::Restrict(DIMT n, IXTYPE l0, IXTYPE u0) {
00714 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00715 l[n]=std::max(l[n],l0);
00716 u[n]=std::min(u[n],u0);
00717 if(l[n]>=u[n]) {
00718 l[n]=u[n];
00719 data.clear();
00720 }
00721 return *this;
00722 }
00723
00724 template<int N, class T0>
00725 inline Array<N,Fix<T0> > &
00726 Array<N,Fix<T0> >::Restrict(const Ix<N> &l0, const Ix<N> &u0) {
00727 for(int n=0; n<N; n++) {
00728 l[n]=std::max(l[n],l0[n]);
00729 u[n]=std::min(u[n],u0[n]);
00730 if(l[n]>=u[n]) {
00731 l[n]=u[n];
00732 data.clear();
00733 break;
00734 }
00735 }
00736 return *this;
00737 }
00738
00739 template<int N, class T0>
00740 inline
00741 Array<N,Fix<T0> >::Array(const Ix<varrank> &len0):
00742 data(fixtotlen*IndexInternal::Recurse<0,varrank>::Prod(len0)), origo(data.Data()),l(0)
00743 {
00744 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00745 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00746 #endif
00747 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00748 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00749 for(int n=fixrank; n<N; n++)
00750 u[n]=len0[n-fixrank];
00751 for(int n=fixrank+1; n<N; n++)
00752 stride[n]=stride[n-1]*len0[n-1-fixrank];
00753 }
00754
00755 template<int N, class T0>
00756 inline
00757 Array<N,Fix<T0> >::Array(const Ix<varrank> &len0, const Ix<N> &l0):
00758 data(fixtotlen*IndexInternal::Recurse<0,varrank>::Prod(len0)), origo(data.Data()),l(l0)
00759 {
00760 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00761 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00762 #endif
00763 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00764 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00765 for(int n=0; n<fixrank; n++)
00766 u[n]+=l[n];
00767 for(int n=fixrank; n<N; n++)
00768 u[n]=len0[n-fixrank]+l[n];
00769 for(int n=fixrank+1; n<N; n++)
00770 stride[n]=stride[n-1]*len0[n-1-fixrank];
00771 origo=origo-IndexInternal::Recurse<fixrank+1,N>::SumProd(stride,l)-
00772 FixInternal::FixInfo<FixType,0,true>::Offset(l);
00773 }
00774
00776
00777
00778 template<int N, class T0>
00779 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00780 Reverse(const Array<N,Fix<T0> > &src, DIMT n) {
00781 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Reverse(n);
00782 }
00783
00784 template<int N, class T0>
00785 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00786 Reverse(const Array<N,Fix<T0> > &src, const Ix<N,bool> &nx) {
00787 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Reverse(nx);
00788 }
00789
00790 template<int N, class T0>
00791 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00792 Flip(const Array<N,Fix<T0> > &src, DIMT n) {
00793 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Flip(n);
00794 }
00795
00796 template<int N, class T0>
00797 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00798 Flip(const Array<N,Fix<T0> > &src, const Ix<N,bool> &nx) {
00799 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Flip(nx);
00800 }
00801
00802 template<int N, class T0>
00803 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00804 Restride(const Array<N,Fix<T0> > &src, DIMT n, IXTYPE s) {
00805 return Array<N,typename TmplTools::ArrayInfo<T0>::T>
00806 (src).Restride(n,s);
00807 }
00808
00809 template<int N, class T0>
00810 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00811 Restride(const Array<N,Fix<T0> > &src, const Ix<N> &sx) {
00812 return Array<N,typename TmplTools::ArrayInfo<T0>::T>
00813 (src).Restride(sx);
00814 }
00815
00816 template<int N, class T0>
00817 Array<N,typename TmplTools::ArrayInfo<T0>::T>
00818 Permute(const Array<N,Fix<T0> > &src, DIMT n1, DIMT n2) {
00819 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Permute(n1,n2);
00820 }
00821
00822 template<int N, class T0>
00823 Array<N,typename TmplTools::ArrayInfo<T0>::T>
00824 Permute(const Array<N,Fix<T0> > &src, const Permutation<N> &nx) {
00825 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Permute(nx);
00826 }
00827
00828 #ifdef __KCC
00829 template<class T>
00830 class KAI_workaround;
00831
00832 template<class T0>
00833 class KAI_workaround<Fix<T0> > {
00834 public:
00835 typedef typename TmplTools::ArrayInfo<T0>::T ReturnType;
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 template<int N>
00852 static Array<N-1,ReturnType>
00853 Rmdim(const Array<N,Fix<T0> > &src, DIMT n, IXTYPE i) {
00854 return Array<N-1,ReturnType>(src,n,i);
00855 }
00856 template<int N>
00857 static Array<N+1,ReturnType>
00858 Extend(const Array<N,Fix<T0> > &src, IXTYPE l0, IXTYPE u0) {
00859 return Array<N+1,ReturnType>().Extend(src,l0,u0);
00860 }
00861 };
00862 #else
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878 template<int N, class T0>
00879 inline Array<N-1,typename Array<N,Fix<T0> >::T>
00880 Rmdim(const Array<N,Fix<T0> > &src, DIMT n, IXTYPE i) {
00881 return Array<N-1,typename Array<N,Fix<T0> >::T>().Rmdim(src,n,i);
00882 }
00883 template<int N, class T0>
00884 inline Array<N+1,typename Array<N,Fix<T0> >::T>
00885 Extend(const Array<N,Fix<T0> > &src, IXTYPE l0, IXTYPE u0) {
00886 return Array<N+1,typename Array<N,Fix<T0> >::T>().Extend(src,l0,u0);
00887 }
00888 #endif
00889
00890 }
00891
00892 #endif