// This may look like C code, but it is really -*- C++ -*- // Gestion de block de donnees avec partage de references // C.Magneville 04/99 // LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA #ifndef NDATABLOCK_H #define NDATABLOCK_H #include "machdefs.h" #include /* pour que size_t soit defini */ #include "anydataobj.h" #include namespace SOPHYA { //////////////////////////////////////////////////////////////// //// ------------------- Class Bridge ----------------------- // //////////////////////////////////////////////////////////////// /*! \class Bridge \ingroup BaseTools This class is use by NDataBlock. It allows sharing of datas with external structures : by example, if you want to connect a Blitz data structure with a NDataBlock or a TMatrix or ... \sa NDataBlock */ // Classe pour permettre de partager des donnees avec // un autre systeme de gestion de references (ex avec Blitz) //! Empty class which allows data sharing with external structures (for NDataBlock) class Bridge { public: Bridge() { } virtual ~Bridge() { } }; //////////////////////////////////////////////////////////////// //// ----------------- Class NDataBlock --------------------- // //////////////////////////////////////////////////////////////// // classe de container avec partage de reference //! Container of data with reference sharing template class NDataBlock : public AnyDataObj { public: // Methodes statiques pour debug. static void SetPrintDebug(int prtdbglevel=1); static void ResetDebug(size_t nallocdata=0, size_t nallocsref=0); static void PrintDebug(); // Creation / destruction NDataBlock(size_t n); NDataBlock(size_t n, T* data, Bridge* br=NULL); NDataBlock(); NDataBlock(const NDataBlock& a); NDataBlock(const NDataBlock& a,bool share); virtual ~NDataBlock(); // Temporaire? //! Return true if data block is temporay inline bool IsTemp(void) const {return mIsTemp;} //! Set temporary caracter of data block inline void SetTemp(bool temp=false) const {mIsTemp = temp;} // Depuis que le createur par copie partage les donnees // la seule utilisation de SetTemp et pour faire les operations du type: // NDataBlock = NDataBlock + NDataBlock + NDataBlock ... // Gestion taille/Remplissage void Clone(const NDataBlock& a); void CloneOrShare(const NDataBlock& a); void Share(const NDataBlock& a); void FillFrom(size_t n,T* data); //! Re-set all data values to \b v inline void Reset(T v=0) {if(mSz==0) return; T *p=Begin(),*pe=End(); while(pdata; else return NULL;} //! Return pointer on data structure. inline T* Data() const {if(mSRef) return mSRef->data; else return NULL;} //! Return the size of the data structure inline size_t Size() const {return mSz;} //! Return the \b i th element of the data structure inline T& operator()(size_t i) {return *(mSRef->data+i);} //! Return the \b i th element of the data structure inline T operator()(size_t i) const {return *(mSRef->data+i);} //! Return pointer to the beginning of the data structure. inline T* Begin() {return mSRef->data;} //! Return pointer to the beginning of the data structure. inline T const* Begin() const {return mSRef->data;} //! Return pointer to the end of the data structure. inline T* End() {return mSRef->data+mSz;} //! Return pointer to the end of the data structure. inline T const* End() const {return mSRef->data+mSz;} //! Return the number of references to the data structure inline size_t NRef() const {if(mSRef) return 0; else return mSRef->nref;} // Impression void Print(ostream& os, size_t i1=0,size_t n=10) const; //! print infos and datas (from \b i1 to \b i2) on stdout. inline void Print(size_t i1=0,size_t n=0) const {Print(cout,i1,n);} // T Sum(size_t i1=0,size_t n=0) const; T Product(size_t i1=0,size_t n=0) const; // Surcharge d'operateurs INPLACE: A = x , A = B , A @= x , A @= B NDataBlock& operator = (const NDataBlock& a); NDataBlock& operator = (T v); NDataBlock& operator += (T b); NDataBlock& operator -= (T b); NDataBlock& operator *= (T b); NDataBlock& operator /= (T b); NDataBlock& operator += (const NDataBlock& a); NDataBlock& operator -= (const NDataBlock& a); NDataBlock& operator *= (const NDataBlock& a); NDataBlock& operator /= (const NDataBlock& a); // Surcharge d'operateurs: C = A @ x , C = A @ B NDataBlock Add(T b) const; NDataBlock Sub(T b,bool fginv=false) const; NDataBlock Mul(T b) const; NDataBlock Div(T b,bool fginv=false) const; NDataBlock Add(const NDataBlock& b) const; NDataBlock Sub(const NDataBlock& b) const; NDataBlock Mul(const NDataBlock& b) const; NDataBlock Div(const NDataBlock& b) const; inline uint_8 DRefId() { return mSRef->dsid; } protected: //! NDREF structure for reference management typedef struct { size_t nref; //!< Number of references to the data structure uint_8 dsid; //!< Data structure Id - Used by FIO_NDataBlock T* data; //!< Pointer to data structure itself Bridge* bridge; //!< Pointer to a bridge for the data structure } NDREF; void Alloc(size_t n,T* data=NULL,Bridge* br=NULL, bool zero=true); void Delete(void); static int Debug_NDataBlock; //!< DEBUG: set debug level (all type classes) static size_t NallocData; //!< DEBUG: number of allocations (all type classes) static size_t NallocSRef; //!< DEBUG: number of references (all type classes) size_t mSz; //!< size of data structure NDREF* mSRef; //!< NDREF structure for reference management mutable bool mIsTemp; //!< true if class is temporary }; //! Define operator \<\< for printing template inline ostream& operator << (ostream& os, const NDataBlock& a) {a.Print(os); return(os);} //! Add a constant to datas and return NDataBlock : ND = NDa + b template inline NDataBlock operator + (const NDataBlock& a,T b) {return a.Add(b);} //! Add a constant to datas and return NDataBlock : ND = b + NDa template inline NDataBlock operator + (T b,const NDataBlock& a) {return a.Add(b);} //! Substract a constant to datas and return NDataBlock : ND = NDa - b template inline NDataBlock operator - (const NDataBlock& a,T b) {return a.Sub(b);} //! Substract a constant to datas and return NDataBlock : ND = b - NDa template inline NDataBlock operator - (T b,const NDataBlock& a) {return a.Sub(b,true);} //! Multiply datas by a constant and return NDataBlock : ND = NDa * b template inline NDataBlock operator * (const NDataBlock& a,T b) {return a.Mul(b);} //! Multiply datas by a constant and return NDataBlock : ND = b * NDa template inline NDataBlock operator * (T b,const NDataBlock& a) {return a.Mul(b);} //! Divide datas by a constant and return NDataBlock : ND = NDa / b template inline NDataBlock operator / (const NDataBlock& a,T b) {return a.Div(b);} //! Divide a constant by datas and return NDataBlock : ND = b / NDa template inline NDataBlock operator / (T b,const NDataBlock& a) {return a.Div(b,true);} //! Add datas of two data blocks and return NDataBlock : ND = NDa + NDb template inline NDataBlock operator + (const NDataBlock& a,const NDataBlock& b) {return a.Add(b);} //! Substract datas of two data blocks and return NDataBlock : ND = NDa - NDb template inline NDataBlock operator - (const NDataBlock& a,const NDataBlock& b) {return a.Sub(b);} //! Multiply datas of two data blocks and return NDataBlock : ND = NDa * NDb template inline NDataBlock operator * (const NDataBlock& a,const NDataBlock& b) {return a.Mul(b);} //! Divide datas of two data blocks and return NDataBlock : ND = NDa / NDb template inline NDataBlock operator / (const NDataBlock& a,const NDataBlock& b) {return a.Div(b);} } // Fin du namespace #endif