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

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

version qui compile cmv 23/4/99

File size: 13.2 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
143 cout<<"DEBUG_NDataBlock::Delete() mSRef="<<mSRef;
144 if(mSRef) cout<<" mSRef->nref"<<mSRef->nref<<" mSRef->data "<<mSRef->data;
145 cout<<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>::ReSize(size_t n)
170// Re-dimension, dans ce cas re-allocation de la place
171{
172Alloc(n);
173}
174
175template <class T>
176void NDataBlock<T>::FillFrom(size_t n,T* data)
177// Remplissage par un tableau de donnees
178// - Si classe vide : creation de l'espace memoire
179// - Si classe connectee : on ecrit selon la longueur
180{
181if(data==NULL) throw(NullPtrError("NDataBlock::FillFrom data==NULL\n"));
182if(n==0) throw(ParmError("NDataBlock::FillFrom n<=0\n"));
183if(mSRef==NULL) Alloc(n); // cas du createur par default
184if(mSz<n) n= mSz;
185memcpy(Data(),data,n*sizeof(T));
186}
187
188//**** Impression
189
190template <class T>
191void NDataBlock<T>::Print(size_t i1,size_t n)
192// Impression de n elements a partir de i1
193{
194size_t nr = 0;
195T* p = NULL;
196if(mSRef) {nr = mSRef->nref; p = mSRef->data;}
197cout<<"NDataBlock::Print nel=%ld nref=%d (%p)\n",mSz,nr,p;
198if(i1>=mSz || n<=0 || !p) return;
199size_t i2 = i1+n; if(i2>mSz) i2=mSz;
200size_t im = 1; bool enl;
201while(i1<i2) {
202 enl = false;
203 cout<<" "<<(*this)(i1); i1++;
204 if(im==10) {cout<<"\n"; im=1; enl=true;} else im++;
205}
206if(!enl) cout<<endl;
207}
208
209//**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b;
210
211template <class T>
212NDataBlock<T>& NDataBlock<T>::operator = (NDataBlock<T>& a)
213// surcharge avec partage des donnees
214// Ecriture: NDataBlock a; a = b;
215// NDataBlock a(10); a = b; (a est re-affecte)
216{
217if(this == &a) return *this;
218if(a.mSz!=mSz) throw(SzMismatchError("NDataBlock::operator=A size mismatch/null\n"));
219Share(a);
220return *this;
221}
222
223template <class T>
224NDataBlock<T>& NDataBlock<T>::operator = (T v)
225// surcharge avec copie des donnees (pas de partage)
226// "this" est sur-ecrit, attention au partage de reference!
227// NDataBlock a; a = v; ou bien NDataBlock a(10); a = v;
228{
229if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n"));
230T *p=Begin(), *pe=End();
231while (p<pe) *p++ = v;
232return *this;
233}
234
235//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += <T> b;
236
237template <class T>
238NDataBlock<T>& NDataBlock<T>::operator += (T b)
239{
240if(mSz==0) throw(SzMismatchError("NDataBlock::operator+=v null size\n"));
241T *p=Begin(), *pe=End();
242while (p<pe) *p++ += b;
243return *this;
244}
245
246template <class T>
247NDataBlock<T>& NDataBlock<T>::operator -= (T b)
248{
249if(mSz==0) throw(SzMismatchError("NDataBlock::operator-=v null size\n"));
250T *p=Begin(), *pe=End();
251while (p<pe) *p++ -= b;
252return *this;
253}
254
255template <class T>
256NDataBlock<T>& NDataBlock<T>::operator *= (T b)
257{
258if(mSz==0) throw(SzMismatchError("NDataBlock::operator*=v null size\n"));
259T *p=Begin(), *pe=End();
260while (p<pe) *p++ *= b;
261return *this;
262}
263
264template <class T>
265NDataBlock<T>& NDataBlock<T>::operator /= (T b)
266{
267if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
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
274//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock;
275
276template <class T>
277NDataBlock<T>& NDataBlock<T>::operator += (NDataBlock<T>& a)
278{
279if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
280T *p=Begin(), *pe=End(), *pa=a.Begin();
281while (p<pe) *p++ += *pa++; // ca marche meme si *this=a
282return *this;
283}
284
285template <class T>
286NDataBlock<T>& NDataBlock<T>::operator -= (NDataBlock<T>& a)
287{
288if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
289T *p=Begin(), *pe=End(), *pa=a.Begin();
290while (p<pe) *p++ -= *pa++; // ca marche meme si *this=a
291return *this;
292}
293
294template <class T>
295NDataBlock<T>& NDataBlock<T>::operator *= (NDataBlock<T>& a)
296{
297if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
298T *p=Begin(), *pe=End(), *pa=a.Begin();
299while (p<pe) *p++ *= *pa++; // ca marche meme si *this=a
300return *this;
301}
302
303template <class T>
304NDataBlock<T>& NDataBlock<T>::operator /= (NDataBlock<T>& a)
305{
306if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
307T *p=Begin(), *pe=End(), *pa=a.Begin();
308while (p<pe) *p++ /= *pa++;
309return *this;
310}
311
312//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+<T>b; NDataBlock = <T>b+NDataBlock;
313// ATTENTION: re-affectation imposee
314
315template <class T>
316NDataBlock<T>& Add(T b)
317// Pour A+b
318{
319NDataBlock<T>& a = *this;
320NDataBlock<T> result(a,false); result.SetTemp(true);
321return (result += b);
322}
323
324template <class T>
325NDataBlock<T>& Sub(T b)
326// Pour A-b
327{
328NDataBlock<T>& a = *this;
329NDataBlock<T> result(a,false); result.SetTemp(true);
330return (result -= b);
331}
332
333template <class T>
334NDataBlock<T>& SubInv(T b)
335// Pour b-A
336{
337NDataBlock<T>& a = *this;
338NDataBlock<T> result(a,false); result.SetTemp(true);
339T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
340while(p<pe) {*p++ = b - *pa++;}
341return result;
342}
343
344template <class T>
345NDataBlock<T>& Mult(T b)
346// Pour A*b
347{
348NDataBlock<T>& a = *this;
349NDataBlock<T> result(a,false); result.SetTemp(true);
350return (result *= b);
351}
352
353template <class T>
354NDataBlock<T>& Div(T b)
355// Pour A/b
356{
357NDataBlock<T>& a = *this;
358NDataBlock<T> result(a,false); result.SetTemp(true);
359return (result /= b);
360}
361
362template <class T>
363NDataBlock<T>& DivInv(T b)
364// Pour b/A
365{
366NDataBlock<T>& a = *this;
367NDataBlock<T> result(a,false); result.SetTemp(true);
368T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
369while(p<pe) {*p++ = b / *pa++;}
370return result;
371}
372
373//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock;
374
375template <class T>
376NDataBlock<T>& Add(const NDataBlock<T>& b)
377// Pour A+B
378{
379NDataBlock<T>& a = *this;
380if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n"));
381if(b.IsTemp()) {
382 NDataBlock<T> result(b,true); result.SetTemp(true);
383 return result += a;
384} else {
385 NDataBlock<T> result(a,false); result.SetTemp(true);
386 return result += b;
387}
388}
389
390template <class T>
391NDataBlock<T>& Mul(const NDataBlock<T>& b)
392// Pour A*B
393{
394NDataBlock<T>& a = *this;
395if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n"));
396if(b.IsTemp()) {
397 NDataBlock<T> result(b,true); result.SetTemp(true);
398 return result *= a;
399} else {
400 NDataBlock<T> result(a,false); result.SetTemp(true);
401 return result *= b;
402}
403}
404
405template <class T>
406NDataBlock<T>& Sub(const NDataBlock<T>& b)
407// Pour A-B
408{
409NDataBlock<T>& a = *this;
410if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n"));
411if(b.IsTemp()) {
412 NDataBlock<T> result(b,true); result.SetTemp(true);
413 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
414 while(p<pe) {*p = *pa++ - *p; p++;}
415 return result;
416} else {
417 NDataBlock<T> result(a,false); result.SetTemp(true);
418 return result -= b;
419}
420}
421
422template <class T>
423NDataBlock<T>& Div(const NDataBlock<T>& b)
424// Pour A/B
425{
426NDataBlock<T>& a = *this;
427if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n"));
428if(b.IsTemp()) {
429 NDataBlock<T> result(b,true); result.SetTemp(true);
430 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
431 while(p<pe) {*p = *pa++ / *p; p++;}
432 return result;
433} else {
434 NDataBlock<T> result(a,false); result.SetTemp(true);
435 return result /= b;
436}
437}
438
439
440#ifdef __CXX_PRAGMA_TEMPLATES__
441#pragma define_template NDataBlock<uint_1>
442#pragma define_template NDataBlock<uint_2>
443#pragma define_template NDataBlock<int_2>
444#pragma define_template NDataBlock<int_4>
445#pragma define_template NDataBlock<int_8>
446#pragma define_template NDataBlock<uint_2>
447#pragma define_template NDataBlock<uint_4>
448#pragma define_template NDataBlock<uint_8>
449#pragma define_template NDataBlock<r_4>
450#pragma define_template NDataBlock<r_8>
451// pas de definitions de cout pour les complex ??
452//#pragma define_template NDataBlock< complex<float> >
453//#pragma define_template NDataBlock< complex<double> >
454#endif
455
456#ifdef __GNU_TEMPLATES__
457template class NDataBlock<uint_1>;
458template class NDataBlock<uint_2>;
459template class NDataBlock<int_2>;
460template class NDataBlock<int_4>;
461template class NDataBlock<int_8>;
462template class NDataBlock<uint_2>;
463template class NDataBlock<uint_4>;
464template class NDataBlock<uint_8>;
465template class NDataBlock<r_4>;
466template class NDataBlock<r_8>;
467template class NDataBlock< complex<float> >;
468template class NDataBlock< complex<double> >;
469#endif
470
471#if defined(__ANSI_TEMPLATES__)
472template class NDataBlock<uint_1>;
473template class NDataBlock<uint_2>;
474template class NDataBlock<int_2>;
475template class NDataBlock<int_4>;
476template class NDataBlock<int_8>;
477template class NDataBlock<uint_2>;
478template class NDataBlock<uint_4>;
479template class NDataBlock<uint_8>;
480template class NDataBlock<r_4>;
481template class NDataBlock<r_8>;
482template class NDataBlock< complex<float> >;
483template class NDataBlock< complex<double> >;
484#endif
Note: See TracBrowser for help on using the repository browser.