#include "machdefs.h" #include #include #include #include #include "pexceptions.h" #include "ndatablock.h" #define DEBUG_NDATABLOCK #ifdef DEBUG_NDATABLOCK static size_t NallocData = 0; static size_t NallocSRef = 0; #endif // LOGIQUE DE BASE: // - le createur par copie et la surcharge de l operateur = "partage" les donnees // - gestion du partage de reference //************ Createur, Destructeur, gestion des donnees template NDataBlock::NDataBlock(size_t n) // Createur d'une structure de "n" donnees : mSz(0), mSRef(NULL), mIsTemp(false) { Alloc(n); } template NDataBlock::NDataBlock(size_t n, T* data, Bridge* br) // Createur d'une structure de "n" donnees, avec donnees preallouees : mSz(0), mSRef(NULL), mIsTemp(false) { Alloc(n,data,br); } template NDataBlock::NDataBlock() // Createur par default : mSz(0), mSRef(NULL), mIsTemp(false) { } template NDataBlock::NDataBlock(NDataBlock& a) // Createur par copie // ATTENTION: partage les donnees avec "a" // Ecriture: NDataBlock a = b; // NDataBlock a(b) : mSz(0), mSRef(NULL), mIsTemp(false) { Share(a); } template NDataBlock::NDataBlock(NDataBlock& a,bool share) // Createur avec choix de partager ou non : mSz(0), mSRef(NULL), mIsTemp(false) { if(share) Share(a); else Clone(a); } template NDataBlock::~NDataBlock() // Destructeur { Delete(); } template void NDataBlock::Alloc(size_t n,T* data,Bridge* br) // Allocation d'un NOUVEL espace de stoquage // Si data==NULL : allocation de l'espace memoire // data!=NULL : partage des donnees avec l'adresse data // Si br==NULL : les donnees nous appartiennent // br!=NULL : les donnees ne nous appartiennent pas (ex Blitz) { #ifdef DEBUG_NDATABLOCK cout<<"NDataBlock::Alloc("<nref = 1; if(data) mSRef->data = data; else mSRef->data = new T[n]; mSRef->bridge = br; #ifdef DEBUG_NDATABLOCK if(!data) NallocData++; NallocSRef++; cout<<"NDataBlock::Alloc("<nref"<nref<<" mSRef->data"<< mSRef->data <<" Total("< void NDataBlock::Clone(NDataBlock& a) // Clone (copie de donnee) a partir de "a" { #ifdef DEBUG_NDATABLOCK cout<<"NDataBlock::Clone("<<&a< void NDataBlock::Share(NDataBlock& a) // Partage des donnees avec "a" { #ifdef DEBUG_NDATABLOCK cout<<"NDataBlock::Share("<<&a<<") a.mSRef="<nref++; #ifdef DEBUG_NDATABLOCK cout<<"...NDataBlock::Share("<<&a<<") mSRef="<nref"<nref<<" mSRef->data"<< mSRef->data< void NDataBlock::Delete(void) // Pour detruire les pointeurs en tenant compte des references { #ifdef DEBUG_NDATABLOCK cout<<"NDataBlock::Delete() mSRef="<nref"<nref<<" mSRef->data"<data; cout<nref--; if(mSRef->nref != 0) { #ifdef DEBUG_NDATABLOCK cout<<"...NDataBlock::Delete() pas de desallocation il reste nref="<nref<bridge) NallocData--; NallocSRef--; cout<<"...NNDataBlock::Delete() desallocation complete il reste nref="<nref <<" Total("<bridge) delete mSRef->bridge; // sinon, les donnees ont ete allouees par nos soins, on libere l'espace memoire else delete [] mSRef->data; mSRef->bridge=NULL; mSRef->data=NULL; delete mSRef; mSRef=NULL; } template void NDataBlock::ReSize(size_t n) // Re-dimension, dans ce cas re-allocation de la place { Alloc(n); } //**** Impression template void NDataBlock::Print(size_t i1,size_t n) // Impression de n elements a partir de i1 { size_t nr = 0; T* p = NULL; if(mSRef) {nr = mSRef->nref; p = mSRef->data;} cout<<"NDataBlock::Print nel=%ld nref=%d (%p)\n",mSz,nr,p; if(i1>=mSz || n<=0 || !p) return; size_t i2 = i1+n; if(i2>mSz) i2=mSz; size_t im = 1; while(i1 b; template NDataBlock& NDataBlock::operator = (NDataBlock& a) // surcharge avec partage des donnees // Ecriture: NDataBlock a; a = b; // NDataBlock a(10); a = b; (a est re-affecte) { if(this == &a) return *this; if(a.mSz!=mSz) throw(SzMismatchError("NDataBlock::operator=A size mismatch/null\n")); Share(a); return *this; } template NDataBlock& NDataBlock::operator = (T v) // surcharge avec copie des donnees (pas de partage) // "this" est sur-ecrit, attention au partage de reference! // NDataBlock a; a = v; ou bien NDataBlock a(10); a = v; { if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n")); T *p=Begin(), *pe=End(); while (p b; template NDataBlock& NDataBlock::operator += (T b) { if(mSz==0) throw(SzMismatchError("NDataBlock::operator+=v null size\n")); T *p=Begin(), *pe=End(); while (p NDataBlock& NDataBlock::operator -= (T b) { if(mSz==0) throw(SzMismatchError("NDataBlock::operator-=v null size\n")); T *p=Begin(), *pe=End(); while (p NDataBlock& NDataBlock::operator *= (T b) { if(mSz==0) throw(SzMismatchError("NDataBlock::operator*=v null size\n")); T *p=Begin(), *pe=End(); while (p NDataBlock& NDataBlock::operator /= (T b) { if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n")); if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n")); T *p=Begin(), *pe=End(); while (p NDataBlock& NDataBlock::operator += (NDataBlock& a) { if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null")); T *p=Begin(), *pe=End(), *pa=a.Begin(); while (p NDataBlock& NDataBlock::operator -= (NDataBlock& a) { if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null")); T *p=Begin(), *pe=End(), *pa=a.Begin(); while (p NDataBlock& NDataBlock::operator *= (NDataBlock& a) { if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null")); T *p=Begin(), *pe=End(), *pa=a.Begin(); while (p NDataBlock& NDataBlock::operator /= (NDataBlock& a) { if(mSz==0 || mSz!=a.mSz) throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null")); T *p=Begin(), *pe=End(), *pa=a.Begin(); while (pb; NDataBlock = b+NDataBlock; // ATTENTION: re-affectation imposee template NDataBlock operator + (const NDataBlock& a, T b) { NDataBlock result(a,false); result.SetTemp(true); return (result += b); } template NDataBlock operator + (T b, const NDataBlock& a) { NDataBlock result(a,false); result.SetTemp(true); return (result += b); } template NDataBlock operator - (const NDataBlock& a, T b) { NDataBlock result(a,false); result.SetTemp(true); return (result -= b); } template NDataBlock operator - (T b, const NDataBlock& a) { NDataBlock result(a,false); result.SetTemp(true); T *p=result.Begin(), *pe=result.End(), *pa=a.Begin(); while(p NDataBlock operator * (const NDataBlock& a, T b) { NDataBlock result(a,false); result.SetTemp(true); return (result *= b); } template NDataBlock operator * (T b, const NDataBlock& a) { NDataBlock result(a,false); result.SetTemp(true); return (result *= b); } template NDataBlock operator / (const NDataBlock& a, T b) { NDataBlock result(a,false); result.SetTemp(true); return (result /= b); } template NDataBlock operator / (T b, const NDataBlock& a) { NDataBlock result(a,false); result.SetTemp(true); T *p=result.Begin(), *pe=result.End(), *pa=a.Begin(); while(p NDataBlock operator + (const NDataBlock& a, const NDataBlock& b) { if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n")); if(b.IsTemp()) { NDataBlock result(b,true); result.SetTemp(true); return result += a; } else { NDataBlock result(a,false); result.SetTemp(true); return result += b; } } template NDataBlock operator * (const NDataBlock& a, const NDataBlock& b) { if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n")); if(b.IsTemp()) { NDataBlock result(b,true); result.SetTemp(true); return result *= a; } else { NDataBlock result(a,false); result.SetTemp(true); return result *= b; } } template NDataBlock operator - (const NDataBlock& a, const NDataBlock& b) { if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n")); if(b.IsTemp()) { NDataBlock result(b,true); result.SetTemp(true); T *p=result.Begin(), *pe=result.End(), *pa=a.Begin(); while(p result(a,false); result.SetTemp(true); return result -= b; } } template NDataBlock operator / (const NDataBlock& a, const NDataBlock& b) { if(a.mSz!=b.mSz) throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n")); if(b.IsTemp()) { NDataBlock result(b,true); result.SetTemp(true); T *p=result.Begin(), *pe=result.End(), *pa=a.Begin(); while(p result(a,false); result.SetTemp(true); return result /= b; } } #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock #pragma define_template NDataBlock< complex > #pragma define_template NDataBlock< complex > #endif #ifdef __GNU_TEMPLATES__ template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock< complex >; template class NDataBlock< complex >; #endif #if defined(__ANSI_TEMPLATES__) template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock; template class NDataBlock< complex >; template class NDataBlock< complex >; #endif #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template (operator+) mais comment on fait ca! CMV_A_FAIRE #endif #ifdef __GNU_TEMPLATES__ template NDataBlock operator + (const NDataBlock&, const NDataBlock&); mais comment on fait ca! CMV_A_FAIRE #endif #if defined(__ANSI_TEMPLATES__) #endif