// This may look like C code, but it is really -*- C++ -*- // template array class for numerical types // R. Ansari, C.Magneville 03/2000 #ifndef TArray_SEEN #define TArray_SEEN #include "machdefs.h" #include #include #include "basarr.h" #include "ndatablock.h" #include #include "utilarr.h" namespace SOPHYA { // Forward declaration template class FIO_TArray; // --------------------------- classe template Array ----------------------- // ( See BaseArray class for data organisation in memory and related methods ) template class TArray : public BaseArray { public: // Creation / destruction TArray(); TArray(uint_4 ndim, uint_4 * siz, uint_4 step =1); TArray(uint_4 nx, uint_4 ny=0, uint_4 nz=0); TArray(uint_4 ndim, uint_4 * siz, NDataBlock & db, bool share=false, uint_4 step=1, uint_8 offset=0); TArray(uint_4 ndim, uint_4 * siz, T* values, uint_4 step=1, uint_8 offset=0, Bridge* br=NULL); TArray(const TArray& a); TArray(const TArray& a, bool share); virtual ~TArray(); // A = B : partage les donnees si "a" est temporaire, clone sinon. virtual TArray& operator = (const TArray& a); // Gestion taille/Remplissage virtual void Clone(const TArray& a); virtual void ReSize(uint_4 ndim, uint_4 * siz, uint_4 step=1); virtual void Realloc(uint_4 ndim, uint_4 * siz, uint_4 step=1, bool force=false); // Compacts size=1 array dimensions virtual TArray& CompactAllDimensions(); virtual TArray& CompactTrailingDimensions(); // SubArrays virtual TArray operator () (Range rx, Range ry, Range rz=0, Range rt=0, Range ru=0); // ---- Access to data // Definition of virtual element acces method inherited from BaseArray class virtual double ValueAtPosition(uint_8 ip) const; // Data Access: operator overloaded inline acces methods inline T const& operator()(uint_4 ix, uint_4 iy, uint_4 iz) const ; inline T& operator()(uint_4 ix, uint_4 iy, uint_4 iz); inline T const& operator()(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it, uint_4 iu=0) const ; inline T& operator()(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it, uint_4 iu=0); inline T const& operator[](uint_8 ip) const ; inline T& operator[](uint_8 ip); inline T const& Elem(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it=0, uint_4 iu=0) const ; inline T& Elem(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it=0, uint_4 iu=0); inline T const& ElemCheckBound(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it=0, uint_4 iu=0) const ; inline T& ElemCheckBound(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it=0, uint_4 iu=0); inline T* Data() {return mNDBlock.Begin()+offset_;} inline const T* Data() const {return mNDBlock.Begin()+offset_;} inline NDataBlock& DataBlock() {return mNDBlock;} inline const NDataBlock& DataBlock() const {return mNDBlock;} // Temporaire? inline bool IsTemp(void) const {return mNDBlock.IsTemp();} inline void SetTemp(bool temp=false) const {mNDBlock.SetTemp(temp);} // Operations diverses = , +=, ... // Conversion en type T, if Size() == 1 inline T toScalar(); // Met les elements a une suite de valeurs virtual TArray& operator = (Sequence seq); // A = x (tous les elements a x) virtual TArray& operator = (T x); // A += -= *= /= x (ajoute, soustrait, ... x a tous les elements) virtual TArray& operator += (T x); virtual TArray& operator -= (T x); virtual TArray& operator *= (T x); virtual TArray& operator /= (T x); // A += -= (ajoute, soustrait element par element les deux tableaux ) virtual TArray& operator += (const TArray& a); virtual TArray& operator -= (const TArray& a); // Multiplication, division element par element les deux tableaux virtual TArray& MultElt(const TArray& a); virtual TArray& DivElt(const TArray& a); // Impression, I/O, ... virtual string DataType() const; // definition of abstract method inherited from BaseArray virtual void Print(ostream& os, int_4 maxprt=-1, bool si=false) const ; // Pour la gestion de persistance friend class FIO_TArray; protected: // partage les donnees si "a" temporaire, clone sinon. void CloneOrShare(const TArray& a); // Share: partage les donnees de "a" void Share(const TArray& a); NDataBlock mNDBlock; // Le bloc des donnees }; //////////////////////////////////////////////////////////////// // Surcharge d'operateur << template inline ostream& operator << (ostream& os, const TArray& a) { a.Print(os); return(os); } //////////////////////////////////////////////////////////////// // Surcharge d'operateurs A (+,-,*,/) (T) x template inline TArray operator + (const TArray& a, T b) {TArray result(a); result.SetTemp(true); result += b; return result;} template inline TArray operator + (T b,const TArray& a) {TArray result(a); result.SetTemp(true); result += b; return result;} template inline TArray operator - (const TArray& a, T b) {TArray result(a); result.SetTemp(true); result -= b; return result;} template inline TArray operator - (T b,const TArray& a) {TArray result(a); result.SetTemp(true); result.DataBlock() = b-result.DataBlock(); return result;} template inline TArray operator * (const TArray& a, T b) {TArray result(a); result.SetTemp(true); result *= b; return result;} template inline TArray operator * (T b,const TArray& a) {TArray result(a); result.SetTemp(true); result *= b; return result;} template inline TArray operator / (const TArray& a, T b) {TArray result(a); result.SetTemp(true); result /= b; return result;} //////////////////////////////////////////////////////////////// // Surcharge d'operateurs C = A (+,-) B template inline TArray operator + (const TArray& a,const TArray& b) {TArray result(a); result.SetTemp(true); result += b; return result;} template inline TArray operator - (const TArray& a,const TArray& b) {TArray result(a); result.SetTemp(true); result += b; return result;} // -------------------------------------------------- // inline element acces methods // -------------------------------------------------- template inline T const& TArray::Elem(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it, uint_4 iu) const { return ( *( mNDBlock.Begin()+ offset_+ ix*step_[0] + iy*step_[1] + iz*step_[2] + it*step_[3] + iu*step_[4]) ); } template inline T & TArray::Elem(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it, uint_4 iu) { return ( *( mNDBlock.Begin()+ offset_+ ix*step_[0] + iy*step_[1] + iz*step_[2] + it*step_[3] + iu*step_[4]) ); } template inline T const& TArray::ElemCheckBound(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it, uint_4 iu) const { CheckBound(ix, iy, iz, it, iu, 4); Elem(ix, iy, iz, it, iu); } template inline T & TArray::ElemCheckBound(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it, uint_4 iu) { CheckBound(ix, iy, iz, it, iu, 4); Elem(ix, iy, iz, it, iu); } template inline T const& TArray::operator()(uint_4 ix, uint_4 iy, uint_4 iz) const { #ifdef SO_BOUNDCHECKING CheckBound(ix, iy, iz, 0, 0, 4); #endif return ( *( mNDBlock.Begin()+ offset_+ ix*step_[0] + iy*step_[1] + iz*step_[2]) ); } template inline T & TArray::operator()(uint_4 ix, uint_4 iy, uint_4 iz) { #ifdef SO_BOUNDCHECKING CheckBound(ix, iy, iz, 0, 0, 4); #endif return ( *( mNDBlock.Begin()+ offset_+ ix*step_[0] + iy*step_[1] + iz*step_[2]) ); } template inline T const& TArray::operator()(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it, uint_4 iu) const { #ifdef SO_BOUNDCHECKING CheckBound(ix, iy, iz, it, iu, 4); #endif return ( *( mNDBlock.Begin()+ offset_+ ix*step_[0] + iy*step_[1] + iz*step_[2] + it*step_[3] + iu*step_[4]) ); } template inline T & TArray::operator()(uint_4 ix, uint_4 iy, uint_4 iz, uint_4 it, uint_4 iu) { #ifdef SO_BOUNDCHECKING CheckBound(ix, iy, iz, it, iu, 4); #endif return ( *( mNDBlock.Begin()+ offset_+ ix*step_[0] + iy*step_[1] + iz*step_[2] + it*step_[3] + iu*step_[4]) ); } template inline T const& TArray::operator[](uint_8 ip) const { #ifdef SO_BOUNDCHECKING if (ip >= totsize_) throw( ParmError("TArray::operator[] Out-of-bound Error") ); #endif return *(mNDBlock.Begin()+Offset(ip)); } template inline T & TArray::operator[](uint_8 ip) { #ifdef SO_BOUNDCHECKING if (ip >= totsize_) throw( ParmError("TArray::operator[] Out-of-bound Error") ); #endif return *(mNDBlock.Begin()+Offset(ip)); } template inline T TArray::toScalar() { if (Size() != 1) throw(SzMismatchError("TArray::operator T() Size() != 1")) ; return ( (*this)[0] ); } } // Fin du namespace #endif