| 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);
 | 
|---|
| 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. 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 to zero.
 | 
|---|
| 84 |     The new data structure has only one reference (itself!). */
 | 
|---|
| 85 |   inline void ReSize(size_t n) {Alloc(n);}
 | 
|---|
| 86 | 
 | 
|---|
| 87 |   void Realloc(size_t nnew,bool force=false);
 | 
|---|
| 88 |   
 | 
|---|
| 89 |   // Informations pointeur/data
 | 
|---|
| 90 |   //! Return pointer on data structure.
 | 
|---|
| 91 |   inline T* Data()
 | 
|---|
| 92 |          {if(mSRef) return mSRef->data; else return NULL;}
 | 
|---|
| 93 |   //! Return pointer on data structure.
 | 
|---|
| 94 |   inline T* Data() const
 | 
|---|
| 95 |          {if(mSRef) return mSRef->data; else return NULL;}
 | 
|---|
| 96 |   //! Return the size of the data structure
 | 
|---|
| 97 |   inline size_t Size() const    {return mSz;}
 | 
|---|
| 98 |   //! Return the \b i th element of  the data structure
 | 
|---|
| 99 |   inline T& operator()(size_t i)       {return *(mSRef->data+i);}
 | 
|---|
| 100 |   //! Return the \b i th element of  the data structure
 | 
|---|
| 101 |   inline T  operator()(size_t i) const {return *(mSRef->data+i);}
 | 
|---|
| 102 |   //! Return pointer to the beginning of the data structure.
 | 
|---|
| 103 |   inline T*        Begin()        {return mSRef->data;}
 | 
|---|
| 104 |   //! Return pointer to the beginning of the data structure.
 | 
|---|
| 105 |   inline T const*  Begin() const  {return mSRef->data;} 
 | 
|---|
| 106 |   //! Return pointer to the end of the data structure.
 | 
|---|
| 107 |   inline T*        End()          {return mSRef->data+mSz;}
 | 
|---|
| 108 |   //! Return pointer to the end of the data structure.
 | 
|---|
| 109 |   inline T const*  End() const    {return mSRef->data+mSz;}
 | 
|---|
| 110 |   //! Return the number of references to the data structure
 | 
|---|
| 111 |   inline size_t NRef() const {if(mSRef) return 0; else return mSRef->nref;}
 | 
|---|
| 112 | 
 | 
|---|
| 113 |   // Impression
 | 
|---|
| 114 |   void Print(ostream& os, size_t i1=0,size_t n=10) const;
 | 
|---|
| 115 |   //! print infos and datas (from \b i1 to \b i2) on stdout.
 | 
|---|
| 116 |   inline void Print(size_t i1=0,size_t n=0) const {Print(cout,i1,n);}
 | 
|---|
| 117 | 
 | 
|---|
| 118 |   //
 | 
|---|
| 119 |   T Sum(size_t i1=0,size_t n=0) const;
 | 
|---|
| 120 |   T Product(size_t i1=0,size_t n=0) const;
 | 
|---|
| 121 | 
 | 
|---|
| 122 |   // Surcharge d'operateurs INPLACE: A = x , A = B , A @= x , A @= B
 | 
|---|
| 123 |   NDataBlock<T>& operator = (const NDataBlock<T>& a);
 | 
|---|
| 124 |   NDataBlock<T>& operator = (T v);
 | 
|---|
| 125 | 
 | 
|---|
| 126 |   NDataBlock<T>& operator += (T b);
 | 
|---|
| 127 |   NDataBlock<T>& operator -= (T b);
 | 
|---|
| 128 |   NDataBlock<T>& operator *= (T b);
 | 
|---|
| 129 |   NDataBlock<T>& operator /= (T b);
 | 
|---|
| 130 | 
 | 
|---|
| 131 |   NDataBlock<T>& operator += (const NDataBlock<T>& a);
 | 
