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 #include <cassert>
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
00590 for(int n=0; n<=fixrank; n++) {
00591 if(src.Stride(n)!=stride[n]) {
00592 Dealloc();
00593 return false;
00594 }
00595 }
00596
00597 for(int n=fixrank+1; n<N; n++) {
00598 if(src.Stride(n)<src.Stride(n-1) ||
00599 src.Stride(n)%src.Stride(n-1) != 0) {
00600 Dealloc();
00601 return false;
00602 }
00603 }
00604 data=src.Data();
00605 origo=src.Origo();
00606 for(int n=0; n<N; n++) {
00607 l[n]=src.L(n);
00608 u[n]=src.U(n);
00609 stride[n]=src.Stride(n);
00610 }
00611 }
00612 return true;
00613 }
00614
00615 template<int N, class T0>
00616 template<class TypeS>
00617 inline bool
00618 Array<N,Fix<T0> >::Realloc(const Array<N,TypeS> &src) {
00619 int totsize;
00620 for(int n=0; n<fixrank; n++)
00621 if(src.Len(n)!=0 && src.Len(n)*stride[n]!=stride[n+1]) {
00622 return false;
00623 }
00624 for(int n=0; n<N; n++) {
00625 l[n]=src.L(n);
00626 u[n]=src.U(n);
00627 }
00628 totsize=stride[fixrank]*Len(fixrank);
00629 for(int n=fixrank+1; n<N; n++) {
00630 stride[n]=totsize;
00631 totsize*=Len(n);
00632 }
00633 data=MultiPtr<T>(totsize);
00634 origo=data.Data()-IndexInternal::Recurse<fixrank+1,N>::SumProd(stride,l)-
00635 FixInternal::FixInfo<FixType,0,true>::Offset(l);
00636 return true;
00637 }
00638
00639 template<int N, class T0>
00640 template<class TypeS>
00641 inline bool
00642 Array<N,Fix<T0> >::Clone(const Array<N,TypeS> &src) {
00643 Array<N,Fix<T0> > foo;
00644 if(!foo.Realloc(src))
00645 return false;
00646 if(!foo.IsNull())
00647 foo<<=src;
00648 *this=foo;
00649 return true;
00650 }
00651
00652 template<int N, class T0>
00653 inline Array<N,Fix<T0> > &
00654 Array<N,Fix<T0> >::Shift(DIMT n, IXTYPE i) {
00655 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00656 l[n]+=i;
00657 u[n]+=i;
00658 origo-=i*stride[n];
00659 return *this;
00660 }
00661
00662 template<int N, class T0>
00663 inline Array<N,Fix<T0> > &
00664 Array<N,Fix<T0> >::Shift(const Ix<N> &ix) {
00665 for(int n=0; n<N; n++)
00666 Shift(n,ix[n]);
00667 return *this;
00668 }
00669
00670 template<int N, class T0>
00671 inline Array<N,Fix<T0> > &
00672 Array<N,Fix<T0> >::RestrictL(DIMT n, IXTYPE l0) {
00673 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00674 l[n]=std::max(l[n],l0);
00675 if(l[n]>=u[n]) {
00676 l[n]=u[n];
00677 data.clear();
00678 }
00679 return *this;
00680 }
00681
00682 template<int N, class T0>
00683 inline Array<N,Fix<T0> > &
00684 Array<N,Fix<T0> >::RestrictL(const Ix<N> &l0) {
00685 for(int n=0; n<N; n++) {
00686 l[n]=std::max(l[n],l0[n]);
00687 if(l[n]>=u[n]) {
00688 l[n]=u[n];
00689 data.clear();
00690 break;
00691 }
00692 }
00693 return *this;
00694 }
00695
00696 template<int N, class T0>
00697 inline Array<N,Fix<T0> > &
00698 Array<N,Fix<T0> >::RestrictU(DIMT n, IXTYPE u0) {
00699 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00700 u[n]=std::min(u[n],u0);
00701 if(u[n]<=l[n]) {
00702 u[n]=l[n];
00703 data.clear();
00704 }
00705 return *this;
00706 }
00707
00708 template<int N, class T0>
00709 inline Array<N,Fix<T0> > &
00710 Array<N,Fix<T0> >::RestrictU(const Ix<N> &u0) {
00711 for(int n=0; n<N; n++) {
00712 u[n]=std::min(u[n],u0[n]);
00713 if(u[n]<=l[n]) {
00714 u[n]=l[n];
00715 data.clear();
00716 break;
00717 }
00718 }
00719 return *this;
00720 }
00721
00722 template<int N, class T0>
00723 inline Array<N,Fix<T0> > &
00724 Array<N,Fix<T0> >::Restrict(DIMT n, IXTYPE l0, IXTYPE u0) {
00725 EXPRESSO_DEBUG_CHECK_DIM(0<=n && n<N);
00726 l[n]=std::max(l[n],l0);
00727 u[n]=std::min(u[n],u0);
00728 if(l[n]>=u[n]) {
00729 l[n]=u[n];
00730 data.clear();
00731 }
00732 return *this;
00733 }
00734
00735 template<int N, class T0>
00736 inline Array<N,Fix<T0> > &
00737 Array<N,Fix<T0> >::Restrict(const Ix<N> &l0, const Ix<N> &u0) {
00738 for(int n=0; n<N; n++) {
00739 l[n]=std::max(l[n],l0[n]);
00740 u[n]=std::min(u[n],u0[n]);
00741 if(l[n]>=u[n]) {
00742 l[n]=u[n];
00743 data.clear();
00744 break;
00745 }
00746 }
00747 return *this;
00748 }
00749
00750 template<int N, class T0>
00751 inline
00752 Array<N,Fix<T0> >::Array(const Ix<varrank> &len0):
00753 data(fixtotlen*IndexInternal::Recurse<0,varrank>::Prod(len0)), origo(data.Data()),l(0)
00754 {
00755 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00756 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00757 #endif
00758 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00759 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00760 for(int n=fixrank; n<N; n++)
00761 u[n]=len0[n-fixrank];
00762 for(int n=fixrank+1; n<N; n++)
00763 stride[n]=stride[n-1]*len0[n-1-fixrank];
00764 }
00765
00766 template<int N, class T0>
00767 inline
00768 Array<N,Fix<T0> >::Array(const Ix<varrank> &len0, const Ix<N> &l0):
00769 data(fixtotlen*IndexInternal::Recurse<0,varrank>::Prod(len0)), origo(data.Data()),l(l0)
00770 {
00771 #ifdef EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE
00772 for(int k=0; k<varrank; k++) EXPRESSO_DEBUG_CHECK_NONEGATIVE_SIZE(0<=len0[k]);
00773 #endif
00774 FixInternal::FixInfo<FixType,0,(0<=fixrank)>::FillStride(stride);
00775 FixInternal::FixInfo<FixType,0,(0<fixrank)>::FillLen(u);
00776 for(int n=0; n<fixrank; n++)
00777 u[n]+=l[n];
00778 for(int n=fixrank; n<N; n++)
00779 u[n]=len0[n-fixrank]+l[n];
00780 for(int n=fixrank+1; n<N; n++)
00781 stride[n]=stride[n-1]*len0[n-1-fixrank];
00782 origo=origo-IndexInternal::Recurse<fixrank+1,N>::SumProd(stride,l)-
00783 FixInternal::FixInfo<FixType,0,true>::Offset(l);
00784 }
00785
00787
00788
00789 template<int N, class T0>
00790 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00791 Reverse(const Array<N,Fix<T0> > &src, DIMT n) {
00792 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Reverse(n);
00793 }
00794
00795 template<int N, class T0>
00796 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00797 Reverse(const Array<N,Fix<T0> > &src, const Ix<N,bool> &nx) {
00798 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Reverse(nx);
00799 }
00800
00801 template<int N, class T0>
00802 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00803 Flip(const Array<N,Fix<T0> > &src, DIMT n) {
00804 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Flip(n);
00805 }
00806
00807 template<int N, class T0>
00808 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00809 Flip(const Array<N,Fix<T0> > &src, const Ix<N,bool> &nx) {
00810 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Flip(nx);
00811 }
00812
00813 template<int N, class T0>
00814 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00815 Restride(const Array<N,Fix<T0> > &src, DIMT n, IXTYPE s) {
00816 return Array<N,typename TmplTools::ArrayInfo<T0>::T>
00817 (src).Restride(n,s);
00818 }
00819
00820 template<int N, class T0>
00821 inline Array<N,typename TmplTools::ArrayInfo<T0>::T>
00822 Restride(const Array<N,Fix<T0> > &src, const Ix<N> &sx) {
00823 return Array<N,typename TmplTools::ArrayInfo<T0>::T>
00824 (src).Restride(sx);
00825 }
00826
00827 template<int N, class T0>
00828 Array<N,typename TmplTools::ArrayInfo<T0>::T>
00829 Permute(const Array<N,Fix<T0> > &src, DIMT n1, DIMT n2) {
00830 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Permute(n1,n2);
00831 }
00832
00833 template<int N, class T0>
00834 Array<N,typename TmplTools::ArrayInfo<T0>::T>
00835 Permute(const Array<N,Fix<T0> > &src, const Permutation<N> &nx) {
00836 return Array<N,typename TmplTools::ArrayInfo<T0>::T>(src).Permute(nx);
00837 }
00838
00839 #ifdef __KCC
00840 template<class T>
00841 class KAI_workaround;
00842
00843 template<class T0>
00844 class KAI_workaround<Fix<T0> > {
00845 public:
00846 typedef typename TmplTools::ArrayInfo<T0>::T ReturnType;
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 template<int N>
00863 static Array<N-1,ReturnType>
00864 Rmdim(const Array<N,Fix<T0> > &src, DIMT n, IXTYPE i) {
00865 return Array<N-1,ReturnType>(src,n,i);
00866 }
00867 template<int N>
00868 static Array<N+1,ReturnType>
00869 Extend(const Array<N,Fix<T0> > &src, IXTYPE l0, IXTYPE u0) {
00870 return Array<N+1,ReturnType>().Extend(src,l0,u0);
00871 }
00872 };
00873 #else
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889 template<int N, class T0>
00890 inline Array<N-1,typename Array<N,Fix<T0> >::T>
00891 Rmdim(const Array<N,Fix<T0> > &src, DIMT n, IXTYPE i) {
00892 return Array<N-1,typename Array<N,Fix<T0> >::T>().Rmdim(src,n,i);
00893 }
00894 template<int N, class T0>
00895 inline Array<N+1,typename Array<N,Fix<T0> >::T>
00896 Extend(const Array<N,Fix<T0> > &src, IXTYPE l0, IXTYPE u0) {
00897 return Array<N+1,typename Array<N,Fix<T0> >::T>().Extend(src,l0,u0);
00898 }
00899 #endif
00900
00901 }
00902
00903 #endif