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

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

encore version inter cmv 23/4/99

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