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

Last change on this file since 286 was 285, checked in by ansari, 26 years ago

complex est un include system -> <...> et pas "..." sinon pb mkmf
ndatablock ameliore cmv 30/4/99

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