#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::SetTemp(bool temp) // Set temporary { mIsTemp=temp; #ifdef DEBUG_NDATABLOCK cout<<"DEBUG_NDataBlock::SetTemp("<nref = 1; if(data) mSRef->data = data; else mSRef->data = new T[n]; mSRef->bridge = br; #ifdef DEBUG_NDATABLOCK if(!data) NallocData++; NallocSRef++; cout<<"...DEBUG_NDataBlock::Alloc mSz="<nref="<nref<<" mSRef->data="<< mSRef->data <<" mSRef->bridge="<bridge<<" IsTemp="< void NDataBlock::Clone(NDataBlock& a) // Clone (copie de donnee) a partir de "a" { #ifdef DEBUG_NDATABLOCK cout<<"DEBUG_NDataBlock::Clone("< void NDataBlock::Share(NDataBlock& a) // Partage des donnees avec "a" { #ifdef DEBUG_NDATABLOCK cout<<"DEBUG_NDataBlock::Share("<nref++; #ifdef DEBUG_NDATABLOCK cout<<"...DEBUG_NDataBlock::Share mSz="<nref="<nref<<" mSRef->data="<< mSRef->data <<" mSRef->bridge="<bridge<<" IsTemp="< void NDataBlock::Delete(void) // Pour detruire les pointeurs en tenant compte des references { #ifdef DEBUG_NDATABLOCK cout<<"DEBUG_NDataBlock::Delete("<nref="<nref<<" mSRef->data=" <data<<" mSRef->bridge="<bridge; cout<nref--; if(mSRef->nref != 0) { #ifdef DEBUG_NDATABLOCK cout<<"...DEBUG_NDataBlock::Delete() pas de desallocation il reste nref=" <nref<bridge) NallocData--; NallocSRef--; cout<<"...DEBUG_NDataBlock::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::Reset(T v) { if(mSRef==NULL) return; if(mSRef->data==NULL) return; if(mSz==0) return; T *p=Begin(), *pe=End(); while(p void NDataBlock::ReSize(size_t n) // Re-dimension, dans ce cas re-allocation de la place { Alloc(n); } template void NDataBlock::FillFrom(size_t n,T* data) // Remplissage par un tableau de donnees // - Si classe vide : creation de l'espace memoire // - Si classe connectee : on ecrit selon la longueur { if(data==NULL) throw(NullPtrError("NDataBlock::FillFrom data==NULL\n")); if(n==0) throw(ParmError("NDataBlock::FillFrom n<=0\n")); if(mSRef==NULL) Alloc(n); // cas du createur par default if(mSz void NDataBlock::Print(size_t i1,size_t n) // Impression de n elements a partir de i1 { size_t nr = 0; T* p = NULL; Bridge* br = NULL; if(mSRef) {nr = mSRef->nref; p = mSRef->data; br = mSRef->bridge;} cout<<"NDataBlock::Print("<=mSz || n<=0 || !p) return; size_t i2 = i1+n; if(i2>mSz) i2=mSz; size_t im = 1; bool enl; 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 NDataBlock::Add(T b) // Pour A+b { NDataBlock& a = *this; NDataBlock result(a,false); result.SetTemp(true); return result += b; } template NDataBlock NDataBlock::Sub(T b) // Pour A-b { NDataBlock& a = *this; NDataBlock result(a,false); result.SetTemp(true); return result -= b; } template NDataBlock NDataBlock::SubInv(T b) // Pour b-A { NDataBlock& a = *this; NDataBlock result(a,false); result.SetTemp(true); T *p=result.Begin(), *pe=result.End(), *pa=a.Begin(); while(p NDataBlock NDataBlock::Mul(T b) // Pour A*b { NDataBlock& a = *this; NDataBlock result(a,false); result.SetTemp(true); return result *= b; } template NDataBlock NDataBlock::Div(T b) // Pour A/b { NDataBlock& a = *this; NDataBlock result(a,false); result.SetTemp(true); return result /= b; } template NDataBlock NDataBlock::DivInv(T b) // Pour b/A { NDataBlock& a = *this; NDataBlock result(a,false); result.SetTemp(true); T *p=result.Begin(), *pe=result.End(), *pa=a.Begin(); while(p NDataBlock NDataBlock::Add(NDataBlock& b) // Pour A+B { NDataBlock& a = *this; 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 NDataBlock::Mul(NDataBlock& b) // Pour A*B { NDataBlock& a = *this; 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 NDataBlock::Sub(NDataBlock& b) // Pour A-B { NDataBlock& a = *this; 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 NDataBlock::Div(NDataBlock& b) // Pour A/B { NDataBlock& a = *this; 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 // pas de definitions de cout pour les complex ?? //#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