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

Last change on this file since 787 was 773, checked in by ansari, 26 years ago

Ajout de l'argument bool zero ds NDataBlock<T>::Alloc()
Fonction pour construire un message d'exception avec num de ligne et
nom de fichier ds pexceptions.h .cc

Reza 10/3/2000

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