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

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

version temp pour reza cmv 23/4/99

File size: 13.7 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
91 cout<<"DEBUG_NDataBlock::Alloc("
92 <<n<<","<<data<<","<<br<<") mSRef="<<mSRef<<endl;
93 #endif
94if(n==0) throw(SzMismatchError("NDataBlock::Alloc n==0\n"));
95if(mSRef) Delete();
96mSz = n;
97mSRef = new NDREF;
98mSRef->nref = 1;
99if(data) mSRef->data = data; else mSRef->data = new T[n];
100mSRef->bridge = br;
101 #ifdef DEBUG_NDATABLOCK
102 if(!data) NallocData++; NallocSRef++;
103 cout<<"...DEBUG_NDataBlock::Alloc("<<n<<") mSRef="<<mSRef
104 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
105 <<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
106 #endif
107}
108
109template <class T>
110void NDataBlock<T>::Clone(NDataBlock<T>& a)
111// Clone (copie de donnee) a partir de "a"
112{
113 #ifdef DEBUG_NDATABLOCK
114 cout<<"DEBUG_NDataBlock::Clone("<<&a<<") a.mSz="
115 <<a.mSz<<" a.mSRef="<<a.mSRef<<" a.IsTemp="<<a.IsTemp()<<endl;
116 #endif
117if(!a.mSRef) {mSz=0; mSRef=NULL;} // cas ou "a" est cree par defaut
118else if(a.IsTemp()) Share(a);
119else {Alloc(a.mSz); memcpy(Data(),a.Data(),mSz*sizeof(T));}
120}
121
122template <class T>
123void NDataBlock<T>::Share(NDataBlock<T>& a)
124// Partage des donnees avec "a"
125{
126 #ifdef DEBUG_NDATABLOCK
127 cout<<"DEBUG_NDataBlock::Share("<<&a<<") a.mSRef="<<a.mSRef<<" mSRef="<<mSRef<<endl;
128 #endif
129if(&a==NULL) throw(NullPtrError("NDataBlock::Share &a==NULL\n"));
130// on ne peut partager si "a" pas alloue
131if(!a.mSRef) throw(NullPtrError("NDataBlock::Share not allocated a\n"));
132if(mSRef) Delete();
133mSz = a.mSz; mSRef = a.mSRef; mSRef->nref++;
134 #ifdef DEBUG_NDATABLOCK
135 cout<<"...DEBUG_NDataBlock::Share("<<&a<<") mSRef="<<mSRef
136 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data<<endl;
137 #endif
138}
139
140template <class T>
141void NDataBlock<T>::Delete(void)
142// Pour detruire les pointeurs en tenant compte des references
143{
144 #ifdef DEBUG_NDATABLOCK
145 cout<<"DEBUG_NDataBlock::Delete() mSRef="<<mSRef;
146 if(mSRef) cout<<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<<mSRef->data;
147 cout<<endl;
148 #endif
149if(mSRef==NULL) return; // cas du createur par defaut
150mSRef->nref--;
151if(mSRef->nref != 0) {
152 #ifdef DEBUG_NDATABLOCK
153 cout<<"...DEBUG_NDataBlock::Delete() pas de desallocation il reste nref="
154 <<mSRef->nref<<endl;
155 #endif
156 return;
157}
158 #ifdef DEBUG_NDATABLOCK
159 if(!mSRef->bridge) NallocData--; NallocSRef--;
160 cout<<"...DEBUG_NDataBlock::Delete() desallocation complete il reste nref="
161 <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
162 #endif
163// Si il y a un Bridge les donnees ne n'appartiennent pas, on detruit le Bridge
164if(mSRef->bridge) delete mSRef->bridge;
165// sinon, les donnees ont ete allouees par nos soins, on libere l'espace memoire
166else delete [] mSRef->data;
167mSRef->bridge=NULL; mSRef->data=NULL;
168delete mSRef; mSRef=NULL;
169}
170
171template <class T>
172void NDataBlock<T>::Reset(T v)
173{
174if(mSRef==NULL) return;
175if(mSRef->data==NULL) return;
176if(mSz==0) return;
177T *p=Begin(), *pe=End();
178while(p<pe) *p++ = v;
179}
180
181template <class T>
182void NDataBlock<T>::ReSize(size_t n)
183// Re-dimension, dans ce cas re-allocation de la place
184{
185Alloc(n);
186}
187
188template <class T>
189void NDataBlock<T>::FillFrom(size_t n,T* data)
190// Remplissage par un tableau de donnees
191// - Si classe vide : creation de l'espace memoire
192// - Si classe connectee : on ecrit selon la longueur
193{
194if(data==NULL) throw(NullPtrError("NDataBlock::FillFrom data==NULL\n"));
195if(n==0) throw(ParmError("NDataBlock::FillFrom n<=0\n"));
196if(mSRef==NULL) Alloc(n); // cas du createur par default
197if(mSz<n) n= mSz;
198memcpy(Data(),data,n*sizeof(T));
199}
200
201//**** Impression
202
203template <class T>
204void NDataBlock<T>::Print(size_t i1,size_t n)
205// Impression de n elements a partir de i1
206{
207size_t nr = 0;
208T* p = NULL;
209if(mSRef) {nr = mSRef->nref; p = mSRef->data;}
210cout<<"NDataBlock::Print nel="<<mSz<<" nref="<<nr<<" ("<<p<<")"<<endl;
211if(i1>=mSz || n<=0 || !p) return;
212size_t i2 = i1+n; if(i2>mSz) i2=mSz;
213size_t im = 1; bool enl;
214while(i1<i2) {
215 enl = false;
216 cout<<" "<<(*this)(i1); i1++;
217 if(im==10) {cout<<"\n"; im=1; enl=true;} else im++;
218}
219if(!enl) cout<<endl;
220}
221
222//**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b;
223
224template <class T>
225NDataBlock<T>& NDataBlock<T>::operator = (NDataBlock<T>& a)
226// surcharge avec partage des donnees
227// Ecriture: NDataBlock a; a = b;
228// NDataBlock a(10); a = b; (a est re-affecte)
229{
230if(this == &a) return *this;
231if(a.mSz!=mSz)
232 throw(SzMismatchError("NDataBlock::operator=A size mismatch/null\n"));
233Share(a);
234return *this;
235}
236
237template <class T>
238NDataBlock<T>& NDataBlock<T>::operator = (T v)
239// surcharge avec copie des donnees (pas de partage)
240// "this" est sur-ecrit, attention au partage de reference!
241// NDataBlock a; a = v; ou bien NDataBlock a(10); a = v;
242{
243if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n"));
244T *p=Begin(), *pe=End();
245while (p<pe) *p++ = v;
246return *this;
247}
248
249//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += <T> b;
250
251template <class T>
252NDataBlock<T>& NDataBlock<T>::operator += (T b)
253{
254if(mSz==0) throw(SzMismatchError("NDataBlock::operator+=v null size\n"));
255T *p=Begin(), *pe=End();
256while (p<pe) *p++ += b;
257return *this;
258}
259
260template <class T>
261NDataBlock<T>& NDataBlock<T>::operator -= (T b)
262{
263if(mSz==0) throw(SzMismatchError("NDataBlock::operator-=v null size\n"));
264T *p=Begin(), *pe=End();
265while (p<pe) *p++ -= b;
266return *this;
267}
268
269template <class T>
270NDataBlock<T>& NDataBlock<T>::operator *= (T b)
271{
272if(mSz==0) throw(SzMismatchError("NDataBlock::operator*=v null size\n"));
273T *p=Begin(), *pe=End();
274while (p<pe) *p++ *= b;
275return *this;
276}
277
278template <class T>
279NDataBlock<T>& NDataBlock<T>::operator /= (T b)
280{
281if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
282if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
283T *p=Begin(), *pe=End();
284while (p<pe) *p++ /= b;
285return *this;
286}
287
288//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock;
289
290template <class T>
291NDataBlock<T>& NDataBlock<T>::operator += (NDataBlock<T>& a)
292{
293if(mSz==0 || mSz!=a.mSz)
294 throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
295T *p=Begin(), *pe=End(), *pa=a.Begin();
296while (p<pe) *p++ += *pa++; // ca marche meme si *this=a
297return *this;
298}
299
300template <class T>
301NDataBlock<T>& NDataBlock<T>::operator -= (NDataBlock<T>& a)
302{
303if(mSz==0 || mSz!=a.mSz)
304 throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
305T *p=Begin(), *pe=End(), *pa=a.Begin();
306while (p<pe) *p++ -= *pa++; // ca marche meme si *this=a
307return *this;
308}
309
310template <class T>
311NDataBlock<T>& NDataBlock<T>::operator *= (NDataBlock<T>& a)
312{
313if(mSz==0 || mSz!=a.mSz)
314 throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
315T *p=Begin(), *pe=End(), *pa=a.Begin();
316while (p<pe) *p++ *= *pa++; // ca marche meme si *this=a
317return *this;
318}
319
320template <class T>
321NDataBlock<T>& NDataBlock<T>::operator /= (NDataBlock<T>& a)
322{
323if(mSz==0 || mSz!=a.mSz)
324 throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
325T *p=Begin(), *pe=End(), *pa=a.Begin();
326while (p<pe) *p++ /= *pa++;
327return *this;
328}
329
330//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+<T>b; NDataBlock = <T>b+NDataBlock;
331// ATTENTION: re-affectation imposee
332
333template <class T>
334NDataBlock<T> NDataBlock<T>::Add(T b)
335// Pour A+b
336{
337NDataBlock<T>& a = *this;
338NDataBlock<T> result(a,false); result.SetTemp(true);
339return result += b;
340}
341
342template <class T>
343NDataBlock<T> NDataBlock<T>::Sub(T b)
344// Pour A-b
345{
346NDataBlock<T>& a = *this;
347NDataBlock<T> result(a,false); result.SetTemp(true);
348return result -= b;
349}
350
351template <class T>
352NDataBlock<T> NDataBlock<T>::SubInv(T b)
353// Pour b-A
354{
355NDataBlock<T>& a = *this;
356NDataBlock<T> result(a,false); result.SetTemp(true);
357T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
358while(p<pe) {*p++ = b - *pa++;}
359return result;
360}
361
362template <class T>
363NDataBlock<T> NDataBlock<T>::Mul(T b)
364// Pour A*b
365{
366NDataBlock<T>& a = *this;
367NDataBlock<T> result(a,false); result.SetTemp(true);
368return result *= b;
369}
370
371template <class T>
372NDataBlock<T> NDataBlock<T>::Div(T b)
373// Pour A/b
374{
375NDataBlock<T>& a = *this;
376NDataBlock<T> result(a,false); result.SetTemp(true);
377return result /= b;
378}
379
380template <class T>
381NDataBlock<T> NDataBlock<T>::DivInv(T b)
382// Pour b/A
383{
384NDataBlock<T>& a = *this;
385NDataBlock<T> result(a,false); result.SetTemp(true);
386T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
387while(p<pe) {*p++ = b / *pa++;}
388return result;
389}
390
391//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock;
392
393template <class T>
394NDataBlock<T> NDataBlock<T>::Add(NDataBlock<T>& b)
395// Pour A+B
396{
397NDataBlock<T>& a = *this;
398if(a.mSz!=b.mSz)
399 throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n"));
400if(b.IsTemp()) {
401 NDataBlock<T> result(b,true); result.SetTemp(true);
402 return result += a;
403} else {
404 NDataBlock<T> result(a,false); result.SetTemp(true);
405 return result += b;
406}
407}
408
409template <class T>
410NDataBlock<T> NDataBlock<T>::Mul(NDataBlock<T>& b)
411// Pour A*B
412{
413NDataBlock<T>& a = *this;
414if(a.mSz!=b.mSz)
415 throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n"));
416if(b.IsTemp()) {
417 NDataBlock<T> result(b,true); result.SetTemp(true);
418 return result *= a;
419} else {
420 NDataBlock<T> result(a,false); result.SetTemp(true);
421 return result *= b;
422}
423}
424
425template <class T>
426NDataBlock<T> NDataBlock<T>::Sub(NDataBlock<T>& b)
427// Pour A-B
428{
429NDataBlock<T>& a = *this;
430if(a.mSz!=b.mSz)
431 throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n"));
432if(b.IsTemp()) {
433 NDataBlock<T> result(b,true); result.SetTemp(true);
434 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
435 while(p<pe) {*p = *pa++ - *p; p++;}
436 return result;
437} else {
438 NDataBlock<T> result(a,false); result.SetTemp(true);
439 return result -= b;
440}
441}
442
443template <class T>
444NDataBlock<T> NDataBlock<T>::Div(NDataBlock<T>& b)
445// Pour A/B
446{
447NDataBlock<T>& a = *this;
448if(a.mSz!=b.mSz)
449 throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n"));
450if(b.IsTemp()) {
451 NDataBlock<T> result(b,true); result.SetTemp(true);
452 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
453 while(p<pe) {*p = *pa++ / *p; p++;}
454 return result;
455} else {
456 NDataBlock<T> result(a,false); result.SetTemp(true);
457 return result /= b;
458}
459}
460
461
462#ifdef __CXX_PRAGMA_TEMPLATES__
463#pragma define_template NDataBlock<uint_1>
464#pragma define_template NDataBlock<uint_2>
465#pragma define_template NDataBlock<int_2>
466#pragma define_template NDataBlock<int_4>
467#pragma define_template NDataBlock<int_8>
468#pragma define_template NDataBlock<uint_2>
469#pragma define_template NDataBlock<uint_4>
470#pragma define_template NDataBlock<uint_8>
471#pragma define_template NDataBlock<r_4>
472#pragma define_template NDataBlock<r_8>
473// pas de definitions de cout pour les complex ??
474//#pragma define_template NDataBlock< complex<float> >
475//#pragma define_template NDataBlock< complex<double> >
476#endif
477
478#ifdef __GNU_TEMPLATES__
479template class NDataBlock<uint_1>;
480template class NDataBlock<uint_2>;
481template class NDataBlock<int_2>;
482template class NDataBlock<int_4>;
483template class NDataBlock<int_8>;
484template class NDataBlock<uint_2>;
485template class NDataBlock<uint_4>;
486template class NDataBlock<uint_8>;
487template class NDataBlock<r_4>;
488template class NDataBlock<r_8>;
489template class NDataBlock< complex<float> >;
490template class NDataBlock< complex<double> >;
491#endif
492
493#if defined(__ANSI_TEMPLATES__)
494template class NDataBlock<uint_1>;
495template class NDataBlock<uint_2>;
496template class NDataBlock<int_2>;
497template class NDataBlock<int_4>;
498template class NDataBlock<int_8>;
499template class NDataBlock<uint_2>;
500template class NDataBlock<uint_4>;
501template class NDataBlock<uint_8>;
502template class NDataBlock<r_4>;
503template class NDataBlock<r_8>;
504template class NDataBlock< complex<float> >;
505template class NDataBlock< complex<double> >;
506#endif
Note: See TracBrowser for help on using the repository browser.