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

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

version intermediaire cmv 23/4/99

File size: 13.3 KB
RevLine 
[245]1#include "machdefs.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <iostream.h>
5#include <complex>
6#include "pexceptions.h"
7#include "ndatablock.h"
8
9#define DEBUG_NDATABLOCK
10
11#ifdef DEBUG_NDATABLOCK
12 static size_t NallocData = 0;
13 static size_t NallocSRef = 0;
14#endif
15
16// LOGIQUE DE BASE:
17// - le createur par copie et la surcharge de l operateur = "partage" les donnees
18// - gestion du partage de reference
19
20//************ Createur, Destructeur, gestion des donnees
21
22template <class T>
23NDataBlock<T>::NDataBlock(size_t n)
24// Createur d'une structure de "n" donnees
25: mSz(0), mSRef(NULL), mIsTemp(false)
26{
27Alloc(n);
28}
29
30template <class T>
31NDataBlock<T>::NDataBlock(size_t n, T* data, Bridge* br)
32// Createur d'une structure de "n" donnees, avec donnees preallouees
33: mSz(0), mSRef(NULL), mIsTemp(false)
34{
35Alloc(n,data,br);
36}
37
38template <class T>
39NDataBlock<T>::NDataBlock()
40// Createur par default
41: mSz(0), mSRef(NULL), mIsTemp(false)
42{
43}
44
45template <class T>
46NDataBlock<T>::NDataBlock(NDataBlock<T>& a)
47// Createur par copie
48// ATTENTION: partage les donnees avec "a"
49// Ecriture: NDataBlock a = b;
50// NDataBlock a(b)
51: mSz(0), mSRef(NULL), mIsTemp(false)
52{
53Share(a);
54}
55
56template <class T>
57NDataBlock<T>::NDataBlock(NDataBlock<T>& a,bool share)
58// Createur avec choix de partager ou non
59: mSz(0), mSRef(NULL), mIsTemp(false)
60{
61if(share) Share(a); else Clone(a);
62}
63
64template <class T>
65NDataBlock<T>::~NDataBlock()
66// Destructeur
67{
68Delete();
69}
70
71template <class T>
72void NDataBlock<T>::Alloc(size_t n,T* data,Bridge* br)
73// Allocation d'un NOUVEL espace de stoquage
74// Si data==NULL : allocation de l'espace memoire
75// data!=NULL : partage des donnees avec l'adresse data
76// Si br==NULL : les donnees nous appartiennent
77// br!=NULL : les donnees ne nous appartiennent pas (ex Blitz)
[257]78// Exemple: on veut connecter a un tableau de T*
79// -- On veut que NDataBlock ne desalloue pas le tableau
80// float *x = new float[5]; ... remplissage de x[] ...;
81// NDataBlock A(5,x,new Bridge);
82// delete [] x; // Il faut deleter explicitement
83// -- On veut que NDataBlock desalloue le tableau
84// ( Ne Pas Faire "delete [] x;" )
85// float *x = new float[5]; ... remplissage de x[] ...;
86// NDataBlock A(5,x);
87// -- Autre solution:
88// NDataBlock A(5); A.FillFrom(5,x);
[245]89{
90#ifdef DEBUG_NDATABLOCK
[257]91cout<<"DEBUG_NDataBlock::Alloc("<<n<<") mSRef="<<mSRef<<endl;
[245]92#endif
93if(n==0) throw(SzMismatchError("NDataBlock::Alloc n==0\n"));
94if(mSRef) Delete();
95mSz = n;
96mSRef = new NDREF;
97mSRef->nref = 1;
98if(data) mSRef->data = data; else mSRef->data = new T[n];
99mSRef->bridge = br;
100#ifdef DEBUG_NDATABLOCK
101if(!data) NallocData++; NallocSRef++;
[257]102cout<<"DEBUG_NDataBlock::Alloc("<<n<<") mSRef="<<mSRef
[259]103 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
[245]104 <<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
105#endif
106}
107
108template <class T>
109void NDataBlock<T>::Clone(NDataBlock<T>& a)
110// Clone (copie de donnee) a partir de "a"
111{
112#ifdef DEBUG_NDATABLOCK
[257]113 cout<<"DEBUG_NDataBlock::Clone("<<&a<<")"<<endl;
[245]114#endif
115if(!a.mSRef) {mSz=0; mSRef=NULL;} // cas ou "a" est cree par defaut
116else if(a.IsTemp()) Share(a);
[249]117else {Alloc(a.mSz); memcpy(Data(),a.Data(),mSz*sizeof(T));}
[245]118}
119
120template <class T>
121void NDataBlock<T>::Share(NDataBlock<T>& a)
122// Partage des donnees avec "a"
123{
124#ifdef DEBUG_NDATABLOCK
[257]125cout<<"DEBUG_NDataBlock::Share("<<&a<<") a.mSRef="<<a.mSRef<<" mSRef="<<mSRef<<endl;
[245]126#endif
127if(&a==NULL) throw(NullPtrError("NDataBlock::Share &a==NULL\n"));
128// on ne peut partager si "a" pas alloue
129if(!a.mSRef) throw(NullPtrError("NDataBlock::Share not allocated a\n"));
130if(mSRef) Delete();
131mSz = a.mSz; mSRef = a.mSRef; mSRef->nref++;
132#ifdef DEBUG_NDATABLOCK
[257]133cout<<"DEBUG_...NDataBlock::Share("<<&a<<") mSRef="<<mSRef
[259]134 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data<<endl;
[245]135#endif
136}
137
138template <class T>
139void NDataBlock<T>::Delete(void)
140// Pour detruire les pointeurs en tenant compte des references
141{
[259]142#ifdef DEBUG_NDATABLOCK
143cout<<"DEBUG_NDataBlock::Delete() mSRef="<<mSRef;
144if(mSRef) cout<<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<<mSRef->data;
145cout<<endl;
146#endif
[245]147if(mSRef==NULL) return; // cas du createur par defaut
148mSRef->nref--;
149if(mSRef->nref != 0) {
150#ifdef DEBUG_NDATABLOCK
[257]151 cout<<"DEBUG_...NDataBlock::Delete() pas de desallocation il reste nref="<<mSRef->nref<<endl;
[245]152#endif
153 return;
154}
155#ifdef DEBUG_NDATABLOCK
156if(!mSRef->bridge) NallocData--; NallocSRef--;
[257]157cout<<"DEBUG_...NNDataBlock::Delete() desallocation complete il reste nref="<<mSRef->nref
[245]158 <<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
159#endif
160// Si il y a un Bridge les donnees ne n'appartiennent pas, on detruit le Bridge
161if(mSRef->bridge) delete mSRef->bridge;
162// sinon, les donnees ont ete allouees par nos soins, on libere l'espace memoire
163else delete [] mSRef->data;
164mSRef->bridge=NULL; mSRef->data=NULL;
165delete mSRef; mSRef=NULL;
166}
167
168template <class T>
[259]169void NDataBlock<T>::Reset(T v)
170{
171if(mSRef==NULL) return;
172if(mSRef->data==NULL) return;
173if(mSz==0) return;
174T *p=Begin(), *pe=End();
175while(p<pe) *p++ = v;
176}
177
178template <class T>
[245]179void NDataBlock<T>::ReSize(size_t n)
180// Re-dimension, dans ce cas re-allocation de la place
181{
182Alloc(n);
183}
184
[257]185template <class T>
186void NDataBlock<T>::FillFrom(size_t n,T* data)
187// Remplissage par un tableau de donnees
188// - Si classe vide : creation de l'espace memoire
189// - Si classe connectee : on ecrit selon la longueur
190{
191if(data==NULL) throw(NullPtrError("NDataBlock::FillFrom data==NULL\n"));
192if(n==0) throw(ParmError("NDataBlock::FillFrom n<=0\n"));
193if(mSRef==NULL) Alloc(n); // cas du createur par default
194if(mSz<n) n= mSz;
195memcpy(Data(),data,n*sizeof(T));
196}
197
[245]198//**** Impression
199
200template <class T>
201void NDataBlock<T>::Print(size_t i1,size_t n)
202// Impression de n elements a partir de i1
203{
204size_t nr = 0;
205T* p = NULL;
206if(mSRef) {nr = mSRef->nref; p = mSRef->data;}
[259]207cout<<"NDataBlock::Print nel="<<mSz<<" nref="<<nr<<" ("<<p<<")"<<endl;
[249]208if(i1>=mSz || n<=0 || !p) return;
[245]209size_t i2 = i1+n; if(i2>mSz) i2=mSz;
[257]210size_t im = 1; bool enl;
[245]211while(i1<i2) {
[257]212 enl = false;
[245]213 cout<<" "<<(*this)(i1); i1++;
[257]214 if(im==10) {cout<<"\n"; im=1; enl=true;} else im++;
[245]215}
[257]216if(!enl) cout<<endl;
[245]217}
218
219//**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b;
220
221template <class T>
[249]222NDataBlock<T>& NDataBlock<T>::operator = (NDataBlock<T>& a)
[245]223// surcharge avec partage des donnees
224// Ecriture: NDataBlock a; a = b;
225// NDataBlock a(10); a = b; (a est re-affecte)
226{
227if(this == &a) return *this;
228if(a.mSz!=mSz) throw(SzMismatchError("NDataBlock::operator=A size mismatch/null\n"));
229Share(a);
230return *this;
231}
232
233template <class T>
[249]234NDataBlock<T>& NDataBlock<T>::operator = (T v)
[245]235// surcharge avec copie des donnees (pas de partage)
236// "this" est sur-ecrit, attention au partage de reference!
237// NDataBlock a; a = v; ou bien NDataBlock a(10); a = v;
238{
239if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n"));
[249]240T *p=Begin(), *pe=End();
[245]241while (p<pe) *p++ = v;
242return *this;
243}
244
245//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += <T> b;
246
247template <class T>
248NDataBlock<T>& NDataBlock<T>::operator += (T b)
249{
250if(mSz==0) throw(SzMismatchError("NDataBlock::operator+=v null size\n"));
[249]251T *p=Begin(), *pe=End();
[245]252while (p<pe) *p++ += b;
253return *this;
254}
255
256template <class T>
257NDataBlock<T>& NDataBlock<T>::operator -= (T b)
258{
259if(mSz==0) throw(SzMismatchError("NDataBlock::operator-=v null size\n"));
[249]260T *p=Begin(), *pe=End();
[245]261while (p<pe) *p++ -= b;
262return *this;
263}
264
265template <class T>
266NDataBlock<T>& NDataBlock<T>::operator *= (T b)
267{
268if(mSz==0) throw(SzMismatchError("NDataBlock::operator*=v null size\n"));
[249]269T *p=Begin(), *pe=End();
[245]270while (p<pe) *p++ *= b;
271return *this;
272}
273
274template <class T>
275NDataBlock<T>& NDataBlock<T>::operator /= (T b)
276{
[249]277if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
[245]278if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
[249]279T *p=Begin(), *pe=End();
[245]280while (p<pe) *p++ /= b;
281return *this;
282}
283
284//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock;
285
286template <class T>
[249]287NDataBlock<T>& NDataBlock<T>::operator += (NDataBlock<T>& a)
[245]288{
289if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
[249]290T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]291while (p<pe) *p++ += *pa++; // ca marche meme si *this=a
292return *this;
293}
294
295template <class T>
[249]296NDataBlock<T>& NDataBlock<T>::operator -= (NDataBlock<T>& a)
[245]297{
298if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
[249]299T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]300while (p<pe) *p++ -= *pa++; // ca marche meme si *this=a
301return *this;
302}
303
304template <class T>
[249]305NDataBlock<T>& NDataBlock<T>::operator *= (NDataBlock<T>& a)
[245]306{
307if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
[249]308T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]309while (p<pe) *p++ *= *pa++; // ca marche meme si *this=a
310return *this;
311}
312
313template <class T>
[249]314NDataBlock<T>& NDataBlock<T>::operator /= (NDataBlock<T>& a)
[245]315{
316if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
[249]317T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]318while (p<pe) *p++ /= *pa++;
319return *this;
320}
321
322//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+<T>b; NDataBlock = <T>b+NDataBlock;
323// ATTENTION: re-affectation imposee
324
325template <class T>
[259]326NDataBlock<T> Add(T b)
[257]327// Pour A+b
[245]328{
[257]329NDataBlock<T>& a = *this;
[245]330NDataBlock<T> result(a,false); result.SetTemp(true);
[259]331return result += b;
[245]332}
333
334template <class T>
[259]335NDataBlock<T> Sub(T b)
[257]336// Pour A-b
[245]337{
[257]338NDataBlock<T>& a = *this;
[245]339NDataBlock<T> result(a,false); result.SetTemp(true);
[259]340return result -= b;
[245]341}
342
343template <class T>
[259]344NDataBlock<T> SubInv(T b)
[257]345// Pour b-A
[245]346{
[257]347NDataBlock<T>& a = *this;
[245]348NDataBlock<T> result(a,false); result.SetTemp(true);
[249]349T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]350while(p<pe) {*p++ = b - *pa++;}
351return result;
352}
353
354template <class T>
[259]355NDataBlock<T> Mult(T b)
[257]356// Pour A*b
[245]357{
[257]358NDataBlock<T>& a = *this;
[245]359NDataBlock<T> result(a,false); result.SetTemp(true);
[259]360return result *= b;
[245]361}
362
363template <class T>
[259]364NDataBlock<T> Div(T b)
[257]365// Pour A/b
[245]366{
[257]367NDataBlock<T>& a = *this;
[245]368NDataBlock<T> result(a,false); result.SetTemp(true);
[259]369return result /= b;
[245]370}
371
372template <class T>
[259]373NDataBlock<T> DivInv(T b)
[257]374// Pour b/A
[245]375{
[257]376NDataBlock<T>& a = *this;
[245]377NDataBlock<T> result(a,false); result.SetTemp(true);
[249]378T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]379while(p<pe) {*p++ = b / *pa++;}
380return result;
381}
382
383//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock;
384
385template <class T>
[259]386NDataBlock<T> Add(NDataBlock<T>& b)
[257]387// Pour A+B
[245]388{
[257]389NDataBlock<T>& a = *this;
[245]390if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n"));
391if(b.IsTemp()) {
392 NDataBlock<T> result(b,true); result.SetTemp(true);
393 return result += a;
394} else {
395 NDataBlock<T> result(a,false); result.SetTemp(true);
396 return result += b;
397}
398}
399
400template <class T>
[259]401NDataBlock<T> Mul(NDataBlock<T>& b)
[257]402// Pour A*B
[245]403{
[257]404NDataBlock<T>& a = *this;
[245]405if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n"));
406if(b.IsTemp()) {
407 NDataBlock<T> result(b,true); result.SetTemp(true);
408 return result *= a;
409} else {
410 NDataBlock<T> result(a,false); result.SetTemp(true);
411 return result *= b;
412}
413}
414
415template <class T>
[259]416NDataBlock<T> Sub(NDataBlock<T>& b)
[257]417// Pour A-B
[245]418{
[257]419NDataBlock<T>& a = *this;
[245]420if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n"));
421if(b.IsTemp()) {
422 NDataBlock<T> result(b,true); result.SetTemp(true);
[249]423 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]424 while(p<pe) {*p = *pa++ - *p; p++;}
425 return result;
426} else {
427 NDataBlock<T> result(a,false); result.SetTemp(true);
428 return result -= b;
429}
430}
431
432template <class T>
[259]433NDataBlock<T> Div(NDataBlock<T>& b)
[257]434// Pour A/B
[245]435{
[257]436NDataBlock<T>& a = *this;
[245]437if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n"));
438if(b.IsTemp()) {
439 NDataBlock<T> result(b,true); result.SetTemp(true);
[249]440 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]441 while(p<pe) {*p = *pa++ / *p; p++;}
442 return result;
443} else {
444 NDataBlock<T> result(a,false); result.SetTemp(true);
445 return result /= b;
446}
447}
448
449
450#ifdef __CXX_PRAGMA_TEMPLATES__
451#pragma define_template NDataBlock<uint_1>
452#pragma define_template NDataBlock<uint_2>
453#pragma define_template NDataBlock<int_2>
454#pragma define_template NDataBlock<int_4>
455#pragma define_template NDataBlock<int_8>
456#pragma define_template NDataBlock<uint_2>
457#pragma define_template NDataBlock<uint_4>
458#pragma define_template NDataBlock<uint_8>
459#pragma define_template NDataBlock<r_4>
460#pragma define_template NDataBlock<r_8>
[257]461// pas de definitions de cout pour les complex ??
462//#pragma define_template NDataBlock< complex<float> >
463//#pragma define_template NDataBlock< complex<double> >
[245]464#endif
465
466#ifdef __GNU_TEMPLATES__
467template class NDataBlock<uint_1>;
468template class NDataBlock<uint_2>;
469template class NDataBlock<int_2>;
470template class NDataBlock<int_4>;
471template class NDataBlock<int_8>;
472template class NDataBlock<uint_2>;
473template class NDataBlock<uint_4>;
474template class NDataBlock<uint_8>;
475template class NDataBlock<r_4>;
476template class NDataBlock<r_8>;
[249]477template class NDataBlock< complex<float> >;
478template class NDataBlock< complex<double> >;
[245]479#endif
480
481#if defined(__ANSI_TEMPLATES__)
482template class NDataBlock<uint_1>;
483template class NDataBlock<uint_2>;
484template class NDataBlock<int_2>;
485template class NDataBlock<int_4>;
486template class NDataBlock<int_8>;
487template class NDataBlock<uint_2>;
488template class NDataBlock<uint_4>;
489template class NDataBlock<uint_8>;
490template class NDataBlock<r_4>;
491template class NDataBlock<r_8>;
[249]492template class NDataBlock< complex<float> >;
493template class NDataBlock< complex<double> >;
[245]494#endif
Note: See TracBrowser for help on using the repository browser.