source: Sophya/trunk/SophyaLib/BaseTools/ndatablock.cc@ 503

Last change on this file since 503 was 502, checked in by ansari, 26 years ago

intro du Realloc cmv 23/10/99

File size: 22.4 KB
RevLine 
[268]1// Gestion de block de donnees avec partage de references
[502]2// malheureusement tres mal concu... C.Magneville 04/99
[268]3// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
[245]4#include "machdefs.h"
5#include <stdio.h>
6#include <stdlib.h>
7#include <iostream.h>
8#include <complex>
9#include "pexceptions.h"
10#include "ndatablock.h"
[269]11#include "objfio.h"
[245]12
[268]13using namespace PlanckDPC;
[245]14
[275]15// define DEBUG_NDATABLOCK
[268]16
[245]17#ifdef DEBUG_NDATABLOCK
18 static size_t NallocData = 0;
19 static size_t NallocSRef = 0;
20#endif
21
[275]22////////////////////////////////////////////////////////////////
[289]23//************ Createur, Destructeur
[245]24
25template <class T>
26NDataBlock<T>::NDataBlock(size_t n)
27// Createur d'une structure de "n" donnees
28: mSz(0), mSRef(NULL), mIsTemp(false)
29{
[268]30#ifdef DEBUG_NDATABLOCK
[289]31cout<<"?_NDataBlock::NDataBlock("<<this<<",n="<<n<<")"<<endl;
[268]32#endif
33
[245]34Alloc(n);
35}
36
37template <class T>
38NDataBlock<T>::NDataBlock(size_t n, T* data, Bridge* br)
[502]39// Createur d'une structure de "n" donnees, avec donnees preallouees.
40// Attention createur TRES DANGEREUX (Voir explications dans Alloc()).
[245]41: mSz(0), mSRef(NULL), mIsTemp(false)
42{
[268]43#ifdef DEBUG_NDATABLOCK
[289]44cout<<"?_NDataBlock::NDataBlock("<<this
[268]45 <<",data="<<data<<",br="<<br<<")"<<endl;
46#endif
47
[245]48Alloc(n,data,br);
49}
50
51template <class T>
52NDataBlock<T>::NDataBlock()
53// Createur par default
54: mSz(0), mSRef(NULL), mIsTemp(false)
55{
[268]56#ifdef DEBUG_NDATABLOCK
[289]57cout<<"?_NDataBlock::NDataBlock("<<this<<") default"<<endl;
[268]58#endif
[245]59}
60
61template <class T>
[268]62NDataBlock<T>::NDataBlock(const NDataBlock<T>& a)
[289]63// Createur par copie: partage les donnees si "a" temporaire, clone sinon.
[245]64: mSz(0), mSRef(NULL), mIsTemp(false)
65{
[268]66#ifdef DEBUG_NDATABLOCK
[289]67cout<<"?_NDataBlock::NDataBlock("<<this<<",&a="<<&a<<")"<<endl;
[268]68#endif
69
[289]70CloneOrShare(a);
[245]71}
72
73template <class T>
[268]74NDataBlock<T>::NDataBlock(const NDataBlock<T>& a,bool share)
[289]75// Createur avec choix de partager ou non selon "share"
[245]76: mSz(0), mSRef(NULL), mIsTemp(false)
77{
[268]78#ifdef DEBUG_NDATABLOCK
[289]79cout<<"?_NDataBlock::NDataBlock("<<this<<",&a="<<&a<<",sh=<<"<<share<<")"<<endl;
[268]80#endif
81
[245]82if(share) Share(a); else Clone(a);
83}
84
85template <class T>
86NDataBlock<T>::~NDataBlock()
87// Destructeur
88{
[268]89#ifdef DEBUG_NDATABLOCK
[289]90cout<<"?_NDataBlock::~NDataBlock("<<this<<")"<<endl;
[268]91#endif
92
[245]93Delete();
94}
95
[275]96////////////////////////////////////////////////////////////////
[289]97//************ Gestion de donnees
[275]98
[245]99template <class T>
100void NDataBlock<T>::Alloc(size_t n,T* data,Bridge* br)
[285]101// Allocation d'un NOUVEL espace de stoquage de "n" donnees
[502]102// Si data==NULL : allocation de l'espace memoire (remplit de zeros)
[245]103// data!=NULL : partage des donnees avec l'adresse data
104// Si br==NULL : les donnees nous appartiennent
[275]105// br!=NULL : les donnees ne nous appartiennent pas (ex: Blitz)
106//
[257]107// Exemple: on veut connecter a un tableau de T*
[502]108// > float *x = new float[5]; ... remplissage de x[] ...;
109// 1- On veut que NDataBlock NE DESALLOUE PAS le tableau "x[]"
[275]110// a- Premiere solution
[502]111// > NDataBlock A(5,x,new Bridge);
112// ......
113// > delete [] x;
114// - Il faut deleter x[] explicitement.
115// - Le destructeur de "A" ne detruit pas x[].
116// ATTENTION: Une fois x[] detruit, "A" ne peut
117// plus acceder les donnees!
118// - Bridge est detruit par le destructeur de "A"
[275]119// b- Autre solution:
[502]120// > NDataBlock A(5); A.FillFrom(5,x);
121// > delete [] x;
122// ......
123// - Il faut deleter x[] explicitement.
124// - "A" possede une copie en local de x[].
125// - Le destructeur de "A" ne detruit pas x[] mais la copie locale.
[275]126// 2- On veut que NDataBlock desalloue le tableau
[502]127// > NDataBlock A(5,x);
128// - Ne Pas Faire "delete [] x;"
129// - "A" partage les donnees avec x[].
130// - Le destructeur de "A" detruit x[].
131//
132// --- REMARQUE SUR LE DANGER DE CERTAINES SITUATIONS (CMV):
133// 1-/ x = new float[n1]; NDataBlock A(n2,x);
134// 1er danger: si n2>n1 depassement de tableaux (core dump)
135// 2sd danger: celui qui alloue x[] ne doit pas faire le "delete"
136// en desaccord avec toutes les regles de bonne conduite.
137// 2-/ float x[5]={1,2,3,4,5}; {NDataBlock A(n2,&x[0]);} cout<<x[2];
138// Ici, a la sortie du bloc {}, le destructeur de "A" va detruire
139// l'adresse de &x[0]: je n'ose imaginer que ca se fasse sans probleme
140// et de toute facon, cout<<x[2]; va surement faire des etincelles.
141// 3-/ x = new float[n1]; NDataBlock A(n2,x,new Bridge);
142// 1er danger: si n2>n1 depassement de tableaux (core dump)
143// 2sd danger: si la methode bridgee (blitz?) detruit x[]
144// "A" n'a plus de donnees connectees!
145// --- CONCLUSION
146// Cette classe est franchement merdique.
147// - On peut accepter la prise de risque liee a NDataBlock(n2,x,new Bridge);
148// car je ne vois pas comment on pourrait faire autrement pour connecter
149// un tableau de type blitz par exemple.
150// - Par contre le createur NDataBlock(n2,x); doit etre interdit
151// dans sa forme actelle car trop dangereux et il me semble inutile.
152// - Dans cette nouvelle optique:
153// NDataBlock(n2,x,new Bridge) et NDataBlock(n2,x) disparaissent
154// On remplace par NDataBlock(n2,x) {Alloc(n2,x,new Bridge);}
155// qui force le Bridge dans tout les cas puisque NDataBlock
156// ne possede pas les donnees.
157// Mais puis-je encore le faire vu que NDataBlock est a la base
158// de TVector,TMatrix et qu'il faut donc reprendre tout le code DPC
159// - Quoiqu'il arrive Alloc est une methode privee et peut donc rester
160// sous sa forme actuelle.
161//
[245]162{
[268]163#ifdef DEBUG_NDATABLOCK
[289]164cout<<"?_NDataBlock::Alloc("<<this<<","
[268]165 <<n<<","<<data<<","<<br<<") mSz="<<mSz
166 <<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
167#endif
168
[275]169if(br && !data)
170 throw(NullPtrError("NDataBlock::Alloc br!=NULL && data==NULL\n"));
[245]171if(n==0) throw(SzMismatchError("NDataBlock::Alloc n==0\n"));
172if(mSRef) Delete();
173mSz = n;
174mSRef = new NDREF;
175mSRef->nref = 1;
[285]176if(data) mSRef->data = data;
177else {mSRef->data = new T[n]; memset(mSRef->data,0,n*sizeof(T));}
[245]178mSRef->bridge = br;
[268]179
180#ifdef DEBUG_NDATABLOCK
[275]181// Meme dans le cas data!=0 et br==0 (connexion d'un tableau
182// avec destruction geree par ~NDataBlock (cas 2-) on compte
183// comme si on avait fait une allocation du tableau (ce qui a ete
184// fait au niveau du dessus!).
185if(!br) NallocData++; NallocSRef++;
[289]186cout<<"...?_NDataBlock::Alloc mSz="<<mSz<<" mSRef="<<mSRef
[268]187 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
188 <<" mSRef->bridge="<<mSRef->bridge<<" IsTemp="<<mIsTemp
189 <<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
190#endif
[245]191}
192
193template <class T>
[268]194void NDataBlock<T>::Clone(const NDataBlock<T>& a)
[289]195// Clone: copie de donnees a partir de "a"
[245]196{
[275]197#ifdef DEBUG_NDATABLOCK
[289]198cout<<"?_NDataBlock::Clone("<<this<<","<<&a<<") a.(mSz="
[275]199 <<a.mSz<<" mSRef="<<a.mSRef<<" IsTemp="<<a.IsTemp()
200 <<"), mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
201#endif
202
[289]203if(&a==NULL) throw(NullPtrError("NDataBlock::Clone &a==NULL\n"));
204if(!a.mSRef || a.mSz==0) throw(SzMismatchError("NDataBlock::Clone a.mSz==0\n"));
205Alloc(a.mSz);
206memcpy(Data(),a.Data(),mSz*sizeof(T));
[245]207}
208
209template <class T>
[289]210void NDataBlock<T>::CloneOrShare(const NDataBlock<T>& a)
211// CloneOrShare: Share si "a" temporaire, Clone sinon.
212{
213#ifdef DEBUG_NDATABLOCK
214cout<<"?_NDataBlock::CloneOrShare("<<this<<","<<&a<<")"<<endl;
215#endif
216
217if(&a==NULL) throw(NullPtrError("NDataBlock::CloneOrShare &a==NULL\n"));
218if(a.IsTemp()) Share(a); else Clone(a);
219}
220
221template <class T>
[268]222void NDataBlock<T>::Share(const NDataBlock<T>& a)
[289]223// Share: Partage les donnees avec "a"
[245]224{
[268]225#ifdef DEBUG_NDATABLOCK
[289]226cout<<"?_NDataBlock::Share("<<this<<","<<&a<<")";
[268]227if(&a!=NULL) cout<<" a.(mSz="<<a.mSz<<" mSRef="<<a.mSRef
228 <<" IsTemp="<<a.IsTemp()<<")";
229cout<<", mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
230#endif
231
[245]232if(&a==NULL) throw(NullPtrError("NDataBlock::Share &a==NULL\n"));
[289]233if(!a.mSRef || a.mSz==0) throw(NullPtrError("NDataBlock::Share a.mSz=0\n"));
[245]234if(mSRef) Delete();
235mSz = a.mSz; mSRef = a.mSRef; mSRef->nref++;
[268]236
237#ifdef DEBUG_NDATABLOCK
[289]238cout<<"...?_NDataBlock::Share mSz="<<mSz<<" mSRef="<<mSRef
[268]239 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
240 <<" mSRef->bridge="<<mSRef->bridge<<" IsTemp="<<mIsTemp<<endl;
241#endif
[245]242}
243
244template <class T>
245void NDataBlock<T>::Delete(void)
246// Pour detruire les pointeurs en tenant compte des references
247{
[268]248#ifdef DEBUG_NDATABLOCK
[289]249cout<<"?_NDataBlock::Delete("<<this<<") mSz="<<mSz
[268]250 <<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp;
251if(mSRef)
252 cout<<" mSRef->nref="<<mSRef->nref<<" mSRef->data="
253 <<mSRef->data<<" mSRef->bridge="<<mSRef->bridge;
254cout<<endl;
255#endif
256
[289]257if(mSRef==NULL) return;
[245]258mSRef->nref--;
259if(mSRef->nref != 0) {
[268]260
261#ifdef DEBUG_NDATABLOCK
[502]262 cout<<"...?_NDataBlock::Delete() pas de desallocation il reste nref="
263 <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
[268]264#endif
265
[285]266 mSz = 0; mSRef=NULL;
[245]267 return;
268}
[268]269
270#ifdef DEBUG_NDATABLOCK
271if(!mSRef->bridge) NallocData--; NallocSRef--;
[289]272cout<<"...?_NDataBlock::Delete() desallocation complete il reste nref="
[268]273 <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
274#endif
275
[245]276// Si il y a un Bridge les donnees ne n'appartiennent pas, on detruit le Bridge
[285]277// sinon, les donnees ont ete allouees par nos soins, on libere l'espace
278if(mSRef->bridge) delete mSRef->bridge; else delete [] mSRef->data;
[245]279mSRef->bridge=NULL; mSRef->data=NULL;
[285]280delete mSRef; mSRef=NULL; mSz = 0;
[245]281}
282
283template <class T>
[257]284void NDataBlock<T>::FillFrom(size_t n,T* data)
285// Remplissage par un tableau de donnees
286// - Si classe vide : creation de l'espace memoire
[289]287// - Si classe connectee : on ecrit selon la longueur minimale
288// (cad this->mSz ou "n")
[257]289{
290if(data==NULL) throw(NullPtrError("NDataBlock::FillFrom data==NULL\n"));
291if(n==0) throw(ParmError("NDataBlock::FillFrom n<=0\n"));
[289]292if(mSRef==NULL) Alloc(n);
[285]293if(mSz<n) n = mSz;
[257]294memcpy(Data(),data,n*sizeof(T));
295}
296
[502]297template <class T>
298void NDataBlock<T>::Realloc(size_t nnew,bool force)
299// Re-allocation de "nnew" place memoire pour les donnees
300// avec conservation des "nold" donnees precedentes si possible.
301// "force" gere la re-allocation de la place memoire pour les donnees.
302// Divers cas se presentent:
303// a-/ *** nnew>nold force=quelconque ***
304// place re-allouee, donnees [0,nold[ copiees, surplus [nold,new[ mis a zero
305// b-/ *** nnew<=nold force=true ***
306// place re-allouee, donnees [0,nnew[ copiees, pas de surplus
307// c-/ *** nnew<=nold force=false ***
308// place non re-allouee, seule la valeur de la taille est diminuee
309// - On tient compte du partage des donnees dans tous les cas.
310// - Si il n'y a pas de donnees connectees a la classe, on re-alloue
311// dans tous les cas
312{
313if(nnew==0) throw(ParmError("NDataBlock::Realloc n<=0\n"));
314
315// Cas sans re-allocation memoire
316if(mSRef && nnew<=mSz && ! force) { mSz=nnew; return;}
317
318// Cas avec re-allocation memoire
319size_t ncop;
320if(!mSRef || mSz==0) ncop=0; else if(mSz<nnew) ncop=mSz; else ncop=nnew;
321T* dataloc = new T[nnew];
322if(ncop>0) memcpy(dataloc,mSRef->data,ncop*sizeof(T));
323if(nnew>ncop) memset(dataloc+ncop,0,(nnew-ncop)*sizeof(T));
324Alloc(nnew,dataloc,NULL); //Alloc gere partage de reference et bridge
325}
326
[275]327////////////////////////////////////////////////////////////////
[245]328//**** Impression
329
330template <class T>
[268]331void NDataBlock<T>::Print(ostream& os,size_t i1,size_t n) const
[245]332// Impression de n elements a partir de i1
333{
334size_t nr = 0;
[267]335T* p = NULL; Bridge* br = NULL;
336if(mSRef) {nr = mSRef->nref; p = mSRef->data; br = mSRef->bridge;}
[268]337os<<"NDataBlock::Print("<<this<<",Sz="<<mSz<<",IsTemp="<<mIsTemp<<")\n"
338 <<" mSRef="<<mSRef<<"(nref="<<nr<<",data="<<p
339 <<",bridge="<<br<<")"<<endl;
[249]340if(i1>=mSz || n<=0 || !p) return;
[245]341size_t i2 = i1+n; if(i2>mSz) i2=mSz;
[269]342size_t im = 1; bool enl=false;
[245]343while(i1<i2) {
[257]344 enl = false;
[268]345 os<<" "<<(*this)(i1); i1++;
346 if(im==8) {os<<"\n"; im=1; enl=true;} else im++;
[245]347}
[268]348if(!enl) os<<endl;
[245]349}
350
[275]351////////////////////////////////////////////////////////////////
[289]352
353template <class T>
354T NDataBlock<T>::Sum(size_t i1,size_t n) const
355// Somme des elements de i1 a i1+n-1
356{
357if(i1>=mSz) return 0;
358if(n>mSz) n = mSz; if(n==0) n = mSz-i1;
359T const *p=Begin()+i1, *pe=p+n;
360T val = 0;
361while (p<pe) val += *p++;
362return val;
363}
364
365template <class T>
366T NDataBlock<T>::Product(size_t i1,size_t n) const
367// Produit des elements de i1 a i1+n-1
368{
369if(i1>=mSz) return 0;
370if(n>mSz) n = mSz; if(n==0) n = mSz-i1;
371T const *p=Begin()+i1, *pe=p+n;
372T val = 0;
373while (p<pe) val *= *p++;
374return val;
375}
376
377////////////////////////////////////////////////////////////////
[245]378//**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b;
379
380template <class T>
[268]381NDataBlock<T>& NDataBlock<T>::operator = (const NDataBlock<T>& a)
[289]382// Affectation: partage des donnees si "a" temporaire, clone sinon.
[245]383{
[268]384#ifdef DEBUG_NDATABLOCK
[289]385cout<<"?_NDataBlock::operator=("<<this<<","<<&a<<") a.(mSz="
[268]386 <<a.mSz<<" mSRef="<<a.mSRef<<" IsTemp="<<a.IsTemp()
387 <<"), mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
388#endif
389
[245]390if(this == &a) return *this;
[289]391if(a.mSz==0)
392 throw(SzMismatchError("NDataBlock::operator=A null size\n"));
393CloneOrShare(a);
[245]394return *this;
395}
396
397template <class T>
[249]398NDataBlock<T>& NDataBlock<T>::operator = (T v)
[289]399// Affectation de tous les elements a une constante "v"
[245]400{
[268]401#ifdef DEBUG_NDATABLOCK
[289]402cout<<"?_NDataBlock::operator=("<<this<<","<<v<<")"
[268]403 <<" mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
404#endif
405
[245]406if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n"));
[249]407T *p=Begin(), *pe=End();
[245]408while (p<pe) *p++ = v;
409return *this;
410}
411
[275]412////////////////////////////////////////////////////////////////
[245]413//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += <T> b;
414
415template <class T>
416NDataBlock<T>& NDataBlock<T>::operator += (T b)
417{
418if(mSz==0) throw(SzMismatchError("NDataBlock::operator+=v null size\n"));
[249]419T *p=Begin(), *pe=End();
[245]420while (p<pe) *p++ += b;
421return *this;
422}
423
424template <class T>
425NDataBlock<T>& NDataBlock<T>::operator -= (T b)
426{
427if(mSz==0) throw(SzMismatchError("NDataBlock::operator-=v null size\n"));
[249]428T *p=Begin(), *pe=End();
[245]429while (p<pe) *p++ -= b;
430return *this;
431}
432
433template <class T>
434NDataBlock<T>& NDataBlock<T>::operator *= (T b)
435{
436if(mSz==0) throw(SzMismatchError("NDataBlock::operator*=v null size\n"));
[249]437T *p=Begin(), *pe=End();
[245]438while (p<pe) *p++ *= b;
439return *this;
440}
441
442template <class T>
443NDataBlock<T>& NDataBlock<T>::operator /= (T b)
444{
[249]445if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
[245]446if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
[249]447T *p=Begin(), *pe=End();
[245]448while (p<pe) *p++ /= b;
449return *this;
450}
451
[275]452////////////////////////////////////////////////////////////////
[245]453//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock;
454
455template <class T>
[268]456NDataBlock<T>& NDataBlock<T>::operator += (const NDataBlock<T>& a)
[245]457{
[265]458if(mSz==0 || mSz!=a.mSz)
459 throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
[268]460T *p=Begin(), *pe=End();
461T const * pa=a.Begin();
[289]462while (p<pe) *p++ += *pa++;
[245]463return *this;
464}
465
466template <class T>
[268]467NDataBlock<T>& NDataBlock<T>::operator -= (const NDataBlock<T>& a)
[245]468{
[265]469if(mSz==0 || mSz!=a.mSz)
470 throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
[268]471T *p=Begin(), *pe=End();
472T const *pa=a.Begin();
[289]473while (p<pe) *p++ -= *pa++;
[245]474return *this;
475}
476
477template <class T>
[268]478NDataBlock<T>& NDataBlock<T>::operator *= (const NDataBlock<T>& a)
[245]479{
[265]480if(mSz==0 || mSz!=a.mSz)
481 throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
[268]482T *p=Begin(), *pe=End();
483T const *pa=a.Begin();
[289]484while (p<pe) *p++ *= *pa++;
[245]485return *this;
486}
487
488template <class T>
[268]489NDataBlock<T>& NDataBlock<T>::operator /= (const NDataBlock<T>& a)
[289]490// Attention, aucune protection si un element de "a" est nul.
[245]491{
[265]492if(mSz==0 || mSz!=a.mSz)
493 throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
[268]494T *p=Begin(), *pe=End();
495T const *pa=a.Begin();
[245]496while (p<pe) *p++ /= *pa++;
497return *this;
498}
499
[275]500////////////////////////////////////////////////////////////////
501//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+<T>b;
502// NDataBlock = <T>b+NDataBlock;
[245]503
504template <class T>
[268]505NDataBlock<T> NDataBlock<T>::Add(T b) const
[257]506// Pour A+b
[245]507{
[289]508NDataBlock<T> result(*this); result.SetTemp(true);
[268]509result += b;
510return result;
[245]511}
512
513template <class T>
[268]514NDataBlock<T> NDataBlock<T>::Sub(T b) const
[257]515// Pour A-b
[245]516{
[289]517NDataBlock<T> result(*this); result.SetTemp(true);
[259]518return result -= b;
[245]519}
520
521template <class T>
[268]522NDataBlock<T> NDataBlock<T>::SubInv(T b) const
[257]523// Pour b-A
[245]524{
[289]525NDataBlock<T> result(*this); result.SetTemp(true);
[268]526T *p=result.Begin(), *pe=result.End();
527T const *pa=this->Begin();
[245]528while(p<pe) {*p++ = b - *pa++;}
529return result;
530}
531
532template <class T>
[268]533NDataBlock<T> NDataBlock<T>::Mul(T b) const
[257]534// Pour A*b
[245]535{
[289]536NDataBlock<T> result(*this); result.SetTemp(true);
[259]537return result *= b;
[245]538}
539
540template <class T>
[268]541NDataBlock<T> NDataBlock<T>::Div(T b) const
[257]542// Pour A/b
[245]543{
[289]544NDataBlock<T> result(*this); result.SetTemp(true);
[259]545return result /= b;
[245]546}
547
548template <class T>
[268]549NDataBlock<T> NDataBlock<T>::DivInv(T b) const
[257]550// Pour b/A
[245]551{
[289]552NDataBlock<T> result(*this); result.SetTemp(true);
[268]553T *p=result.Begin(), *pe=result.End();
554T const *pa = this->Begin();
[245]555while(p<pe) {*p++ = b / *pa++;}
556return result;
557}
558
[275]559////////////////////////////////////////////////////////////////
[245]560//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock;
561
562template <class T>
[268]563NDataBlock<T> NDataBlock<T>::Add(const NDataBlock<T>& b) const
[257]564// Pour A+B
[245]565{
[285]566if(mSz!=b.mSz)
[265]567 throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n"));
[268]568NDataBlock<T> result; result.SetTemp(true);
[289]569if(b.IsTemp()) {result.Share(b); result += *this;}
570 else {result.CloneOrShare(*this); result += b;}
[268]571return result;
[245]572}
573
574template <class T>
[268]575NDataBlock<T> NDataBlock<T>::Mul(const NDataBlock<T>& b) const
[257]576// Pour A*B
[245]577{
[285]578if(mSz!=b.mSz)
[265]579 throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n"));
[268]580NDataBlock<T> result; result.SetTemp(true);
[289]581if(b.IsTemp()) {result.Share(b); result *= *this;}
582 else {result.CloneOrShare(*this); result *= b;}
[268]583return result;
[245]584}
585
586template <class T>
[268]587NDataBlock<T> NDataBlock<T>::Sub(const NDataBlock<T>& b) const
[257]588// Pour A-B
[245]589{
[285]590if(mSz!=b.mSz)
[265]591 throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n"));
[268]592NDataBlock<T> result; result.SetTemp(true);
[245]593if(b.IsTemp()) {
[268]594 result.Share(b);
[289]595 T *p=result.Begin(), *pe=result.End(); T const *pa=Begin();
[245]596 while(p<pe) {*p = *pa++ - *p; p++;}
[289]597} else {result.CloneOrShare(*this); result -= b;}
[268]598return result;
[245]599}
600
601template <class T>
[268]602NDataBlock<T> NDataBlock<T>::Div(const NDataBlock<T>& b) const
[257]603// Pour A/B
[245]604{
[285]605if(mSz!=b.mSz)
[265]606 throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n"));
[268]607NDataBlock<T> result; result.SetTemp(true);
[245]608if(b.IsTemp()) {
[268]609 result.Share(b);
[289]610 T *p=result.Begin(), *pe=result.End(); T const *pa=Begin();
[245]611 while(p<pe) {*p = *pa++ / *p; p++;}
[289]612} else {result.CloneOrShare(*this); result /= b;}
[268]613return result;
[245]614}
615
[275]616////////////////////////////////////////////////////////////////
[269]617// -------------------------------------------------------------------------
618// Les objets delegues pour la gestion de persistance
619// -------------------------------------------------------------------------
620
621/*
622template <class T>
623void ObjFileIO< NDataBlock<T> >::ReadSelf(PInPersist& is)
624template <class T>
625void ObjFileIO< NDataBlock<T> >::WriteSelf(POutPersist& os)
626*/
627
[277]628// Pour pouvoir ecrire des tableaux de complex, en attendant
629// PIn/POutPersist::Get/Put(complex<>)
[441]630#include "piocmplx.h"
[277]631
[269]632template <class T>
633FIO_NDataBlock<T>::FIO_NDataBlock()
634{
635dobj=new NDataBlock<T>;
[277]636ownobj=true;
[269]637}
638
639template <class T>
640FIO_NDataBlock<T>::FIO_NDataBlock(string const & filename)
641{
[277]642dobj=new NDataBlock<T>;
643ownobj=true;
[269]644Read(filename);
645}
646
647template <class T>
648FIO_NDataBlock<T>::FIO_NDataBlock(const NDataBlock<T> & obj)
649{
[277]650dobj = new NDataBlock<T>(obj);
651ownobj=true;
[269]652}
653
654template <class T>
[277]655FIO_NDataBlock<T>::FIO_NDataBlock(NDataBlock<T> * obj)
[269]656{
[277]657dobj = obj;
658ownobj=false;
[269]659}
660
661template <class T>
662FIO_NDataBlock<T>::~FIO_NDataBlock()
663{
[277]664if (ownobj && dobj) delete dobj;
[269]665}
666
667template <class T>
668AnyDataObj* FIO_NDataBlock<T>::DataObj()
669{
670return(dobj);
671}
672
673
674template <class T>
675void FIO_NDataBlock<T>::ReadSelf(PInPersist& is)
676{
677// On lit les 3 premiers uint_8
678uint_8 itab[3];
679is.Get(itab, 3);
680if (dobj == NULL) dobj = new NDataBlock<T>(itab[1]);
[290]681else if (itab[1] != dobj->Size()) dobj->ReSize(itab[1]);
[269]682// On lit le tableau de nombres
683PIOSReadArray(is, dobj->Data(), dobj->Size());
684}
685
686
687template <class T>
688void FIO_NDataBlock<T>::WriteSelf(POutPersist& os) const
689{
690if (dobj == NULL) return; // Attention - $CHECK$ Reza 26/04/99
[305]691// On ecrit 3 uint_8
[269]692// 0 : Numero de version, 1 : Taille, 2 reserve a l
693uint_8 itab[3];
694itab[0] = 1;
695itab[1] = dobj->Size();
696itab[2] = 0;
697os.Put(itab, 3);
698// On ecrit le tableau de nombres
699PIOSWriteArray(os, dobj->Data(), dobj->Size());
700}
701
[275]702///////////////////////////////////////////////////////////////
[245]703#ifdef __CXX_PRAGMA_TEMPLATES__
704#pragma define_template NDataBlock<uint_1>
705#pragma define_template NDataBlock<uint_2>
706#pragma define_template NDataBlock<int_2>
707#pragma define_template NDataBlock<int_4>
708#pragma define_template NDataBlock<int_8>
709#pragma define_template NDataBlock<uint_4>
710#pragma define_template NDataBlock<uint_8>
711#pragma define_template NDataBlock<r_4>
712#pragma define_template NDataBlock<r_8>
[268]713#pragma define_template NDataBlock< complex<float> >
714#pragma define_template NDataBlock< complex<double> >
[269]715// Instances des delegues FileIO (PPersist)
[273]716#pragma define_template FIO_NDataBlock<uint_1>
717#pragma define_template FIO_NDataBlock<uint_2>
718#pragma define_template FIO_NDataBlock<int_2>
719#pragma define_template FIO_NDataBlock<int_4>
720#pragma define_template FIO_NDataBlock<int_8>
721#pragma define_template FIO_NDataBlock<uint_4>
722#pragma define_template FIO_NDataBlock<uint_8>
723#pragma define_template FIO_NDataBlock<r_8>
724#pragma define_template FIO_NDataBlock<r_4>
725#pragma define_template FIO_NDataBlock< complex<float> >
726#pragma define_template FIO_NDataBlock< complex<double> >
[245]727#endif
728
[269]729#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
[245]730template class NDataBlock<uint_1>;
731template class NDataBlock<uint_2>;
732template class NDataBlock<int_2>;
733template class NDataBlock<int_4>;
734template class NDataBlock<int_8>;
735template class NDataBlock<uint_4>;
736template class NDataBlock<uint_8>;
737template class NDataBlock<r_4>;
738template class NDataBlock<r_8>;
[249]739template class NDataBlock< complex<float> >;
740template class NDataBlock< complex<double> >;
[269]741// Instances des delegues FileIO (PPersist)
742template class FIO_NDataBlock<uint_1>;
743template class FIO_NDataBlock<uint_2>;
744template class FIO_NDataBlock<int_2>;
745template class FIO_NDataBlock<int_4>;
746template class FIO_NDataBlock<int_8>;
747template class FIO_NDataBlock<uint_4>;
748template class FIO_NDataBlock<uint_8>;
749template class FIO_NDataBlock<r_8>;
750template class FIO_NDataBlock<r_4>;
751template class FIO_NDataBlock< complex<float> >;
752template class FIO_NDataBlock< complex<double> >;
[245]753#endif
Note: See TracBrowser for help on using the repository browser.