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

fix.h

00001 /* -*- c++ -*- */
00002 /*
00003  * Expresso, a C++ Array template class library
00004  * Copyright (C) 1998,2004 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_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 // Some template magic for use internally by Array<N,Fix<T> > methods
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 // typedefs and enums
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 // Constructors
00492 
00494 // Assignment operator
00495 
00497 // Private data
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       // Check so that fixed ranks have the correct strides
00590       for(int n=0; n<=fixrank; n++) {
00591         if(src.Stride(n)!=stride[n]) {
00592           Dealloc();
00593           return false;
00594         }
00595       }
00596       // Check so that variable ranks are in order
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 // Functions on Fix arrays:
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     template<int N>
00849     static Array<N-1,Fix<T0> >
00850     Rmdim(const Array<N,Fix<T0> > &src, IXTYPE i) {
00851       Array<N-1,Fix<T0> > ret;
00852       Ix<N-1> len0,l0;
00853       for(int n=0; n<N-1; n++)
00854         len0[n]=src.Len(n);
00855       for(int n=0; n<N-1; n++)
00856         l0[n]=src.L(n);
00857       
00858       ret.Realloc(len0,l0,src.Data(),src.Origo());
00859       return ret;
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   template<int N, class T0>
00876   inline Array<N-1,Fix<T0> >
00877   Rmdim(const Array<N,Fix<T0> > &src, IXTYPE i) {
00878     Array<N-1,Fix<T0> > ret;
00879     Ix<N-1> len0,l0;
00880     for(int n=0; n<N-1; n++)
00881       len0[n]=src.Len(n);
00882     for(int n=0; n<N-1; n++)
00883       l0[n]=src.L(n);
00884 
00885     ret.Realloc(len0,l0,src.Data(),src.Origo());
00886     return ret;
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

Generated on Thu Jun 3 00:21:25 2004 for Expresso by doxygen 1.3.3