| 1 | // This may look like C code, but it is really -*- C++ -*-
 | 
|---|
| 2 | // Gestion de block de donnees avec partage de references
 | 
|---|
| 3 | //                         C.Magneville          04/99
 | 
|---|
| 4 | // LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
 | 
|---|
| 5 | #ifndef NDATABLOCK_H
 | 
|---|
| 6 | #define NDATABLOCK_H
 | 
|---|
| 7 | 
 | 
|---|
| 8 | #include "machdefs.h"
 | 
|---|
| 9 | #include <stdlib.h>        /* pour que size_t soit defini */
 | 
|---|
| 10 | #include "anydataobj.h"
 | 
|---|
| 11 | #include <iostream>
 | 
|---|
| 12 | 
 | 
|---|
| 13 | namespace SOPHYA {
 | 
|---|
| 14 | 
 | 
|---|
| 15 | ////////////////////////////////////////////////////////////////
 | 
|---|
| 16 | //// ------------------- Class Bridge ----------------------- //
 | 
|---|
| 17 | ////////////////////////////////////////////////////////////////
 | 
|---|
| 18 | /*!
 | 
|---|
| 19 |   \class Bridge
 | 
|---|
| 20 |   \ingroup BaseTools
 | 
|---|
| 21 |   This class is use by NDataBlock. It allows sharing of datas
 | 
|---|
| 22 |   with external structures : by example, if you want to connect
 | 
|---|
| 23 |   a Blitz data structure with a NDataBlock or a TMatrix or ...
 | 
|---|
| 24 |   \sa NDataBlock
 | 
|---|
| 25 | */
 | 
|---|
| 26 | 
 | 
|---|
| 27 | // Classe pour permettre de partager des donnees avec 
 | 
|---|
| 28 | // un autre systeme de gestion de references (ex avec Blitz)
 | 
|---|
| 29 | //! Empty class which allows data sharing with external structures (for NDataBlock)
 | 
|---|
| 30 | class Bridge {
 | 
|---|
| 31 | public:
 | 
|---|
| 32 |   Bridge() { } 
 | 
|---|
| 33 |   virtual ~Bridge() { }
 | 
|---|
| 34 | };
 | 
|---|
| 35 | 
 | 
|---|
| 36 | ////////////////////////////////////////////////////////////////
 | 
|---|
| 37 | //// ----------------- Class NDataBlock --------------------- //
 | 
|---|
| 38 | ////////////////////////////////////////////////////////////////
 | 
|---|
| 39 | 
 | 
|---|
| 40 | // classe de container avec partage de reference
 | 
|---|
| 41 | //! Container of data with reference sharing
 | 
|---|
| 42 | template <class T>
 | 
|---|
| 43 | class NDataBlock : public AnyDataObj {
 | 
|---|
| 44 | 
 | 
|---|
| 45 | public:
 | 
|---|
| 46 | 
 | 
|---|
| 47 |   // Methodes statiques pour debug.
 | 
|---|
| 48 |   static void SetPrintDebug(int prtdbglevel=1);
 | 
|---|
| 49 |   static void ResetDebug(size_t nallocdata=0, size_t nallocsref=0);
 | 
|---|
| 50 |   static void PrintDebug();
 | 
|---|
| 51 | 
 | 
|---|
| 52 |   // Creation / destruction 
 | 
|---|
| 53 |   NDataBlock(size_t n, bool fzero=true);
 | 
|---|
| 54 |   NDataBlock(size_t n, T* data, Bridge* br=NULL);
 | 
|---|
| 55 |   NDataBlock();
 | 
|---|
| 56 |   NDataBlock(const NDataBlock<T>& a);
 | 
|---|
| 57 |   NDataBlock(const NDataBlock<T>& a,bool share);
 | 
|---|
| 58 |   virtual ~NDataBlock();
 | 
|---|
| 59 | 
 | 
|---|
| 60 |   // Temporaire?
 | 
|---|
| 61 |   //! Return true if data block is temporay
 | 
|---|
| 62 |   inline bool IsTemp(void) const {return mIsTemp;}
 | 
|---|
| 63 |   //! Set temporary caracter of data block
 | 
|---|
| 64 |   inline void SetTemp(bool temp=false) const {mIsTemp = temp;}
 | 
|---|
| 65 |   // Depuis que le createur par copie partage les donnees
 | 
|---|
| 66 |   // la seule utilisation de SetTemp et pour faire les operations du type:
 | 
|---|
| 67 |   // NDataBlock = NDataBlock + NDataBlock + NDataBlock ...
 | 
|---|
| 68 | 
 | 
|---|
| 69 |   // Gestion taille/Remplissage
 | 
|---|
| 70 |   void Clone(const NDataBlock<T>& a);
 | 
|---|
| 71 |   void CloneOrShare(const NDataBlock<T>& a);
 | 
|---|
| 72 |   void Share(const NDataBlock<T>& a);
 | 
|---|
| 73 |   void FillFrom(size_t n,T* data);
 | 
|---|
| 74 |   //! Re-set all data values to \b v
 | 
|---|
| 75 |   inline void Reset(T v=0)
 | 
|---|
| 76 |          {if(mSz==0) return; T *p=Begin(),*pe=End(); while(p<pe) *p++=v;}
 | 
|---|
| 77 | 
 | 
|---|
| 78 |   // ReSize redimmensionne une structure pour "n" donnees.
 | 
|---|
| 79 |   // Les donnees precedentes sont perdues (pour cette classe)
 | 
|---|
| 80 |   // et le nouveau tableau mis a zero si fzero=true. La nouvelle structure de
 | 
|---|
| 81 |   // donnees n'a qu'une reference (celle de cette classe).
 | 
|---|
| 82 |   //! Re-size the data structure
 | 
|---|
| 83 |   /*! Old datas are lost (for this class). The new values are set 
 | 
|---|
| 84 |     to zero if \b fzero=true .
 | 
|---|
| 85 |     The new data structure has only one reference (itself!). */
 | 
|---|
| 86 |   inline void ReSize(size_t n, bool fzero=true) {Alloc(n,NULL,NULL,fzero);}
 | 
|---|
| 87 | 
 | 
|---|
| 88 |   void Realloc(size_t nnew,bool force=false);
 | 
|---|
| 89 |   
 | 
|---|
| 90 |   //! Calls Delete() to set the size to zero (The memory is freed if last referenced structure)
 | 
|---|
| 91 |   inline void Dealloc() { Delete(); }
 | 
|---|
| 92 | 
 | 
|---|
| 93 |   // Informations pointeur/data
 | 
|---|
| 94 |   //! Return pointer on data structure.
 | 
|---|
| 95 |   inline T* Data()
 | 
|---|
| 96 |          {if(mSRef) return mSRef->data; else return NULL;}
 | 
|---|
| 97 |   //! Return pointer on data structure.
 | 
|---|
| 98 |   inline T* Data() const
 | 
|---|
| 99 |          {if(mSRef) return mSRef->data; else return NULL;}
 | 
|---|
| 100 |   //! Return the size of the data structure
 | 
|---|
| 101 |   inline size_t Size() const    {return mSz;}
 | 
|---|
| 102 |   //! Return the \b i th element of  the data structure
 | 
|---|
| 103 |   inline T& operator()(size_t i)       {return *(mSRef->data+i);}
 | 
|---|
| 104 |   //! Return the \b i th element of  the data structure
 | 
|---|
| 105 |   inline T  operator()(size_t i) const {return *(mSRef->data+i);}
 | 
|---|
| 106 |   //! Return pointer to the beginning of the data structure.
 | 
|---|
| 107 |   inline T*        Begin()        {return mSRef->data;}
 | 
|---|
| 108 |   //! Return pointer to the beginning of the data structure.
 | 
|---|
| 109 |   inline T const*  Begin() const  {return mSRef->data;} 
 | 
|---|
| 110 |   //! Return pointer to the end of the data structure.
 | 
|---|
| 111 |   inline T*        End()          {return mSRef->data+mSz;}
 | 
|---|
| 112 |   //! Return pointer to the end of the data structure.
 | 
|---|
| 113 |   inline T const*  End() const    {return mSRef->data+mSz;}
 | 
|---|
| 114 |   //! Return the number of references to the data structure
 | 
|---|
| 115 |   inline size_t NRef() const {if(mSRef) return mSRef->nref;  else return 0; }
 | 
|---|
| 116 | 
 | 
|---|
| 117 |   // Impression
 | 
|---|
| 118 |   void Print(ostream& os, size_t i1=0,size_t n=10) const;
 | 
|---|
| 119 |   //! print infos and datas (from \b i1 to \b i2) on stdout.
 | 
|---|
| 120 |   inline void Print(size_t i1=0,size_t n=0) const {Print(cout,i1,n);}
 | 
|---|
| 121 | 
 | 
|---|
| 122 |   //
 | 
|---|
| 123 |   T Sum(size_t i1=0,size_t n=0) const;
 | 
|---|
| 124 |   T Product(size_t i1=0,size_t n=0) const;
 | 
|---|
| 125 | 
 | 
|---|
| 126 |   // Surcharge d'operateurs INPLACE: A = x , A = B , A @= x , A @= B
 | 
|---|
| 127 |   NDataBlock<T>& operator = (const NDataBlock<T>& a);
 | 
|---|
| 128 |   NDataBlock<T>& operator = (T v);
 | 
|---|
| 129 | 
 | 
|---|
| 130 |   NDataBlock<T>& operator += (T b);
 | 
|---|
| 131 |   NDataBlock<T>& operator -= (T b);
 | 
|---|
| 132 |   NDataBlock<T>& operator *= (T b);
 | 
|---|
| 133 |   NDataBlock<T>& operator /= (T b);
 | 
|---|
| 134 | 
 | 
|---|
| 135 |   NDataBlock<T>& operator += (const NDataBlock<T>& a);
 | 
|---|
| 136 |   NDataBlock<T>& operator -= (const NDataBlock<T>& a);
 | 
|---|
| 137 |   NDataBlock<T>& operator *= (const NDataBlock<T>& a);
 | 
|---|
| 138 |   NDataBlock<T>& operator /= (const NDataBlock<T>& a);
 | 
|---|
| 139 | 
 | 
|---|
| 140 |   // Surcharge d'operateurs: C = A @ x , C = A @ B
 | 
|---|
| 141 |   NDataBlock<T> Add(T b) const;
 | 
|---|
| 142 |   NDataBlock<T> Sub(T b,bool fginv=false) const;
 | 
|---|
| 143 |   NDataBlock<T> Mul(T b) const;
 | 
|---|
| 144 |   NDataBlock<T> Div(T b,bool fginv=false) const;
 | 
|---|
| 145 | 
 | 
|---|
| 146 |   NDataBlock<T> Add(const NDataBlock<T>& b) const;
 | 
|---|
| 147 |   NDataBlock<T> Sub(const NDataBlock<T>& b) const;
 | 
|---|
| 148 |   NDataBlock<T> Mul(const NDataBlock<T>& b) const;
 | 
|---|
| 149 |   NDataBlock<T> Div(const NDataBlock<T>& b) const;
 | 
|---|
| 150 | 
 | 
|---|
| 151 |   //! Return thye associated object Id (or DataRef Id)
 | 
|---|
| 152 |   inline uint_8 DRefId() { return mSRef->dsid; }
 | 
|---|
| 153 |   //! assign a new object Id (or DataRef Id) - useful for PPF write operations 
 | 
|---|
| 154 |   inline void RenewDRefId() { mSRef->dsid = AnyDataObj::getUniqueId(); } 
 | 
|---|
| 155 |   //! assign a new object Id (or DataRef Id) - useful for PPF write operations 
 | 
|---|
| 156 |   inline void RenewObjId() { mSRef->dsid = AnyDataObj::getUniqueId(); }
 | 
|---|
| 157 |   
 | 
|---|
| 158 | 
 | 
|---|
| 159 | protected:
 | 
|---|
| 160 |   //! NDREF structure for reference management
 | 
|---|
| 161 |   typedef struct {
 | 
|---|
| 162 |     size_t nref;      //!< Number of references to the data structure
 | 
|---|
| 163 |     uint_8 dsid;      //!< Data structure Id - Used by FIO_NDataBlock
 | 
|---|
| 164 |     T* data;          //!< Pointer to data structure itself
 | 
|---|
| 165 |     Bridge* bridge;   //!< Pointer to a bridge for the data structure
 | 
|---|
| 166 |   } NDREF;
 | 
|---|
| 167 | 
 | 
|---|
| 168 |   void Alloc(size_t n,T* data=NULL,Bridge* br=NULL, bool zero=true);
 | 
|---|
| 169 |   void Delete(void);
 | 
|---|
| 170 | 
 | 
|---|
| 171 |   static int Debug_NDataBlock; //!< DEBUG: set debug level (all type<T> classes)
 | 
|---|
| 172 |   static size_t NallocData; //!< DEBUG: number of allocations (all type<T> classes)
 | 
|---|
| 173 |   static size_t NallocSRef; //!< DEBUG: number of references (all type<T> classes)
 | 
|---|
| 174 | 
 | 
|---|
| 175 |   size_t       mSz;      //!< size of data structure
 | 
|---|
| 176 |   NDREF*       mSRef;    //!< NDREF structure for reference management
 | 
|---|
| 177 |   mutable bool mIsTemp;  //!< true if class is temporary
 | 
|---|
| 178 | };
 | 
|---|
| 179 | 
 | 
|---|
| 180 | //! Define operator \<\< for printing
 | 
|---|
| 181 | template<class T>
 | 
|---|
| 182 | inline ostream& operator << (ostream& os, const NDataBlock<T>& a)
 | 
|---|
| 183 |                       {a.Print(os); return(os);}
 | 
|---|
| 184 | 
 | 
|---|
| 185 | //! Add a constant to datas and return NDataBlock : ND = NDa + b
 | 
|---|
| 186 | template<class T>
 | 
|---|
| 187 | inline NDataBlock<T> operator + (const NDataBlock<T>& a,T b)
 | 
|---|
| 188 |                       {return a.Add(b);}
 | 
|---|
| 189 | //! Add a constant to datas and return NDataBlock : ND = b + NDa
 | 
|---|
| 190 | template<class T>
 | 
|---|
| 191 | inline NDataBlock<T> operator + (T b,const NDataBlock<T>& a)
 | 
|---|
| 192 |                       {return a.Add(b);}
 | 
|---|
| 193 | //! Substract a constant to datas and return NDataBlock : ND = NDa - b
 | 
|---|
| 194 | template<class T>
 | 
|---|
| 195 | inline NDataBlock<T> operator - (const NDataBlock<T>& a,T b)
 | 
|---|
| 196 |                       {return a.Sub(b);}
 | 
|---|
| 197 | //! Substract a constant to datas and return NDataBlock : ND = b - NDa
 | 
|---|
| 198 | template<class T>
 | 
|---|
| 199 | inline NDataBlock<T> operator - (T b,const NDataBlock<T>& a)
 | 
|---|
| 200 |                       {return a.Sub(b,true);}
 | 
|---|
| 201 | //! Multiply datas by a constant and return NDataBlock : ND = NDa * b
 | 
|---|
| 202 | template<class T>
 | 
|---|
| 203 | inline NDataBlock<T> operator * (const NDataBlock<T>& a,T b)
 | 
|---|
| 204 |                       {return a.Mul(b);}
 | 
|---|
| 205 | //! Multiply datas by a constant and return NDataBlock : ND = b * NDa
 | 
|---|
| 206 | template<class T>
 | 
|---|
| 207 | inline NDataBlock<T> operator * (T b,const NDataBlock<T>& a)
 | 
|---|
| 208 |                       {return a.Mul(b);}
 | 
|---|
| 209 | //! Divide datas by a constant and return NDataBlock : ND = NDa / b
 | 
|---|
| 210 | template<class T>
 | 
|---|
| 211 | inline NDataBlock<T> operator / (const NDataBlock<T>& a,T b)
 | 
|---|
| 212 |                       {return a.Div(b);}
 | 
|---|
| 213 | //! Divide a constant by datas and return NDataBlock : ND = b / NDa
 | 
|---|
| 214 | template<class T>
 | 
|---|
| 215 | inline NDataBlock<T> operator / (T b,const NDataBlock<T>& a)
 | 
|---|
| 216 |                       {return a.Div(b,true);}
 | 
|---|
| 217 | 
 | 
|---|
| 218 | //! Add datas of two data blocks and return NDataBlock : ND = NDa + NDb
 | 
|---|
| 219 | template<class T>
 | 
|---|
| 220 | inline NDataBlock<T> operator + (const NDataBlock<T>& a,const NDataBlock<T>& b)
 | 
|---|
| 221 |                       {return a.Add(b);}
 | 
|---|
| 222 | //! Substract datas of two data blocks and return NDataBlock : ND = NDa - NDb
 | 
|---|
| 223 | template<class T>
 | 
|---|
| 224 | inline NDataBlock<T> operator - (const NDataBlock<T>& a,const NDataBlock<T>& b)
 | 
|---|
| 225 |                       {return a.Sub(b);}
 | 
|---|
| 226 | //! Multiply datas of two data blocks and return NDataBlock : ND = NDa * NDb
 | 
|---|
| 227 | template<class T>
 | 
|---|
| 228 | inline NDataBlock<T> operator * (const NDataBlock<T>& a,const NDataBlock<T>& b)
 | 
|---|
| 229 |                       {return a.Mul(b);}
 | 
|---|
| 230 | //! Divide datas of two data blocks and return NDataBlock : ND = NDa / NDb
 | 
|---|
| 231 | template<class T>
 | 
|---|
| 232 | inline NDataBlock<T> operator / (const NDataBlock<T>& a,const NDataBlock<T>& b)
 | 
|---|
| 233 |                       {return a.Div(b);}
 | 
|---|
| 234 | 
 | 
|---|
| 235 | } // Fin du namespace
 | 
|---|
| 236 | 
 | 
|---|
| 237 | #endif
 | 
|---|