|---|
| 132 |   NDataBlock<T>& operator -= (const NDataBlock<T>& a);
 | 
|---|
| 133 |   NDataBlock<T>& operator *= (const NDataBlock<T>& a);
 | 
|---|
| 134 |   NDataBlock<T>& operator /= (const NDataBlock<T>& a);
 | 
|---|
| 135 | 
 | 
|---|
| 136 |   // Surcharge d'operateurs: C = A @ x , C = A @ B
 | 
|---|
| 137 |   NDataBlock<T> Add(T b) const;
 | 
|---|
| 138 |   NDataBlock<T> Sub(T b,bool fginv=false) const;
 | 
|---|
| 139 |   NDataBlock<T> Mul(T b) const;
 | 
|---|
| 140 |   NDataBlock<T> Div(T b,bool fginv=false) const;
 | 
|---|
| 141 | 
 | 
|---|
| 142 |   NDataBlock<T> Add(const NDataBlock<T>& b) const;
 | 
|---|
| 143 |   NDataBlock<T> Sub(const NDataBlock<T>& b) const;
 | 
|---|
| 144 |   NDataBlock<T> Mul(const NDataBlock<T>& b) const;
 | 
|---|
| 145 |   NDataBlock<T> Div(const NDataBlock<T>& b) const;
 | 
|---|
| 146 | 
 | 
|---|
| 147 |   inline uint_8 DRefId() { return mSRef->dsid; }
 | 
|---|
| 148 | 
 | 
|---|
| 149 | protected:
 | 
|---|
| 150 |   //! NDREF structure for reference management
 | 
|---|
| 151 |   typedef struct {
 | 
|---|
| 152 |     size_t nref;      //!< Number of references to the data structure
 | 
|---|
| 153 |     uint_8 dsid;      //!< Data structure Id - Used by FIO_NDataBlock
 | 
|---|
| 154 |     T* data;          //!< Pointer to data structure itself
 | 
|---|
| 155 |     Bridge* bridge;   //!< Pointer to a bridge for the data structure
 | 
|---|
| 156 |   } NDREF;
 | 
|---|
| 157 | 
 | 
|---|
| 158 |   void Alloc(size_t n,T* data=NULL,Bridge* br=NULL, bool zero=true);
 | 
|---|
| 159 |   void Delete(void);
 | 
|---|
| 160 | 
 | 
|---|
| 161 |   static int Debug_NDataBlock; //!< DEBUG: set debug level (all type<T> classes)
 | 
|---|
| 162 |   static size_t NallocData; //!< DEBUG: number of allocations (all type<T> classes)
 | 
|---|
| 163 |   static size_t NallocSRef; //!< DEBUG: number of references (all type<T> classes)
 | 
|---|
| 164 | 
 | 
|---|
| 165 |   size_t       mSz;      //!< size of data structure
 | 
|---|
| 166 |   NDREF*       mSRef;    //!< NDREF structure for reference management
 | 
|---|
| 167 |   mutable bool mIsTemp;  //!< true if class is temporary
 | 
|---|
| 168 | };
 | 
|---|
| 169 | 
 | 
|---|
| 170 | //! Define operator \<\< for printing
 | 
|---|
| 171 | template<class T>
 | 
|---|
| 172 | inline ostream& operator << (ostream& os, const NDataBlock<T>& a)
 | 
|---|
| 173 |                       {a.Print(os); return(os);}
 | 
|---|
| 174 | 
 | 
|---|
| 175 | //! Add a constant to datas and return NDataBlock : ND = NDa + b
 | 
|---|
| 176 | template<class T>
 | 
|---|
| 177 | inline NDataBlock<T> operator + (const NDataBlock<T>& a,T b)
 | 
|---|
| 178 |                       {return a.Add(b);}
 | 
|---|
| 179 | //! Add a constant to datas and return NDataBlock : ND = b + NDa
 | 
|---|
| 180 | template<class T>
 | 
