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

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

intro du Realloc cmv 23/10/99

File size: 22.4 KB
Line 
1// Gestion de block de donnees avec partage de references
2// malheureusement tres mal concu... C.Magneville 04/99
3// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
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"
11#include "objfio.h"
12
13using namespace PlanckDPC;
14
15// define DEBUG_NDATABLOCK
16
17#ifdef DEBUG_NDATABLOCK
18 static size_t NallocData = 0;
19 static size_t NallocSRef = 0;
20#endif
21
22////////////////////////////////////////////////////////////////
23//************ Createur, Destructeur
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{
30#ifdef DEBUG_NDATABLOCK
31cout<<"?_NDataBlock::NDataBlock("<<this<<",n="<<n<<")"<<endl;
32#endif
33
34Alloc(n);
35}
36
37template <class T>
38NDataBlock<T>::NDataBlock(size_t n, T* data, Bridge* br)
39// Createur d'une structure de "n" donnees, avec donnees preallouees.
40// Attention createur TRES DANGEREUX (Voir explications dans Alloc()).
41: mSz(0), mSRef(NULL), mIsTemp(false)
42{
43#ifdef DEBUG_NDATABLOCK
44cout<<"?_NDataBlock::NDataBlock("<<this
45 <<",data="<<data<<",br="<<br<<")"<<endl;
46#endif
47
48Alloc(n,data,br);
49}
50
51template <class T>
52NDataBlock<T>::NDataBlock()
53// Createur par default
54: mSz(0), mSRef(NULL), mIsTemp(false)
55{
56#ifdef DEBUG_NDATABLOCK
57cout<<"?_NDataBlock::NDataBlock("<<this<<") default"<<endl;
58#endif
59}
60
61template <class T>
62NDataBlock<T>::NDataBlock(const NDataBlock<T>& a)
63// Createur par copie: partage les donnees si "a" temporaire, clone sinon.
64: mSz(0), mSRef(NULL), mIsTemp(false)
65{
66#ifdef DEBUG_NDATABLOCK
67cout<<"?_NDataBlock::NDataBlock("<<this<<",&a="<<&a<<")"<<endl;
68#endif
69
70CloneOrShare(a);
71}
72
73template <class T>
74NDataBlock<T>::NDataBlock(const NDataBlock<T>& a,bool share)
75// Createur avec choix de partager ou non selon "share"
76: mSz(0), mSRef(NULL), mIsTemp(false)
77{
78#ifdef DEBUG_NDATABLOCK
79cout<<"?_NDataBlock::NDataBlock("<<this<<",&a="<<&a<<",sh=<<"<<share<<")"<<endl;
80#endif
81
82if(share) Share(a); else Clone(a);
83}
84
85template <class T>
86NDataBlock<T>::~NDataBlock()
87// Destructeur
88{
89#ifdef DEBUG_NDATABLOCK
90cout<<"?_NDataBlock::~NDataBlock("<<this<<")"<<endl;
91#endif
92
93Delete();
94}
95
96////////////////////////////////////////////////////////////////
97//************ Gestion de donnees
98
99template <class T>
100void NDataBlock<T>::Alloc(size_t n,T* data,Bridge* br)
101// Allocation d'un NOUVEL espace de stoquage de "n" donnees
102// Si data==NULL : allocation de l'espace memoire (remplit de zeros)
103// data!=NULL : partage des donnees avec l'adresse data
104// Si br==NULL : les donnees nous appartiennent
105// br!=NULL : les donnees ne nous appartiennent pas (ex: Blitz)
106//
107// Exemple: on veut connecter a un tableau de T*
108// > float *x = new float[5]; ... remplissage de x[] ...;
109// 1- On veut que NDataBlock NE DESALLOUE PAS le tableau "x[]"
110// a- Premiere solution
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"
119// b- Autre solution:
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.
126// 2- On veut que NDataBlock desalloue le tableau
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//
162{
163#ifdef DEBUG_NDATABLOCK
164cout<<"?_NDataBlock::Alloc("<<this<<","
165 <<n<<","<<data<<","<<br<<") mSz="<<mSz
166 <<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
167#endif
168
169if(br && !data)
170 throw(NullPtrError("NDataBlock::Alloc br!=NULL && data==NULL\n"));
171if(n==0) throw(SzMismatchError("NDataBlock::Alloc n==0\n"));
172if(mSRef) Delete();
173mSz = n;
174mSRef = new NDREF;
175mSRef->nref = 1;
176if(data) mSRef->data = data;
177else {mSRef->data = new T[n]; memset(mSRef->data,0,n*sizeof(T));}
178mSRef->bridge = br;
179
180#ifdef DEBUG_NDATABLOCK
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++;
186cout<<"...?_NDataBlock::Alloc mSz="<<mSz<<" mSRef="<<mSRef
187 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
188 <<" mSRef->bridge="<<mSRef->bridge<<" IsTemp="<<mIsTemp
189 <<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
190#endif
191}
192
193template <class T>
194void NDataBlock<T>::Clone(const NDataBlock<T>& a)
195// Clone: copie de donnees a partir de "a"
196{
197#ifdef DEBUG_NDATABLOCK
198cout<<"?_NDataBlock::Clone("<<this<<","<<&a<<") a.(mSz="
199 <<a.mSz<<" mSRef="<<a.mSRef<<" IsTemp="<<a.IsTemp()
200 <<"), mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
201#endif
202
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));
207}
208
209template <class T>
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>
222void NDataBlock<T>::Share(const NDataBlock<T>& a)
223// Share: Partage les donnees avec "a"
224{
225#ifdef DEBUG_NDATABLOCK
226cout<<"?_NDataBlock::Share("<<this<<","<<&a<<")";
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
232if(&a==NULL) throw(NullPtrError("NDataBlock::Share &a==NULL\n"));
233if(!a.mSRef || a.mSz==0) throw(NullPtrError("NDataBlock::Share a.mSz=0\n"));
234if(mSRef) Delete();
235mSz = a.mSz; mSRef = a.mSRef; mSRef->nref++;
236
237#ifdef DEBUG_NDATABLOCK
238cout<<"...?_NDataBlock::Share mSz="<<mSz<<" mSRef="<<mSRef
239 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
240 <<" mSRef->bridge="<<mSRef->bridge<<" IsTemp="<<mIsTemp<<endl;
241#endif
242}
243
244template <class T>
245void NDataBlock<T>::Delete(void)
246// Pour detruire les pointeurs en tenant compte des references
247{
248#ifdef DEBUG_NDATABLOCK
249cout<<"?_NDataBlock::Delete("<<this<<") mSz="<<mSz
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
257if(mSRef==NULL) return;
258mSRef->nref--;
259if(mSRef->nref != 0) {
260
261#ifdef DEBUG_NDATABLOCK
262 cout<<"...?_NDataBlock::Delete() pas de desallocation il reste nref="
263 <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
264#endif
265
266 mSz = 0; mSRef=NULL;
267 return;
268}
269
270#ifdef DEBUG_NDATABLOCK
271if(!mSRef->bridge) NallocData--; NallocSRef--;
272cout<<"...?_NDataBlock::Delete() desallocation complete il reste nref="
273 <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
274#endif
275
276// Si il y a un Bridge les donnees ne n'appartiennent pas, on detruit le Bridge
277// sinon, les donnees ont ete allouees par nos soins, on libere l'espace
278if(mSRef->bridge) delete mSRef->bridge; else delete [] mSRef->data;
279mSRef->bridge=NULL; mSRef->data=NULL;
280delete mSRef; mSRef=NULL; mSz = 0;
281}
282
283template <class T>
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
287// - Si classe connectee : on ecrit selon la longueur minimale
288// (cad this->mSz ou "n")
289{
290if(data==NULL) throw(NullPtrError("NDataBlock::FillFrom data==NULL\n"));
291if(n==0) throw(ParmError("NDataBlock::FillFrom n<=0\n"));
292if(mSRef==NULL) Alloc(n);
293if(mSz<n) n = mSz;
294memcpy(Data(),data,n*sizeof(T));
295}
296
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
327////////////////////////////////////////////////////////////////
328//**** Impression
329
330template <class T>
331void NDataBlock<T>::Print(ostream& os,size_t i1,size_t n) const
332// Impression de n elements a partir de i1
333{
334size_t nr = 0;
335T* p = NULL; Bridge* br = NULL;
336if(mSRef) {nr = mSRef->nref; p = mSRef->data; br = mSRef->bridge;}
337os<<"NDataBlock::Print("<<this<<",Sz="<<mSz<<",IsTemp="<<mIsTemp<<")\n"
338 <<" mSRef="<<mSRef<<"(nref="<<nr<<",data="<<p
339 <<",bridge="<<br<<")"<<endl;
340if(i1>=mSz || n<=0 || !p) return;
341size_t i2 = i1+n; if(i2>mSz) i2=mSz;
342size_t im = 1; bool enl=false;
343while(i1<i2) {
344 enl = false;
345 os<<" "<<(*this)(i1); i1++;
346 if(im==8) {os<<"\n"; im=1; enl=true;} else im++;
347}
348if(!enl) os<<endl;
349}
350
351////////////////////////////////////////////////////////////////
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////////////////////////////////////////////////////////////////
378//**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b;
379
380template <class T>
381NDataBlock<T>& NDataBlock<T>::operator = (const NDataBlock<T>& a)
382// Affectation: partage des donnees si "a" temporaire, clone sinon.
383{
384#ifdef DEBUG_NDATABLOCK
385cout<<"?_NDataBlock::operator=("<<this<<","<<&a<<") a.(mSz="
386 <<a.mSz<<" mSRef="<<a.mSRef<<" IsTemp="<<a.IsTemp()
387 <<"), mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
388#endif
389
390if(this == &a) return *this;
391if(a.mSz==0)
392 throw(SzMismatchError("NDataBlock::operator=A null size\n"));
393CloneOrShare(a);
394return *this;
395}
396
397template <class T>
398NDataBlock<T>& NDataBlock<T>::operator = (T v)
399// Affectation de tous les elements a une constante "v"
400{
401#ifdef DEBUG_NDATABLOCK
402cout<<"?_NDataBlock::operator=("<<this<<","<<v<<")"
403 <<" mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
404#endif
405
406if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n"));
407T *p=Begin(), *pe=End();
408while (p<pe) *p++ = v;
409return *this;
410}
411
412////////////////////////////////////////////////////////////////
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"));
419T *p=Begin(), *pe=End();
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"));
428T *p=Begin(), *pe=End();
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"));
437T *p=Begin(), *pe=End();
438while (p<pe) *p++ *= b;
439return *this;
440}
441
442template <class T>
443NDataBlock<T>& NDataBlock<T>::operator /= (T b)
444{
445if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
446if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
447T *p=Begin(), *pe=End();
448while (p<pe) *p++ /= b;
449return *this;
450}
451
452////////////////////////////////////////////////////////////////
453//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock;
454
455template <class T>
456NDataBlock<T>& NDataBlock<T>::operator += (const NDataBlock<T>& a)
457{
458if(mSz==0 || mSz!=a.mSz)
459 throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
460T *p=Begin(), *pe=End();
461T const * pa=a.Begin();
462while (p<pe) *p++ += *pa++;
463return *this;
464}
465
466template <class T>
467NDataBlock<T>& NDataBlock<T>::operator -= (const NDataBlock<T>& a)
468{
469if(mSz==0 || mSz!=a.mSz)
470 throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
471T *p=Begin(), *pe=End();
472T const *pa=a.Begin();
473while (p<pe) *p++ -= *pa++;
474return *this;
475}
476
477template <class T>
478NDataBlock<T>& NDataBlock<T>::operator *= (const NDataBlock<T>& a)
479{
480if(mSz==0 || mSz!=a.mSz)
481 throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
482T *p=Begin(), *pe=End();
483T const *pa=a.Begin();
484while (p<pe) *p++ *= *pa++;
485return *this;
486}
487
488template <class T>
489NDataBlock<T>& NDataBlock<T>::operator /= (const NDataBlock<T>& a)
490// Attention, aucune protection si un element de "a" est nul.
491{
492if(mSz==0 || mSz!=a.mSz)
493 throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
494T *p=Begin(), *pe=End();
495T const *pa=a.Begin();
496while (p<pe) *p++ /= *pa++;
497return *this;
498}
499
500////////////////////////////////////////////////////////////////
501//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+<T>b;
502// NDataBlock = <T>b+NDataBlock;
503
504template <class T>
505NDataBlock<T> NDataBlock<T>::Add(T b) const
506// Pour A+b
507{
508NDataBlock<T> result(*this); result.SetTemp(true);
509result += b;
510return result;
511}
512
513template <class T>
514NDataBlock<T> NDataBlock<T>::Sub(T b) const
515// Pour A-b
516{
517NDataBlock<T> result(*this); result.SetTemp(true);
518return result -= b;
519}
520
521template <class T>
522NDataBlock<T> NDataBlock<T>::SubInv(T b) const
523// Pour b-A
524{
525NDataBlock<T> result(*this); result.SetTemp(true);
526T *p=result.Begin(), *pe=result.End();
527T const *pa=this->Begin();
528while(p<pe) {*p++ = b - *pa++;}
529return result;
530}
531
532template <class T>
533NDataBlock<T> NDataBlock<T>::Mul(T b) const
534// Pour A*b
535{
536NDataBlock<T> result(*this); result.SetTemp(true);
537return result *= b;
538}
539
540template <class T>
541NDataBlock<T> NDataBlock<T>::Div(T b) const
542// Pour A/b
543{
544NDataBlock<T> result(*this); result.SetTemp(true);
545return result /= b;
546}
547
548template <class T>
549NDataBlock<T> NDataBlock<T>::DivInv(T b) const
550// Pour b/A
551{
552NDataBlock<T> result(*this); result.SetTemp(true);
553T *p=result.Begin(), *pe=result.End();
554T const *pa = this->Begin();
555while(p<pe) {*p++ = b / *pa++;}
556return result;
557}
558
559////////////////////////////////////////////////////////////////
560//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock;
561
562template <class T>
563NDataBlock<T> NDataBlock<T>::Add(const NDataBlock<T>& b) const
564// Pour A+B
565{
566if(mSz!=b.mSz)
567 throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n"));
568NDataBlock<T> result; result.SetTemp(true);
569if(b.IsTemp()) {result.Share(b); result += *this;}
570 else {result.CloneOrShare(*this); result += b;}
571return result;
572}
573
574template <class T>
575NDataBlock<T> NDataBlock<T>::Mul(const NDataBlock<T>& b) const
576// Pour A*B
577{
578if(mSz!=b.mSz)
579 throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n"));
580NDataBlock<T> result; result.SetTemp(true);
581if(b.IsTemp()) {result.Share(b); result *= *this;}
582 else {result.CloneOrShare(*this); result *= b;}
583return result;
584}
585
586template <class T>
587NDataBlock<T> NDataBlock<T>::Sub(const NDataBlock<T>& b) const
588// Pour A-B
589{
590if(mSz!=b.mSz)
591 throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n"));
592NDataBlock<T> result; result.SetTemp(true);
593if(b.IsTemp()) {
594 result.Share(b);
595 T *p=result.Begin(), *pe=result.End(); T const *pa=Begin();
596 while(p<pe) {*p = *pa++ - *p; p++;}
597} else {result.CloneOrShare(*this); result -= b;}
598return result;
599}
600
601template <class T>
602NDataBlock<T> NDataBlock<T>::Div(const NDataBlock<T>& b) const
603// Pour A/B
604{
605if(mSz!=b.mSz)
606 throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n"));
607NDataBlock<T> result; result.SetTemp(true);
608if(b.IsTemp()) {
609 result.Share(b);
610 T *p=result.Begin(), *pe=result.End(); T const *pa=Begin();
611 while(p<pe) {*p = *pa++ / *p; p++;}
612} else {result.CloneOrShare(*this); result /= b;}
613return result;
614}
615
616////////////////////////////////////////////////////////////////
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
628// Pour pouvoir ecrire des tableaux de complex, en attendant
629// PIn/POutPersist::Get/Put(complex<>)
630#include "piocmplx.h"
631
632template <class T>
633FIO_NDataBlock<T>::FIO_NDataBlock()
634{
635dobj=new NDataBlock<T>;
636ownobj=true;
637}
638
639template <class T>
640FIO_NDataBlock<T>::FIO_NDataBlock(string const & filename)
641{
642dobj=new NDataBlock<T>;
643ownobj=true;
644Read(filename);
645}
646
647template <class T>
648FIO_NDataBlock<T>::FIO_NDataBlock(const NDataBlock<T> & obj)
649{
650dobj = new NDataBlock<T>(obj);
651ownobj=true;
652}
653
654template <class T>
655FIO_NDataBlock<T>::FIO_NDataBlock(NDataBlock<T> * obj)
656{
657dobj = obj;
658ownobj=false;
659}
660
661template <class T>
662FIO_NDataBlock<T>::~FIO_NDataBlock()
663{
664if (ownobj && dobj) delete dobj;
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]);
681else if (itab[1] != dobj->Size()) dobj->ReSize(itab[1]);
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
691// On ecrit 3 uint_8
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
702///////////////////////////////////////////////////////////////
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>
713#pragma define_template NDataBlock< complex<float> >
714#pragma define_template NDataBlock< complex<double> >
715// Instances des delegues FileIO (PPersist)
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> >
727#endif
728
729#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
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>;
739template class NDataBlock< complex<float> >;
740template class NDataBlock< complex<double> >;
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> >;
753#endif
Note: See TracBrowser for help on using the repository browser.