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
Line 
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)
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);
89{
90#ifdef DEBUG_NDATABLOCK
91cout<<"DEBUG_NDataBlock::Alloc("<<n<<") mSRef="<<mSRef<<endl;
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++;
102cout<<"DEBUG_NDataBlock::Alloc("<<n<<") mSRef="<<mSRef
103 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
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
113 cout<<"DEBUG_NDataBlock::Clone("<<&a<<")"<<endl;
114#endif
115if(!a.mSRef) {mSz=0; mSRef=NULL;} // cas ou "a" est cree par defaut
116else if(a.IsTemp()) Share(a);
117else {Alloc(a.mSz); memcpy(Data(),a.Data(),mSz*sizeof(T));}
118}
119
120template <class T>
121void NDataBlock<T>::Share(NDataBlock<T>& a)
122// Partage des donnees avec "a"
123{
124#ifdef DEBUG_NDATABLOCK
125cout<<"DEBUG_NDataBlock::Share("<<&a<<") a.mSRef="<<a.mSRef<<" mSRef="<<mSRef<<endl;
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
133cout<<"DEBUG_...NDataBlock::Share("<<&a<<") mSRef="<<mSRef
134 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data<<endl;
135#endif
136}
137
138template <class T>
139void NDataBlock<T>::Delete(void)
140// Pour detruire les pointeurs en tenant compte des references
141{
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
147if(mSRef==NULL) return; // cas du createur par defaut
148mSRef->nref--;
149if(mSRef->nref != 0) {
150#ifdef DEBUG_NDATABLOCK
151 cout<<"DEBUG_...NDataBlock::Delete() pas de desallocation il reste nref="<<mSRef->nref<<endl;
152#endif
153 return;
154}
155#ifdef DEBUG_NDATABLOCK
156if(!mSRef->bridge) NallocData--; NallocSRef--;
157cout<<"DEBUG_...NNDataBlock::Delete() desallocation complete il reste nref="<<mSRef->nref
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>
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>
179void NDataBlock<T>::ReSize(size_t n)
180// Re-dimension, dans ce cas re-allocation de la place
181{
182Alloc(n);
183}
184
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
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;}
207cout<<"NDataBlock::Print nel="<<mSz<<" nref="<<nr<<" ("<<p<<")"<<endl;
208if(i1>=mSz || n<=0 || !p) return;
209size_t i2 = i1+n; if(i2>mSz) i2=mSz;
210size_t im = 1; bool enl;
211while(i1<i2) {
212 enl = false;
213 cout<<" "<<(*this)(i1); i1++;
214 if(im==10) {cout<<"\n"; im=1; enl=true;} else im++;
215}
216if(!enl) cout<<endl;
217}
218
219//**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b;
220
221template <class T>
222NDataBlock<T>& NDataBlock<T>::operator = (NDataBlock<T>& a)
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>
234NDataBlock<T>& NDataBlock<T>::operator = (T v)
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"));
240T *p=Begin(), *pe=End();
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"));
251T *p=Begin(), *pe=End();
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"));
260T *p=Begin(), *pe=End();
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"));
269T *p=Begin(), *pe=End();
270while (p<pe) *p++ *= b;
271return *this;
272}
273
274template <class T>
275NDataBlock<T>& NDataBlock<T>::operator /= (T b)
276{
277if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
278if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
279T *p=Begin(), *pe=End();
280while (p<pe) *p++ /= b;
281return *this;
282}
283
284//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock;
285
286template <class T>
287NDataBlock<T>& NDataBlock<T>::operator += (NDataBlock<T>& a)
288{
289if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
290T *p=Begin(), *pe=End(), *pa=a.Begin();
291while (p<pe) *p++ += *pa++; // ca marche meme si *this=a
292return *this;
293}
294
295template <class T>
296NDataBlock<T>& NDataBlock<T>::operator -= (NDataBlock<T>& a)
297{
298if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
299T *p=Begin(), *pe=End(), *pa=a.Begin();
300while (p<pe) *p++ -= *pa++; // ca marche meme si *this=a
301return *this;
302}
303
304template <class T>
305NDataBlock<T>& NDataBlock<T>::operator *= (NDataBlock<T>& a)
306{
307if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
308T *p=Begin(), *pe=End(), *pa=a.Begin();
309while (p<pe) *p++ *= *pa++; // ca marche meme si *this=a
310return *this;
311}
312
313template <class T>
314NDataBlock<T>& NDataBlock<T>::operator /= (NDataBlock<T>& a)
315{
316if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
317T *p=Begin(), *pe=End(), *pa=a.Begin();
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>
326NDataBlock<T> Add(T b)
327// Pour A+b
328{
329NDataBlock<T>& a = *this;
330NDataBlock<T> result(a,false); result.SetTemp(true);
331return result += b;
332}
333
334template <class T>
335NDataBlock<T> Sub(T b)
336// Pour A-b
337{
338NDataBlock<T>& a = *this;
339NDataBlock<T> result(a,false); result.SetTemp(true);
340return result -= b;
341}
342
343template <class T>
344NDataBlock<T> SubInv(T b)
345// Pour b-A
346{
347NDataBlock<T>& a = *this;
348NDataBlock<T> result(a,false); result.SetTemp(true);
349T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
350while(p<pe) {*p++ = b - *pa++;}
351return result;
352}
353
354template <class T>
355NDataBlock<T> Mult(T b)
356// Pour A*b
357{
358NDataBlock<T>& a = *this;
359NDataBlock<T> result(a,false); result.SetTemp(true);
360return result *= b;
361}
362
363template <class T>
364NDataBlock<T> Div(T b)
365// Pour A/b
366{
367NDataBlock<T>& a = *this;
368NDataBlock<T> result(a,false); result.SetTemp(true);
369return result /= b;
370}
371
372template <class T>
373NDataBlock<T> DivInv(T b)
374// Pour b/A
375{
376NDataBlock<T>& a = *this;
377NDataBlock<T> result(a,false); result.SetTemp(true);
378T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
379while(p<pe) {*p++ = b / *pa++;}
380return result;
381}
382
383//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock;
384
385template <class T>
386NDataBlock<T> Add(NDataBlock<T>& b)
387// Pour A+B
388{
389NDataBlock<T>& a = *this;
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>
401NDataBlock<T> Mul(NDataBlock<T>& b)
402// Pour A*B
403{
404NDataBlock<T>& a = *this;
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>
416NDataBlock<T> Sub(NDataBlock<T>& b)
417// Pour A-B
418{
419NDataBlock<T>& a = *this;
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);
423 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
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>
433NDataBlock<T> Div(NDataBlock<T>& b)
434// Pour A/B
435{
436NDataBlock<T>& a = *this;
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);
440 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
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>
461// pas de definitions de cout pour les complex ??
462//#pragma define_template NDataBlock< complex<float> >
463//#pragma define_template NDataBlock< complex<double> >
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>;
477template class NDataBlock< complex<float> >;
478template class NDataBlock< complex<double> >;
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>;
492template class NDataBlock< complex<float> >;
493template class NDataBlock< complex<double> >;
494#endif
Note: See TracBrowser for help on using the repository browser.