|---|
| 181 | inline NDataBlock<T> operator + (T b,const NDataBlock<T>& a)
 | 
|---|
| 182 |                       {return a.Add(b);}
 | 
|---|
| 183 | //! Substract a constant to datas and return NDataBlock : ND = NDa - b
 | 
|---|
| 184 | template<class T>
 | 
|---|
| 185 | inline NDataBlock<T> operator - (const NDataBlock<T>& a,T b)
 | 
|---|
| 186 |                       {return a.Sub(b);}
 | 
|---|
| 187 | //! Substract a constant to datas and return NDataBlock : ND = b - NDa
 | 
|---|
| 188 | template<class T>
 | 
|---|
| 189 | inline NDataBlock<T> operator - (T b,const NDataBlock<T>& a)
 | 
|---|
| 190 |                       {return a.Sub(b,true);}
 | 
|---|
| 191 | //! Multiply datas by a constant and return NDataBlock : ND = NDa * b
 | 
|---|
| 192 | template<class T>
 | 
|---|
| 193 | inline NDataBlock<T> operator * (const NDataBlock<T>& a,T b)
 | 
|---|
| 194 |                       {return a.Mul(b);}
 | 
|---|
| 195 | //! Multiply datas by a constant and return NDataBlock : ND = b * NDa
 | 
|---|
| 196 | template<class T>
 | 
|---|
| 197 | inline NDataBlock<T> operator * (T b,const NDataBlock<T>& a)
 | 
|---|
| 198 |                       {return a.Mul(b);}
 | 
|---|
| 199 | //! Divide datas by a constant and return NDataBlock : ND = NDa / b
 | 
|---|
| 200 | template<class T>
 | 
|---|
| 201 | inline NDataBlock<T> operator / (const NDataBlock<T>& a,T b)
 | 
|---|
| 202 |                       {return a.Div(b);}
 | 
|---|
| 203 | //! Divide a constant by datas and return NDataBlock : ND = b / NDa
 | 
|---|
| 204 | template<class T>
 | 
|---|
| 205 | inline NDataBlock<T> operator / (T b,const NDataBlock<T>& a)
 | 
|---|
| 206 |                       {return a.Div(b,true);}
 | 
|---|
| 207 | 
 | 
|---|
| 208 | //! Add datas of two data blocks and return NDataBlock : ND = NDa + NDb
 | 
|---|
| 209 | template<class T>
 | 
|---|
| 210 | inline NDataBlock<T> operator + (const NDataBlock<T>& a,const NDataBlock<T>& b)
 | 
|---|
| 211 |                       {return a.Add(b);}
 | 
|---|
| 212 | //! Substract datas of two data blocks and return NDataBlock : ND = NDa - NDb
 | 
|---|
| 213 | template<class T>
 | 
|---|
| 214 | inline NDataBlock<T> operator - (const NDataBlock<T>& a,const NDataBlock<T>& b)
 | 
|---|
| 215 |                       {return a.Sub(b);}
 | 
|---|
| 216 | //! Multiply datas of two data blocks and return NDataBlock : ND = NDa * NDb
 | 
|---|
| 217 | template<class T>
 | 
|---|
| 218 | inline NDataBlock<T> operator * (const NDataBlock<T>& a,const NDataBlock<T>& b)
 | 
|---|
| 219 |                       {return a.Mul(b);}
 | 
|---|
| 220 | //! Divide datas of two data blocks and return NDataBlock : ND = NDa / NDb
 | 
|---|
| 221 | template<class T>
 | 
|---|
| 222 | inline NDataBlock<T> operator / (const NDataBlock<T>& a,const NDataBlock<T>& b)
 | 
|---|
| 223 |                       {return a.Div(b);}
 | 
|---|
| 224 | 
 | 
|---|
| 225 | } // Fin du namespace
 | 
|---|
| 226 | 
 | 
|---|
| 227 | #endif
 | 
|---|