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
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>
[267]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>
[245]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)
[257]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);
[245]100{
[265]101 #ifdef DEBUG_NDATABLOCK
[267]102 cout<<"DEBUG_NDataBlock::Alloc("<<this<<","
103 <<n<<","<<data<<","<<br<<") mSz="<<mSz
104 <<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
[265]105 #endif
[245]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;
[265]113 #ifdef DEBUG_NDATABLOCK
114 if(!data) NallocData++; NallocSRef++;
[267]115 cout<<"...DEBUG_NDataBlock::Alloc mSz="<<mSz<<" mSRef="<<mSRef
[265]116 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
[267]117 <<" mSRef->bridge="<<mSRef->bridge<<" IsTemp="<<mIsTemp
[265]118 <<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
119 #endif
[245]120}
121
122template <class T>
123void NDataBlock<T>::Clone(NDataBlock<T>& a)
124// Clone (copie de donnee) a partir de "a"
125{
[265]126 #ifdef DEBUG_NDATABLOCK
[267]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;
[265]130 #endif
[245]131if(!a.mSRef) {mSz=0; mSRef=NULL;} // cas ou "a" est cree par defaut
132else if(a.IsTemp()) Share(a);
[249]133else {Alloc(a.mSz); memcpy(Data(),a.Data(),mSz*sizeof(T));}
[245]134}
135
136template <class T>
137void NDataBlock<T>::Share(NDataBlock<T>& a)
138// Partage des donnees avec "a"
139{
[265]140 #ifdef DEBUG_NDATABLOCK
[267]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;
[265]145 #endif
[245]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++;
[265]151 #ifdef DEBUG_NDATABLOCK
[267]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;
[265]155 #endif
[245]156}
157
158template <class T>
159void NDataBlock<T>::Delete(void)
160// Pour detruire les pointeurs en tenant compte des references
161{
[265]162 #ifdef DEBUG_NDATABLOCK
[267]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;
[265]168 cout<<endl;
169 #endif
[245]170if(mSRef==NULL) return; // cas du createur par defaut
171mSRef->nref--;
172if(mSRef->nref != 0) {
[265]173 #ifdef DEBUG_NDATABLOCK
174 cout<<"...DEBUG_NDataBlock::Delete() pas de desallocation il reste nref="
175 <<mSRef->nref<<endl;
176 #endif
[245]177 return;
178}
[265]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
[245]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>
[259]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>
[245]203void NDataBlock<T>::ReSize(size_t n)
204// Re-dimension, dans ce cas re-allocation de la place
205{
206Alloc(n);
207}
208
[257]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
[245]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;
[267]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;
[249]234if(i1>=mSz || n<=0 || !p) return;
[245]235size_t i2 = i1+n; if(i2>mSz) i2=mSz;
[257]236size_t im = 1; bool enl;
[245]237while(i1<i2) {
[257]238 enl = false;
[245]239 cout<<" "<<(*this)(i1); i1++;
[257]240 if(im==10) {cout<<"\n"; im=1; enl=true;} else im++;
[245]241}
[257]242if(!enl) cout<<endl;
[245]243}
244
245//**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b;
246
247template <class T>
[249]248NDataBlock<T>& NDataBlock<T>::operator = (NDataBlock<T>& a)
[245]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;
[265]254if(a.mSz!=mSz)
255 throw(SzMismatchError("NDataBlock::operator=A size mismatch/null\n"));
[245]256Share(a);
257return *this;
258}
259
260template <class T>
[249]261NDataBlock<T>& NDataBlock<T>::operator = (T v)
[245]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"));
[249]267T *p=Begin(), *pe=End();
[245]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"));
[249]278T *p=Begin(), *pe=End();
[245]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"));
[249]287T *p=Begin(), *pe=End();
[245]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"));
[249]296T *p=Begin(), *pe=End();
[245]297while (p<pe) *p++ *= b;
298return *this;
299}
300
301template <class T>
302NDataBlock<T>& NDataBlock<T>::operator /= (T b)
303{
[249]304if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
[245]305if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
[249]306T *p=Begin(), *pe=End();
[245]307while (p<pe) *p++ /= b;
308return *this;
309}
310
311//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock;
312
313template <class T>
[249]314NDataBlock<T>& NDataBlock<T>::operator += (NDataBlock<T>& a)
[245]315{
[265]316if(mSz==0 || mSz!=a.mSz)
317 throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
[249]318T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]319while (p<pe) *p++ += *pa++; // ca marche meme si *this=a
320return *this;
321}
322
323template <class T>
[249]324NDataBlock<T>& NDataBlock<T>::operator -= (NDataBlock<T>& a)
[245]325{
[265]326if(mSz==0 || mSz!=a.mSz)
327 throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
[249]328T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]329while (p<pe) *p++ -= *pa++; // ca marche meme si *this=a
330return *this;
331}
332
333template <class T>
[249]334NDataBlock<T>& NDataBlock<T>::operator *= (NDataBlock<T>& a)
[245]335{
[265]336if(mSz==0 || mSz!=a.mSz)
337 throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
[249]338T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]339while (p<pe) *p++ *= *pa++; // ca marche meme si *this=a
340return *this;
341}
342
343template <class T>
[249]344NDataBlock<T>& NDataBlock<T>::operator /= (NDataBlock<T>& a)
[245]345{
[265]346if(mSz==0 || mSz!=a.mSz)
347 throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
[249]348T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]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>
[261]357NDataBlock<T> NDataBlock<T>::Add(T b)
[257]358// Pour A+b
[245]359{
[257]360NDataBlock<T>& a = *this;
[245]361NDataBlock<T> result(a,false); result.SetTemp(true);
[259]362return result += b;
[245]363}
364
365template <class T>
[261]366NDataBlock<T> NDataBlock<T>::Sub(T b)
[257]367// Pour A-b
[245]368{
[257]369NDataBlock<T>& a = *this;
[245]370NDataBlock<T> result(a,false); result.SetTemp(true);
[259]371return result -= b;
[245]372}
373
374template <class T>
[261]375NDataBlock<T> NDataBlock<T>::SubInv(T b)
[257]376// Pour b-A
[245]377{
[257]378NDataBlock<T>& a = *this;
[245]379NDataBlock<T> result(a,false); result.SetTemp(true);
[249]380T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]381while(p<pe) {*p++ = b - *pa++;}
382return result;
383}
384
385template <class T>
[261]386NDataBlock<T> NDataBlock<T>::Mul(T b)
[257]387// Pour A*b
[245]388{
[257]389NDataBlock<T>& a = *this;
[245]390NDataBlock<T> result(a,false); result.SetTemp(true);
[259]391return result *= b;
[245]392}
393
394template <class T>
[261]395NDataBlock<T> NDataBlock<T>::Div(T b)
[257]396// Pour A/b
[245]397{
[257]398NDataBlock<T>& a = *this;
[245]399NDataBlock<T> result(a,false); result.SetTemp(true);
[259]400return result /= b;
[245]401}
402
403template <class T>
[261]404NDataBlock<T> NDataBlock<T>::DivInv(T b)
[257]405// Pour b/A
[245]406{
[257]407NDataBlock<T>& a = *this;
[245]408NDataBlock<T> result(a,false); result.SetTemp(true);
[249]409T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]410while(p<pe) {*p++ = b / *pa++;}
411return result;
412}
413
414//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock;
415
416template <class T>
[261]417NDataBlock<T> NDataBlock<T>::Add(NDataBlock<T>& b)
[257]418// Pour A+B
[245]419{
[257]420NDataBlock<T>& a = *this;
[265]421if(a.mSz!=b.mSz)
422 throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n"));
[245]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>
[261]433NDataBlock<T> NDataBlock<T>::Mul(NDataBlock<T>& b)
[257]434// Pour A*B
[245]435{
[257]436NDataBlock<T>& a = *this;
[265]437if(a.mSz!=b.mSz)
438 throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n"));
[245]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>
[261]449NDataBlock<T> NDataBlock<T>::Sub(NDataBlock<T>& b)
[257]450// Pour A-B
[245]451{
[257]452NDataBlock<T>& a = *this;
[265]453if(a.mSz!=b.mSz)
454 throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n"));
[245]455if(b.IsTemp()) {
456 NDataBlock<T> result(b,true); result.SetTemp(true);
[249]457 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]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>
[261]467NDataBlock<T> NDataBlock<T>::Div(NDataBlock<T>& b)
[257]468// Pour A/B
[245]469{
[257]470NDataBlock<T>& a = *this;
[265]471if(a.mSz!=b.mSz)
472 throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n"));
[245]473if(b.IsTemp()) {
474 NDataBlock<T> result(b,true); result.SetTemp(true);
[249]475 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]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>
[257]496// pas de definitions de cout pour les complex ??
497//#pragma define_template NDataBlock< complex<float> >
498//#pragma define_template NDataBlock< complex<double> >
[245]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>;
[249]512template class NDataBlock< complex<float> >;
513template class NDataBlock< complex<double> >;
[245]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>;
[249]527template class NDataBlock< complex<float> >;
528template class NDataBlock< complex<double> >;
[245]529#endif
Note: See TracBrowser for help on using the repository browser.