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
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>
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)
[257]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);
[245]89{
[265]90 #ifdef DEBUG_NDATABLOCK
91 cout<<"DEBUG_NDataBlock::Alloc("
92 <<n<<","<<data<<","<<br<<") mSRef="<<mSRef<<endl;
93 #endif
[245]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;
[265]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
[245]107}
108
109template <class T>
110void NDataBlock<T>::Clone(NDataBlock<T>& a)
111// Clone (copie de donnee) a partir de "a"
112{
[265]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
[245]117if(!a.mSRef) {mSz=0; mSRef=NULL;} // cas ou "a" est cree par defaut
118else if(a.IsTemp()) Share(a);
[249]119else {Alloc(a.mSz); memcpy(Data(),a.Data(),mSz*sizeof(T));}
[245]120}
121
122template <class T>
123void NDataBlock<T>::Share(NDataBlock<T>& a)
124// Partage des donnees avec "a"
125{
[265]126 #ifdef DEBUG_NDATABLOCK
127 cout<<"DEBUG_NDataBlock::Share("<<&a<<") a.mSRef="<<a.mSRef<<" mSRef="<<mSRef<<endl;
128 #endif
[245]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++;
[265]134 #ifdef DEBUG_NDATABLOCK
135 cout<<"...DEBUG_NDataBlock::Share("<<&a<<") mSRef="<<mSRef
136 <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data<<endl;
137 #endif
[245]138}
139
140template <class T>
141void NDataBlock<T>::Delete(void)
142// Pour detruire les pointeurs en tenant compte des references
143{
[265]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
[245]149if(mSRef==NULL) return; // cas du createur par defaut
150mSRef->nref--;
151if(mSRef->nref != 0) {
[265]152 #ifdef DEBUG_NDATABLOCK
153 cout<<"...DEBUG_NDataBlock::Delete() pas de desallocation il reste nref="
154 <<mSRef->nref<<endl;
155 #endif
[245]156 return;
157}
[265]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
[245]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>
[259]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>
[245]182void NDataBlock<T>::ReSize(size_t n)
183// Re-dimension, dans ce cas re-allocation de la place
184{
185Alloc(n);
186}
187
[257]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
[245]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;}
[259]210cout<<"NDataBlock::Print nel="<<mSz<<" nref="<<nr<<" ("<<p<<")"<<endl;
[249]211if(i1>=mSz || n<=0 || !p) return;
[245]212size_t i2 = i1+n; if(i2>mSz) i2=mSz;
[257]213size_t im = 1; bool enl;
[245]214while(i1<i2) {
[257]215 enl = false;
[245]216 cout<<" "<<(*this)(i1); i1++;
[257]217 if(im==10) {cout<<"\n"; im=1; enl=true;} else im++;
[245]218}
[257]219if(!enl) cout<<endl;
[245]220}
221
222//**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b;
223
224template <class T>
[249]225NDataBlock<T>& NDataBlock<T>::operator = (NDataBlock<T>& a)
[245]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;
[265]231if(a.mSz!=mSz)
232 throw(SzMismatchError("NDataBlock::operator=A size mismatch/null\n"));
[245]233Share(a);
234return *this;
235}
236
237template <class T>
[249]238NDataBlock<T>& NDataBlock<T>::operator = (T v)
[245]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"));
[249]244T *p=Begin(), *pe=End();
[245]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"));
[249]255T *p=Begin(), *pe=End();
[245]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"));
[249]264T *p=Begin(), *pe=End();
[245]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"));
[249]273T *p=Begin(), *pe=End();
[245]274while (p<pe) *p++ *= b;
275return *this;
276}
277
278template <class T>
279NDataBlock<T>& NDataBlock<T>::operator /= (T b)
280{
[249]281if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
[245]282if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
[249]283T *p=Begin(), *pe=End();
[245]284while (p<pe) *p++ /= b;
285return *this;
286}
287
288//**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock;
289
290template <class T>
[249]291NDataBlock<T>& NDataBlock<T>::operator += (NDataBlock<T>& a)
[245]292{
[265]293if(mSz==0 || mSz!=a.mSz)
294 throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
[249]295T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]296while (p<pe) *p++ += *pa++; // ca marche meme si *this=a
297return *this;
298}
299
300template <class T>
[249]301NDataBlock<T>& NDataBlock<T>::operator -= (NDataBlock<T>& a)
[245]302{
[265]303if(mSz==0 || mSz!=a.mSz)
304 throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
[249]305T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]306while (p<pe) *p++ -= *pa++; // ca marche meme si *this=a
307return *this;
308}
309
310template <class T>
[249]311NDataBlock<T>& NDataBlock<T>::operator *= (NDataBlock<T>& a)
[245]312{
[265]313if(mSz==0 || mSz!=a.mSz)
314 throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
[249]315T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]316while (p<pe) *p++ *= *pa++; // ca marche meme si *this=a
317return *this;
318}
319
320template <class T>
[249]321NDataBlock<T>& NDataBlock<T>::operator /= (NDataBlock<T>& a)
[245]322{
[265]323if(mSz==0 || mSz!=a.mSz)
324 throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
[249]325T *p=Begin(), *pe=End(), *pa=a.Begin();
[245]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>
[261]334NDataBlock<T> NDataBlock<T>::Add(T b)
[257]335// Pour A+b
[245]336{
[257]337NDataBlock<T>& a = *this;
[245]338NDataBlock<T> result(a,false); result.SetTemp(true);
[259]339return result += b;
[245]340}
341
342template <class T>
[261]343NDataBlock<T> NDataBlock<T>::Sub(T b)
[257]344// Pour A-b
[245]345{
[257]346NDataBlock<T>& a = *this;
[245]347NDataBlock<T> result(a,false); result.SetTemp(true);
[259]348return result -= b;
[245]349}
350
351template <class T>
[261]352NDataBlock<T> NDataBlock<T>::SubInv(T b)
[257]353// Pour b-A
[245]354{
[257]355NDataBlock<T>& a = *this;
[245]356NDataBlock<T> result(a,false); result.SetTemp(true);
[249]357T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]358while(p<pe) {*p++ = b - *pa++;}
359return result;
360}
361
362template <class T>
[261]363NDataBlock<T> NDataBlock<T>::Mul(T b)
[257]364// Pour A*b
[245]365{
[257]366NDataBlock<T>& a = *this;
[245]367NDataBlock<T> result(a,false); result.SetTemp(true);
[259]368return result *= b;
[245]369}
370
371template <class T>
[261]372NDataBlock<T> NDataBlock<T>::Div(T b)
[257]373// Pour A/b
[245]374{
[257]375NDataBlock<T>& a = *this;
[245]376NDataBlock<T> result(a,false); result.SetTemp(true);
[259]377return result /= b;
[245]378}
379
380template <class T>
[261]381NDataBlock<T> NDataBlock<T>::DivInv(T b)
[257]382// Pour b/A
[245]383{
[257]384NDataBlock<T>& a = *this;
[245]385NDataBlock<T> result(a,false); result.SetTemp(true);
[249]386T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]387while(p<pe) {*p++ = b / *pa++;}
388return result;
389}
390
391//**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock;
392
393template <class T>
[261]394NDataBlock<T> NDataBlock<T>::Add(NDataBlock<T>& b)
[257]395// Pour A+B
[245]396{
[257]397NDataBlock<T>& a = *this;
[265]398if(a.mSz!=b.mSz)
399 throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n"));
[245]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>
[261]410NDataBlock<T> NDataBlock<T>::Mul(NDataBlock<T>& b)
[257]411// Pour A*B
[245]412{
[257]413NDataBlock<T>& a = *this;
[265]414if(a.mSz!=b.mSz)
415 throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n"));
[245]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>
[261]426NDataBlock<T> NDataBlock<T>::Sub(NDataBlock<T>& b)
[257]427// Pour A-B
[245]428{
[257]429NDataBlock<T>& a = *this;
[265]430if(a.mSz!=b.mSz)
431 throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n"));
[245]432if(b.IsTemp()) {
433 NDataBlock<T> result(b,true); result.SetTemp(true);
[249]434 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]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>
[261]444NDataBlock<T> NDataBlock<T>::Div(NDataBlock<T>& b)
[257]445// Pour A/B
[245]446{
[257]447NDataBlock<T>& a = *this;
[265]448if(a.mSz!=b.mSz)
449 throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n"));
[245]450if(b.IsTemp()) {
451 NDataBlock<T> result(b,true); result.SetTemp(true);
[249]452 T *p=result.Begin(), *pe=result.End(), *pa=a.Begin();
[245]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>
[257]473// pas de definitions de cout pour les complex ??
474//#pragma define_template NDataBlock< complex<float> >
475//#pragma define_template NDataBlock< complex<double> >
[245]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>;
[249]489template class NDataBlock< complex<float> >;
490template class NDataBlock< complex<double> >;
[245]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>;
[249]504template class NDataBlock< complex<float> >;
505template class NDataBlock< complex<double> >;
[245]506#endif
Note: See TracBrowser for help on using the repository browser.