| [658] | 1 | // Gestion de block de donnees avec partage de references | 
|---|
|  | 2 | // malheureusement tres mal concu...  C.Magneville 04/99 | 
|---|
|  | 3 | // LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA | 
|---|
|  | 4 | #include "machdefs.h" | 
|---|
|  | 5 | #include <stdio.h> | 
|---|
|  | 6 | #include <stdlib.h> | 
|---|
|  | 7 | #include <iostream.h> | 
|---|
|  | 8 | #include <complex> | 
|---|
|  | 9 | #include "pexceptions.h" | 
|---|
|  | 10 | #include "ndatablock.h" | 
|---|
|  | 11 | #include "objfio.h" | 
|---|
|  | 12 |  | 
|---|
|  | 13 | // define DEBUG_NDATABLOCK | 
|---|
|  | 14 |  | 
|---|
|  | 15 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 16 | static size_t NallocData = 0; | 
|---|
|  | 17 | static size_t NallocSRef = 0; | 
|---|
|  | 18 | #endif | 
|---|
|  | 19 |  | 
|---|
|  | 20 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 21 | //************ Createur, Destructeur | 
|---|
|  | 22 |  | 
|---|
|  | 23 | template <class T> | 
|---|
|  | 24 | NDataBlock<T>::NDataBlock(size_t n) | 
|---|
|  | 25 | // Createur d'une structure de "n" donnees | 
|---|
|  | 26 | : mSz(0), mSRef(NULL), mIsTemp(false) | 
|---|
|  | 27 | { | 
|---|
|  | 28 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 29 | cout<<"?_NDataBlock::NDataBlock("<<this<<",n="<<n<<")"<<endl; | 
|---|
|  | 30 | #endif | 
|---|
|  | 31 |  | 
|---|
|  | 32 | Alloc(n); | 
|---|
|  | 33 | } | 
|---|
|  | 34 |  | 
|---|
|  | 35 | template <class T> | 
|---|
|  | 36 | NDataBlock<T>::NDataBlock(size_t n, T* data, Bridge* br) | 
|---|
|  | 37 | // Createur d'une structure de "n" donnees, avec donnees preallouees. | 
|---|
|  | 38 | // Attention createur TRES DANGEREUX (Voir explications dans Alloc()). | 
|---|
|  | 39 | : mSz(0), mSRef(NULL), mIsTemp(false) | 
|---|
|  | 40 | { | 
|---|
|  | 41 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 42 | cout<<"?_NDataBlock::NDataBlock("<<this | 
|---|
|  | 43 | <<",data="<<data<<",br="<<br<<")"<<endl; | 
|---|
|  | 44 | #endif | 
|---|
|  | 45 |  | 
|---|
|  | 46 | Alloc(n,data,br); | 
|---|
|  | 47 | } | 
|---|
|  | 48 |  | 
|---|
|  | 49 | template <class T> | 
|---|
|  | 50 | NDataBlock<T>::NDataBlock() | 
|---|
|  | 51 | // Createur par default | 
|---|
|  | 52 | : mSz(0), mSRef(NULL), mIsTemp(false) | 
|---|
|  | 53 | { | 
|---|
|  | 54 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 55 | cout<<"?_NDataBlock::NDataBlock("<<this<<") default"<<endl; | 
|---|
|  | 56 | #endif | 
|---|
|  | 57 | } | 
|---|
|  | 58 |  | 
|---|
|  | 59 | template <class T> | 
|---|
|  | 60 | NDataBlock<T>::NDataBlock(const NDataBlock<T>& a) | 
|---|
|  | 61 | // Createur par copie: partage les donnees si "a" temporaire, clone sinon. | 
|---|
|  | 62 | : mSz(0), mSRef(NULL), mIsTemp(false) | 
|---|
|  | 63 | { | 
|---|
|  | 64 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 65 | cout<<"?_NDataBlock::NDataBlock("<<this<<",&a="<<&a<<")"<<endl; | 
|---|
|  | 66 | #endif | 
|---|
|  | 67 |  | 
|---|
|  | 68 | CloneOrShare(a); | 
|---|
|  | 69 | } | 
|---|
|  | 70 |  | 
|---|
|  | 71 | template <class T> | 
|---|
|  | 72 | NDataBlock<T>::NDataBlock(const NDataBlock<T>& a,bool share) | 
|---|
|  | 73 | // Createur avec choix de partager ou non selon "share" | 
|---|
|  | 74 | : mSz(0), mSRef(NULL), mIsTemp(false) | 
|---|
|  | 75 | { | 
|---|
|  | 76 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 77 | cout<<"?_NDataBlock::NDataBlock("<<this<<",&a="<<&a<<",sh=<<"<<share<<")"<<endl; | 
|---|
|  | 78 | #endif | 
|---|
|  | 79 |  | 
|---|
|  | 80 | if(share) Share(a); else Clone(a); | 
|---|
|  | 81 | } | 
|---|
|  | 82 |  | 
|---|
|  | 83 | template <class T> | 
|---|
|  | 84 | NDataBlock<T>::~NDataBlock() | 
|---|
|  | 85 | // Destructeur | 
|---|
|  | 86 | { | 
|---|
|  | 87 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 88 | cout<<"?_NDataBlock::~NDataBlock("<<this<<")"<<endl; | 
|---|
|  | 89 | #endif | 
|---|
|  | 90 |  | 
|---|
|  | 91 | Delete(); | 
|---|
|  | 92 | } | 
|---|
|  | 93 |  | 
|---|
|  | 94 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 95 | //************ Gestion de donnees | 
|---|
|  | 96 |  | 
|---|
|  | 97 | template <class T> | 
|---|
|  | 98 | void NDataBlock<T>::Alloc(size_t n,T* data,Bridge* br) | 
|---|
|  | 99 | // Allocation d'un NOUVEL espace de stoquage de "n" donnees | 
|---|
|  | 100 | // Si data==NULL : allocation de l'espace memoire (remplit de zeros) | 
|---|
|  | 101 | //    data!=NULL : partage des donnees avec l'adresse data | 
|---|
|  | 102 | // Si br==NULL   : les donnees nous appartiennent | 
|---|
|  | 103 | //    br!=NULL   : les donnees ne nous appartiennent pas (ex: Blitz) | 
|---|
|  | 104 | // | 
|---|
|  | 105 | // Exemple: on veut connecter a un tableau de T* | 
|---|
|  | 106 | // > float *x = new float[5]; ... remplissage de x[] ...; | 
|---|
|  | 107 | // 1- On veut que NDataBlock NE DESALLOUE PAS le tableau "x[]" | 
|---|
|  | 108 | //    a- Premiere solution | 
|---|
|  | 109 | //       > NDataBlock A(5,x,new Bridge); | 
|---|
|  | 110 | //       ...... | 
|---|
|  | 111 | //       > delete [] x; | 
|---|
|  | 112 | //          - Il faut deleter x[] explicitement. | 
|---|
|  | 113 | //          - Le destructeur de "A" ne detruit pas x[]. | 
|---|
|  | 114 | //          ATTENTION: Une fois x[] detruit, "A" ne peut | 
|---|
|  | 115 | //                     plus acceder les donnees! | 
|---|
|  | 116 | //          - Bridge est detruit par le destructeur de "A" | 
|---|
|  | 117 | //    b- Autre solution: | 
|---|
|  | 118 | //       > NDataBlock A(5); A.FillFrom(5,x); | 
|---|
|  | 119 | //       > delete [] x; | 
|---|
|  | 120 | //       ...... | 
|---|
|  | 121 | //          - Il faut deleter x[] explicitement. | 
|---|
|  | 122 | //          - "A" possede une copie en local de x[]. | 
|---|
|  | 123 | //          - Le destructeur de "A" ne detruit pas x[] mais la copie locale. | 
|---|
|  | 124 | // 2- On veut que NDataBlock desalloue le tableau | 
|---|
|  | 125 | //       > NDataBlock A(5,x); | 
|---|
|  | 126 | //          - Ne Pas Faire "delete [] x;" | 
|---|
|  | 127 | //          - "A" partage les donnees avec x[]. | 
|---|
|  | 128 | //          - Le destructeur de "A" detruit x[]. | 
|---|
|  | 129 | // | 
|---|
|  | 130 | // --- REMARQUE SUR LE DANGER DE CERTAINES SITUATIONS (CMV): | 
|---|
|  | 131 | // 1-/ x = new float[n1]; NDataBlock A(n2,x); | 
|---|
|  | 132 | //     1er danger: si n2>n1 depassement de tableaux (core dump) | 
|---|
|  | 133 | //     2sd danger: celui qui alloue x[] ne doit pas faire le "delete" | 
|---|
|  | 134 | //                 en desaccord avec toutes les regles de bonne conduite. | 
|---|
|  | 135 | // 2-/ float x[5]={1,2,3,4,5}; {NDataBlock A(n2,&x[0]);} cout<<x[2]; | 
|---|
|  | 136 | //     Ici, a la sortie du bloc {}, le destructeur de "A" va detruire | 
|---|
|  | 137 | //     l'adresse de &x[0]: je n'ose imaginer que ca se fasse sans probleme | 
|---|
|  | 138 | //     et de toute facon, cout<<x[2]; va surement faire des etincelles. | 
|---|
|  | 139 | // 3-/ x = new float[n1]; NDataBlock A(n2,x,new Bridge); | 
|---|
|  | 140 | //     1er danger: si n2>n1 depassement de tableaux (core dump) | 
|---|
|  | 141 | //     2sd danger: si la methode bridgee (blitz?) detruit x[] | 
|---|
|  | 142 | //                 "A" n'a plus de donnees connectees! | 
|---|
|  | 143 | // --- CONCLUSION | 
|---|
|  | 144 | // Cette classe est franchement merdique. | 
|---|
|  | 145 | // - On peut accepter la prise de risque liee a NDataBlock(n2,x,new Bridge); | 
|---|
|  | 146 | //   car je ne vois pas comment on pourrait faire autrement pour connecter | 
|---|
|  | 147 | //   un tableau de type blitz par exemple. | 
|---|
|  | 148 | // - Par contre le createur NDataBlock(n2,x); doit etre interdit | 
|---|
|  | 149 | //   dans sa forme actelle car trop dangereux et il me semble inutile. | 
|---|
|  | 150 | // - Dans cette nouvelle optique: | 
|---|
|  | 151 | //   NDataBlock(n2,x,new Bridge) et NDataBlock(n2,x) disparaissent | 
|---|
|  | 152 | //   On remplace par NDataBlock(n2,x) {Alloc(n2,x,new Bridge);} | 
|---|
|  | 153 | //      qui force le Bridge dans tout les cas puisque NDataBlock | 
|---|
|  | 154 | //      ne possede pas les donnees. | 
|---|
|  | 155 | //   Mais puis-je encore le faire vu que NDataBlock est a la base | 
|---|
|  | 156 | //   de TVector,TMatrix et qu'il faut donc reprendre tout le code DPC | 
|---|
|  | 157 | // - Quoiqu'il arrive Alloc est une methode privee et peut donc rester | 
|---|
|  | 158 | //   sous sa forme actuelle. | 
|---|
|  | 159 | // | 
|---|
|  | 160 | { | 
|---|
|  | 161 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 162 | cout<<"?_NDataBlock::Alloc("<<this<<"," | 
|---|
|  | 163 | <<n<<","<<data<<","<<br<<") mSz="<<mSz | 
|---|
|  | 164 | <<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl; | 
|---|
|  | 165 | #endif | 
|---|
|  | 166 |  | 
|---|
|  | 167 | if(br && !data) | 
|---|
|  | 168 | throw(NullPtrError("NDataBlock::Alloc br!=NULL && data==NULL\n")); | 
|---|
|  | 169 | if(n==0) throw(SzMismatchError("NDataBlock::Alloc n==0\n")); | 
|---|
|  | 170 | if(mSRef) Delete(); | 
|---|
|  | 171 | mSz = n; | 
|---|
|  | 172 | mSRef = new NDREF; | 
|---|
|  | 173 | mSRef->nref = 1; | 
|---|
|  | 174 | if(data) mSRef->data = data; | 
|---|
|  | 175 | else {mSRef->data = new T[n]; memset(mSRef->data,0,n*sizeof(T));} | 
|---|
|  | 176 | mSRef->bridge = br; | 
|---|
|  | 177 |  | 
|---|
|  | 178 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 179 | // Meme dans le cas data!=0 et br==0 (connexion d'un tableau | 
|---|
|  | 180 | // avec destruction geree par ~NDataBlock (cas 2-) on compte | 
|---|
|  | 181 | // comme si on avait fait une allocation du tableau (ce qui a ete | 
|---|
|  | 182 | // fait au niveau du dessus!). | 
|---|
|  | 183 | if(!br) NallocData++; NallocSRef++; | 
|---|
|  | 184 | cout<<"...?_NDataBlock::Alloc mSz="<<mSz<<" mSRef="<<mSRef | 
|---|
|  | 185 | <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data | 
|---|
|  | 186 | <<" mSRef->bridge="<<mSRef->bridge<<" IsTemp="<<mIsTemp | 
|---|
|  | 187 | <<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl; | 
|---|
|  | 188 | #endif | 
|---|
|  | 189 | } | 
|---|
|  | 190 |  | 
|---|
|  | 191 | template <class T> | 
|---|
|  | 192 | void NDataBlock<T>::Clone(const NDataBlock<T>& a) | 
|---|
|  | 193 | // Clone: copie de donnees a partir de "a" | 
|---|
|  | 194 | { | 
|---|
|  | 195 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 196 | cout<<"?_NDataBlock::Clone("<<this<<","<<&a<<") a.(mSz=" | 
|---|
|  | 197 | <<a.mSz<<" mSRef="<<a.mSRef<<" IsTemp="<<a.IsTemp() | 
|---|
|  | 198 | <<"), mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl; | 
|---|
|  | 199 | #endif | 
|---|
|  | 200 |  | 
|---|
|  | 201 | if(&a==NULL) throw(NullPtrError("NDataBlock::Clone  &a==NULL\n")); | 
|---|
|  | 202 | if(!a.mSRef || a.mSz==0) throw(SzMismatchError("NDataBlock::Clone a.mSz==0\n")); | 
|---|
|  | 203 | Alloc(a.mSz); | 
|---|
|  | 204 | memcpy(Data(),a.Data(),mSz*sizeof(T)); | 
|---|
|  | 205 | } | 
|---|
|  | 206 |  | 
|---|
|  | 207 | template <class T> | 
|---|
|  | 208 | void NDataBlock<T>::CloneOrShare(const NDataBlock<T>& a) | 
|---|
|  | 209 | // CloneOrShare: Share si "a" temporaire, Clone sinon. | 
|---|
|  | 210 | { | 
|---|
|  | 211 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 212 | cout<<"?_NDataBlock::CloneOrShare("<<this<<","<<&a<<")"<<endl; | 
|---|
|  | 213 | #endif | 
|---|
|  | 214 |  | 
|---|
|  | 215 | if(&a==NULL) throw(NullPtrError("NDataBlock::CloneOrShare  &a==NULL\n")); | 
|---|
|  | 216 | if(a.IsTemp()) Share(a); else Clone(a); | 
|---|
|  | 217 | } | 
|---|
|  | 218 |  | 
|---|
|  | 219 | template <class T> | 
|---|
|  | 220 | void NDataBlock<T>::Share(const NDataBlock<T>& a) | 
|---|
|  | 221 | // Share: Partage les donnees avec "a" | 
|---|
|  | 222 | { | 
|---|
|  | 223 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 224 | cout<<"?_NDataBlock::Share("<<this<<","<<&a<<")"; | 
|---|
|  | 225 | if(&a!=NULL) cout<<" a.(mSz="<<a.mSz<<" mSRef="<<a.mSRef | 
|---|
|  | 226 | <<" IsTemp="<<a.IsTemp()<<")"; | 
|---|
|  | 227 | cout<<", mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl; | 
|---|
|  | 228 | #endif | 
|---|
|  | 229 |  | 
|---|
|  | 230 | if(&a==NULL) throw(NullPtrError("NDataBlock::Share  &a==NULL\n")); | 
|---|
|  | 231 | if(!a.mSRef || a.mSz==0) throw(NullPtrError("NDataBlock::Share a.mSz=0\n")); | 
|---|
|  | 232 | if(mSRef) Delete(); | 
|---|
|  | 233 | mSz = a.mSz; mSRef = a.mSRef; mSRef->nref++; | 
|---|
|  | 234 |  | 
|---|
|  | 235 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 236 | cout<<"...?_NDataBlock::Share mSz="<<mSz<<" mSRef="<<mSRef | 
|---|
|  | 237 | <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data | 
|---|
|  | 238 | <<" mSRef->bridge="<<mSRef->bridge<<" IsTemp="<<mIsTemp<<endl; | 
|---|
|  | 239 | #endif | 
|---|
|  | 240 | } | 
|---|
|  | 241 |  | 
|---|
|  | 242 | template <class T> | 
|---|
|  | 243 | void NDataBlock<T>::Delete(void) | 
|---|
|  | 244 | // Pour detruire les pointeurs en tenant compte des references | 
|---|
|  | 245 | { | 
|---|
|  | 246 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 247 | cout<<"?_NDataBlock::Delete("<<this<<") mSz="<<mSz | 
|---|
|  | 248 | <<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp; | 
|---|
|  | 249 | if(mSRef) | 
|---|
|  | 250 | cout<<" mSRef->nref="<<mSRef->nref<<" mSRef->data=" | 
|---|
|  | 251 | <<mSRef->data<<" mSRef->bridge="<<mSRef->bridge; | 
|---|
|  | 252 | cout<<endl; | 
|---|
|  | 253 | #endif | 
|---|
|  | 254 |  | 
|---|
|  | 255 | if(mSRef==NULL) return; | 
|---|
|  | 256 | mSRef->nref--; | 
|---|
|  | 257 | if(mSRef->nref != 0) { | 
|---|
|  | 258 |  | 
|---|
|  | 259 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 260 | cout<<"...?_NDataBlock::Delete() pas de desallocation il reste nref=" | 
|---|
|  | 261 | <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl; | 
|---|
|  | 262 | #endif | 
|---|
|  | 263 |  | 
|---|
|  | 264 | mSz = 0; mSRef=NULL; | 
|---|
|  | 265 | return; | 
|---|
|  | 266 | } | 
|---|
|  | 267 |  | 
|---|
|  | 268 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 269 | if(!mSRef->bridge) NallocData--; NallocSRef--; | 
|---|
|  | 270 | cout<<"...?_NDataBlock::Delete() desallocation complete il reste nref=" | 
|---|
|  | 271 | <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl; | 
|---|
|  | 272 | #endif | 
|---|
|  | 273 |  | 
|---|
|  | 274 | // Si il y a un Bridge les donnees ne n'appartiennent pas, on detruit le Bridge | 
|---|
|  | 275 | // sinon, les donnees ont ete allouees par nos soins, on libere l'espace | 
|---|
|  | 276 | if(mSRef->bridge) delete mSRef->bridge; else delete [] mSRef->data; | 
|---|
|  | 277 | mSRef->bridge=NULL; mSRef->data=NULL; | 
|---|
|  | 278 | delete mSRef; mSRef=NULL; mSz = 0; | 
|---|
|  | 279 | } | 
|---|
|  | 280 |  | 
|---|
|  | 281 | template <class T> | 
|---|
|  | 282 | void NDataBlock<T>::FillFrom(size_t n,T* data) | 
|---|
|  | 283 | // Remplissage par un tableau de donnees | 
|---|
|  | 284 | // - Si classe vide : creation de l'espace memoire | 
|---|
|  | 285 | // - Si classe connectee : on ecrit selon la longueur minimale | 
|---|
|  | 286 | //                         (cad this->mSz ou "n") | 
|---|
|  | 287 | { | 
|---|
|  | 288 | if(data==NULL) throw(NullPtrError("NDataBlock::FillFrom  data==NULL\n")); | 
|---|
|  | 289 | if(n==0) throw(ParmError("NDataBlock::FillFrom  n<=0\n")); | 
|---|
|  | 290 | if(mSRef==NULL) Alloc(n); | 
|---|
|  | 291 | if(mSz<n) n = mSz; | 
|---|
|  | 292 | memcpy(Data(),data,n*sizeof(T)); | 
|---|
|  | 293 | } | 
|---|
|  | 294 |  | 
|---|
|  | 295 | template <class T> | 
|---|
|  | 296 | void NDataBlock<T>::Realloc(size_t nnew,bool force) | 
|---|
|  | 297 | // Re-allocation de "nnew" place memoire pour les donnees | 
|---|
|  | 298 | // avec conservation des "nold" donnees precedentes si possible. | 
|---|
|  | 299 | // "force" gere la re-allocation de la place memoire pour les donnees. | 
|---|
|  | 300 | // Divers cas se presentent: | 
|---|
|  | 301 | // a-/ *** nnew>nold force=quelconque *** | 
|---|
|  | 302 | //     place re-allouee, donnees [0,nold[ copiees, surplus [nold,new[ mis a zero | 
|---|
|  | 303 | // b-/ *** nnew<=nold force=true *** | 
|---|
|  | 304 | //     place re-allouee, donnees [0,nnew[ copiees, pas de surplus | 
|---|
|  | 305 | // c-/ *** nnew<=nold force=false *** | 
|---|
|  | 306 | //     place non re-allouee, seule la valeur de la taille est diminuee | 
|---|
|  | 307 | // - On tient compte du partage des donnees dans tous les cas. | 
|---|
|  | 308 | // - Si il n'y a pas de donnees connectees a la classe, on re-alloue | 
|---|
|  | 309 | //   dans tous les cas | 
|---|
|  | 310 | { | 
|---|
|  | 311 | if(nnew==0) throw(ParmError("NDataBlock::Realloc  n<=0\n")); | 
|---|
|  | 312 |  | 
|---|
|  | 313 | // Cas sans re-allocation memoire | 
|---|
|  | 314 | if(mSRef && nnew<=mSz && ! force) { mSz=nnew; return;} | 
|---|
|  | 315 |  | 
|---|
|  | 316 | // Cas avec re-allocation memoire | 
|---|
|  | 317 | size_t ncop; | 
|---|
|  | 318 | if(!mSRef || mSz==0) ncop=0; else if(mSz<nnew) ncop=mSz; else ncop=nnew; | 
|---|
|  | 319 | T* dataloc = new T[nnew]; | 
|---|
|  | 320 | if(ncop>0) memcpy(dataloc,mSRef->data,ncop*sizeof(T)); | 
|---|
|  | 321 | if(nnew>ncop) memset(dataloc+ncop,0,(nnew-ncop)*sizeof(T)); | 
|---|
|  | 322 | Alloc(nnew,dataloc,NULL); //Alloc gere partage de reference et bridge | 
|---|
|  | 323 | } | 
|---|
|  | 324 |  | 
|---|
|  | 325 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 326 | //**** Impression | 
|---|
|  | 327 |  | 
|---|
|  | 328 | template <class T> | 
|---|
|  | 329 | void NDataBlock<T>::Print(ostream& os,size_t i1,size_t n) const | 
|---|
|  | 330 | // Impression de n elements a partir de i1 | 
|---|
|  | 331 | { | 
|---|
|  | 332 | size_t nr = 0; | 
|---|
|  | 333 | T* p = NULL; Bridge* br = NULL; | 
|---|
|  | 334 | if(mSRef) {nr = mSRef->nref; p = mSRef->data; br = mSRef->bridge;} | 
|---|
|  | 335 | os<<"NDataBlock::Print("<<this<<",Sz="<<mSz<<",IsTemp="<<mIsTemp<<")\n" | 
|---|
|  | 336 | <<"            mSRef="<<mSRef<<"(nref="<<nr<<",data="<<p | 
|---|
|  | 337 | <<",bridge="<<br<<")"<<endl; | 
|---|
|  | 338 | if(i1>=mSz || n<=0 || !p) return; | 
|---|
|  | 339 | size_t i2 = i1+n; if(i2>mSz) i2=mSz; | 
|---|
|  | 340 | size_t im = 1; bool enl=false; | 
|---|
|  | 341 | while(i1<i2) { | 
|---|
|  | 342 | enl = false; | 
|---|
|  | 343 | os<<" "<<(*this)(i1);  i1++; | 
|---|
|  | 344 | if(im==8) {os<<"\n"; im=1; enl=true;} else im++; | 
|---|
|  | 345 | } | 
|---|
|  | 346 | if(!enl) os<<endl; | 
|---|
|  | 347 | } | 
|---|
|  | 348 |  | 
|---|
|  | 349 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 350 |  | 
|---|
|  | 351 | template <class T> | 
|---|
|  | 352 | T NDataBlock<T>::Sum(size_t i1,size_t n) const | 
|---|
|  | 353 | // Somme des elements de i1 a i1+n-1 | 
|---|
|  | 354 | { | 
|---|
|  | 355 | if(i1>=mSz) return 0; | 
|---|
|  | 356 | if(n>mSz) n = mSz; if(n==0) n = mSz-i1; | 
|---|
|  | 357 | T const *p=Begin()+i1, *pe=p+n; | 
|---|
|  | 358 | T val = 0; | 
|---|
|  | 359 | while (p<pe) val += *p++; | 
|---|
|  | 360 | return val; | 
|---|
|  | 361 | } | 
|---|
|  | 362 |  | 
|---|
|  | 363 | template <class T> | 
|---|
|  | 364 | T NDataBlock<T>::Product(size_t i1,size_t n) const | 
|---|
|  | 365 | // Produit des elements de i1 a i1+n-1 | 
|---|
|  | 366 | { | 
|---|
|  | 367 | if(i1>=mSz) return 0; | 
|---|
|  | 368 | if(n>mSz) n = mSz; if(n==0) n = mSz-i1; | 
|---|
|  | 369 | T const *p=Begin()+i1, *pe=p+n; | 
|---|
|  | 370 | T val = 0; | 
|---|
|  | 371 | while (p<pe) val *= *p++; | 
|---|
|  | 372 | return val; | 
|---|
|  | 373 | } | 
|---|
|  | 374 |  | 
|---|
|  | 375 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 376 | //**** Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b; | 
|---|
|  | 377 |  | 
|---|
|  | 378 | template <class T> | 
|---|
|  | 379 | NDataBlock<T>& NDataBlock<T>::operator = (const NDataBlock<T>& a) | 
|---|
|  | 380 | // Affectation: partage des donnees si "a" temporaire, clone sinon. | 
|---|
|  | 381 | { | 
|---|
|  | 382 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 383 | cout<<"?_NDataBlock::operator=("<<this<<","<<&a<<") a.(mSz=" | 
|---|
|  | 384 | <<a.mSz<<" mSRef="<<a.mSRef<<" IsTemp="<<a.IsTemp() | 
|---|
|  | 385 | <<"), mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl; | 
|---|
|  | 386 | #endif | 
|---|
|  | 387 |  | 
|---|
|  | 388 | if(this == &a) return *this; | 
|---|
|  | 389 | if(a.mSz==0) | 
|---|
|  | 390 | throw(SzMismatchError("NDataBlock::operator=A null size\n")); | 
|---|
|  | 391 | CloneOrShare(a); | 
|---|
|  | 392 | return *this; | 
|---|
|  | 393 | } | 
|---|
|  | 394 |  | 
|---|
|  | 395 | template <class T> | 
|---|
|  | 396 | NDataBlock<T>& NDataBlock<T>::operator = (T v) | 
|---|
|  | 397 | // Affectation de tous les elements a une constante "v" | 
|---|
|  | 398 | { | 
|---|
|  | 399 | #ifdef DEBUG_NDATABLOCK | 
|---|
|  | 400 | cout<<"?_NDataBlock::operator=("<<this<<","<<v<<")" | 
|---|
|  | 401 | <<" mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl; | 
|---|
|  | 402 | #endif | 
|---|
|  | 403 |  | 
|---|
|  | 404 | if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n")); | 
|---|
|  | 405 | T *p=Begin(), *pe=End(); | 
|---|
|  | 406 | while (p<pe) *p++ = v; | 
|---|
|  | 407 | return *this; | 
|---|
|  | 408 | } | 
|---|
|  | 409 |  | 
|---|
|  | 410 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 411 | //**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += <T> b; | 
|---|
|  | 412 |  | 
|---|
|  | 413 | template <class T> | 
|---|
|  | 414 | NDataBlock<T>& NDataBlock<T>::operator += (T b) | 
|---|
|  | 415 | { | 
|---|
|  | 416 | if(mSz==0) throw(SzMismatchError("NDataBlock::operator+=v null size\n")); | 
|---|
|  | 417 | T *p=Begin(), *pe=End(); | 
|---|
|  | 418 | while (p<pe) *p++ += b; | 
|---|
|  | 419 | return *this; | 
|---|
|  | 420 | } | 
|---|
|  | 421 |  | 
|---|
|  | 422 | template <class T> | 
|---|
|  | 423 | NDataBlock<T>& NDataBlock<T>::operator -= (T b) | 
|---|
|  | 424 | { | 
|---|
|  | 425 | if(mSz==0) throw(SzMismatchError("NDataBlock::operator-=v null size\n")); | 
|---|
|  | 426 | T *p=Begin(), *pe=End(); | 
|---|
|  | 427 | while (p<pe) *p++ -= b; | 
|---|
|  | 428 | return *this; | 
|---|
|  | 429 | } | 
|---|
|  | 430 |  | 
|---|
|  | 431 | template <class T> | 
|---|
|  | 432 | NDataBlock<T>& NDataBlock<T>::operator *= (T b) | 
|---|
|  | 433 | { | 
|---|
|  | 434 | if(mSz==0) throw(SzMismatchError("NDataBlock::operator*=v null size\n")); | 
|---|
|  | 435 | T *p=Begin(), *pe=End(); | 
|---|
|  | 436 | while (p<pe) *p++ *= b; | 
|---|
|  | 437 | return *this; | 
|---|
|  | 438 | } | 
|---|
|  | 439 |  | 
|---|
|  | 440 | template <class T> | 
|---|
|  | 441 | NDataBlock<T>& NDataBlock<T>::operator /= (T b) | 
|---|
|  | 442 | { | 
|---|
|  | 443 | if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n")); | 
|---|
|  | 444 | if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n")); | 
|---|
|  | 445 | T *p=Begin(), *pe=End(); | 
|---|
|  | 446 | while (p<pe) *p++ /= b; | 
|---|
|  | 447 | return *this; | 
|---|
|  | 448 | } | 
|---|
|  | 449 |  | 
|---|
|  | 450 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 451 | //**** Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock; | 
|---|
|  | 452 |  | 
|---|
|  | 453 | template <class T> | 
|---|
|  | 454 | NDataBlock<T>& NDataBlock<T>::operator += (const NDataBlock<T>& a) | 
|---|
|  | 455 | { | 
|---|
|  | 456 | if(mSz==0 || mSz!=a.mSz) | 
|---|
|  | 457 | throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null")); | 
|---|
|  | 458 | T *p=Begin(), *pe=End(); | 
|---|
|  | 459 | T const * pa=a.Begin(); | 
|---|
|  | 460 | while (p<pe) *p++ += *pa++; | 
|---|
|  | 461 | return *this; | 
|---|
|  | 462 | } | 
|---|
|  | 463 |  | 
|---|
|  | 464 | template <class T> | 
|---|
|  | 465 | NDataBlock<T>& NDataBlock<T>::operator -= (const NDataBlock<T>& a) | 
|---|
|  | 466 | { | 
|---|
|  | 467 | if(mSz==0 || mSz!=a.mSz) | 
|---|
|  | 468 | throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null")); | 
|---|
|  | 469 | T *p=Begin(), *pe=End(); | 
|---|
|  | 470 | T const *pa=a.Begin(); | 
|---|
|  | 471 | while (p<pe) *p++ -= *pa++; | 
|---|
|  | 472 | return *this; | 
|---|
|  | 473 | } | 
|---|
|  | 474 |  | 
|---|
|  | 475 | template <class T> | 
|---|
|  | 476 | NDataBlock<T>& NDataBlock<T>::operator *= (const NDataBlock<T>& a) | 
|---|
|  | 477 | { | 
|---|
|  | 478 | if(mSz==0 || mSz!=a.mSz) | 
|---|
|  | 479 | throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null")); | 
|---|
|  | 480 | T *p=Begin(), *pe=End(); | 
|---|
|  | 481 | T const *pa=a.Begin(); | 
|---|
|  | 482 | while (p<pe) *p++ *= *pa++; | 
|---|
|  | 483 | return *this; | 
|---|
|  | 484 | } | 
|---|
|  | 485 |  | 
|---|
|  | 486 | template <class T> | 
|---|
|  | 487 | NDataBlock<T>& NDataBlock<T>::operator /= (const NDataBlock<T>& a) | 
|---|
|  | 488 | // Attention, aucune protection si un element de "a" est nul. | 
|---|
|  | 489 | { | 
|---|
|  | 490 | if(mSz==0 || mSz!=a.mSz) | 
|---|
|  | 491 | throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null")); | 
|---|
|  | 492 | T *p=Begin(), *pe=End(); | 
|---|
|  | 493 | T const *pa=a.Begin(); | 
|---|
|  | 494 | while (p<pe) *p++ /= *pa++; | 
|---|
|  | 495 | return *this; | 
|---|
|  | 496 | } | 
|---|
|  | 497 |  | 
|---|
|  | 498 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 499 | //**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+<T>b; | 
|---|
|  | 500 | //                            NDataBlock = <T>b+NDataBlock; | 
|---|
|  | 501 |  | 
|---|
|  | 502 | template <class T> | 
|---|
|  | 503 | NDataBlock<T> NDataBlock<T>::Add(T b) const | 
|---|
|  | 504 | // Pour A+b | 
|---|
|  | 505 | { | 
|---|
|  | 506 | NDataBlock<T> result(*this); result.SetTemp(true); | 
|---|
|  | 507 | result += b; | 
|---|
|  | 508 | return result; | 
|---|
|  | 509 | } | 
|---|
|  | 510 |  | 
|---|
|  | 511 | template <class T> | 
|---|
|  | 512 | NDataBlock<T> NDataBlock<T>::Sub(T b) const | 
|---|
|  | 513 | // Pour A-b | 
|---|
|  | 514 | { | 
|---|
|  | 515 | NDataBlock<T> result(*this); result.SetTemp(true); | 
|---|
|  | 516 | return result -= b; | 
|---|
|  | 517 | } | 
|---|
|  | 518 |  | 
|---|
|  | 519 | template <class T> | 
|---|
|  | 520 | NDataBlock<T> NDataBlock<T>::SubInv(T b) const | 
|---|
|  | 521 | // Pour b-A | 
|---|
|  | 522 | { | 
|---|
|  | 523 | NDataBlock<T> result(*this); result.SetTemp(true); | 
|---|
|  | 524 | T *p=result.Begin(), *pe=result.End(); | 
|---|
|  | 525 | T const *pa=this->Begin(); | 
|---|
|  | 526 | while(p<pe) {*p++ = b - *pa++;} | 
|---|
|  | 527 | return result; | 
|---|
|  | 528 | } | 
|---|
|  | 529 |  | 
|---|
|  | 530 | template <class T> | 
|---|
|  | 531 | NDataBlock<T> NDataBlock<T>::Mul(T b) const | 
|---|
|  | 532 | // Pour A*b | 
|---|
|  | 533 | { | 
|---|
|  | 534 | NDataBlock<T> result(*this); result.SetTemp(true); | 
|---|
|  | 535 | return result *= b; | 
|---|
|  | 536 | } | 
|---|
|  | 537 |  | 
|---|
|  | 538 | template <class T> | 
|---|
|  | 539 | NDataBlock<T> NDataBlock<T>::Div(T b) const | 
|---|
|  | 540 | // Pour A/b | 
|---|
|  | 541 | { | 
|---|
|  | 542 | NDataBlock<T> result(*this); result.SetTemp(true); | 
|---|
|  | 543 | return result /= b; | 
|---|
|  | 544 | } | 
|---|
|  | 545 |  | 
|---|
|  | 546 | template <class T> | 
|---|
|  | 547 | NDataBlock<T> NDataBlock<T>::DivInv(T b) const | 
|---|
|  | 548 | // Pour b/A | 
|---|
|  | 549 | { | 
|---|
|  | 550 | NDataBlock<T> result(*this); result.SetTemp(true); | 
|---|
|  | 551 | T *p=result.Begin(), *pe=result.End(); | 
|---|
|  | 552 | T const *pa = this->Begin(); | 
|---|
|  | 553 | while(p<pe) {*p++ = b / *pa++;} | 
|---|
|  | 554 | return result; | 
|---|
|  | 555 | } | 
|---|
|  | 556 |  | 
|---|
|  | 557 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 558 | //**** Surcharge de +,-,*,/ : NDataBlock = NDataBlock+NDataBlock; | 
|---|
|  | 559 |  | 
|---|
|  | 560 | template <class T> | 
|---|
|  | 561 | NDataBlock<T> NDataBlock<T>::Add(const NDataBlock<T>& b) const | 
|---|
|  | 562 | // Pour A+B | 
|---|
|  | 563 | { | 
|---|
|  | 564 | if(mSz!=b.mSz) | 
|---|
|  | 565 | throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n")); | 
|---|
|  | 566 | NDataBlock<T> result; result.SetTemp(true); | 
|---|
|  | 567 | if(b.IsTemp()) {result.Share(b);            result += *this;} | 
|---|
|  | 568 | else         {result.CloneOrShare(*this); result += b;} | 
|---|
|  | 569 | return result; | 
|---|
|  | 570 | } | 
|---|
|  | 571 |  | 
|---|
|  | 572 | template <class T> | 
|---|
|  | 573 | NDataBlock<T> NDataBlock<T>::Mul(const NDataBlock<T>& b) const | 
|---|
|  | 574 | // Pour A*B | 
|---|
|  | 575 | { | 
|---|
|  | 576 | if(mSz!=b.mSz) | 
|---|
|  | 577 | throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n")); | 
|---|
|  | 578 | NDataBlock<T> result; result.SetTemp(true); | 
|---|
|  | 579 | if(b.IsTemp()) {result.Share(b);            result *= *this;} | 
|---|
|  | 580 | else         {result.CloneOrShare(*this); result *= b;} | 
|---|
|  | 581 | return result; | 
|---|
|  | 582 | } | 
|---|
|  | 583 |  | 
|---|
|  | 584 | template <class T> | 
|---|
|  | 585 | NDataBlock<T> NDataBlock<T>::Sub(const NDataBlock<T>& b) const | 
|---|
|  | 586 | // Pour A-B | 
|---|
|  | 587 | { | 
|---|
|  | 588 | if(mSz!=b.mSz) | 
|---|
|  | 589 | throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n")); | 
|---|
|  | 590 | NDataBlock<T> result; result.SetTemp(true); | 
|---|
|  | 591 | if(b.IsTemp()) { | 
|---|
|  | 592 | result.Share(b); | 
|---|
|  | 593 | T *p=result.Begin(), *pe=result.End(); T const *pa=Begin(); | 
|---|
|  | 594 | while(p<pe) {*p = *pa++  - *p; p++;} | 
|---|
|  | 595 | } else {result.CloneOrShare(*this); result -= b;} | 
|---|
|  | 596 | return result; | 
|---|
|  | 597 | } | 
|---|
|  | 598 |  | 
|---|
|  | 599 | template <class T> | 
|---|
|  | 600 | NDataBlock<T> NDataBlock<T>::Div(const NDataBlock<T>& b) const | 
|---|
|  | 601 | // Pour A/B | 
|---|
|  | 602 | { | 
|---|
|  | 603 | if(mSz!=b.mSz) | 
|---|
|  | 604 | throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n")); | 
|---|
|  | 605 | NDataBlock<T> result; result.SetTemp(true); | 
|---|
|  | 606 | if(b.IsTemp()) { | 
|---|
|  | 607 | result.Share(b); | 
|---|
|  | 608 | T *p=result.Begin(), *pe=result.End(); T const *pa=Begin(); | 
|---|
|  | 609 | while(p<pe) {*p = *pa++  / *p; p++;} | 
|---|
|  | 610 | } else {result.CloneOrShare(*this); result /= b;} | 
|---|
|  | 611 | return result; | 
|---|
|  | 612 | } | 
|---|
|  | 613 |  | 
|---|
|  | 614 | //////////////////////////////////////////////////////////////// | 
|---|
|  | 615 | // ------------------------------------------------------------------------- | 
|---|
|  | 616 | //   Les objets delegues pour la gestion de persistance | 
|---|
|  | 617 | // ------------------------------------------------------------------------- | 
|---|
|  | 618 |  | 
|---|
|  | 619 | /* | 
|---|
|  | 620 | template <class T> | 
|---|
|  | 621 | void ObjFileIO< NDataBlock<T> >::ReadSelf(PInPersist& is) | 
|---|
|  | 622 | template <class T> | 
|---|
|  | 623 | void ObjFileIO< NDataBlock<T> >::WriteSelf(POutPersist& os) | 
|---|
|  | 624 | */ | 
|---|
|  | 625 |  | 
|---|
|  | 626 | // Pour pouvoir ecrire des tableaux de complex, en attendant | 
|---|
|  | 627 | // PIn/POutPersist::Get/Put(complex<>) | 
|---|
|  | 628 | #include "piocmplx.h" | 
|---|
|  | 629 |  | 
|---|
|  | 630 | template <class T> | 
|---|
|  | 631 | FIO_NDataBlock<T>::FIO_NDataBlock() | 
|---|
|  | 632 | { | 
|---|
|  | 633 | dobj=new NDataBlock<T>; | 
|---|
|  | 634 | ownobj=true; | 
|---|
|  | 635 | } | 
|---|
|  | 636 |  | 
|---|
|  | 637 | template <class T> | 
|---|
|  | 638 | FIO_NDataBlock<T>::FIO_NDataBlock(string const & filename) | 
|---|
|  | 639 | { | 
|---|
|  | 640 | dobj=new NDataBlock<T>; | 
|---|
|  | 641 | ownobj=true; | 
|---|
|  | 642 | Read(filename); | 
|---|
|  | 643 | } | 
|---|
|  | 644 |  | 
|---|
|  | 645 | template <class T> | 
|---|
|  | 646 | FIO_NDataBlock<T>::FIO_NDataBlock(const NDataBlock<T> & obj) | 
|---|
|  | 647 | { | 
|---|
|  | 648 | dobj = new NDataBlock<T>(obj); | 
|---|
|  | 649 | ownobj=true; | 
|---|
|  | 650 | } | 
|---|
|  | 651 |  | 
|---|
|  | 652 | template <class T> | 
|---|
|  | 653 | FIO_NDataBlock<T>::FIO_NDataBlock(NDataBlock<T> * obj) | 
|---|
|  | 654 | { | 
|---|
|  | 655 | dobj = obj; | 
|---|
|  | 656 | ownobj=false; | 
|---|
|  | 657 | } | 
|---|
|  | 658 |  | 
|---|
|  | 659 | template <class T> | 
|---|
|  | 660 | FIO_NDataBlock<T>::~FIO_NDataBlock() | 
|---|
|  | 661 | { | 
|---|
|  | 662 | if (ownobj && dobj) delete dobj; | 
|---|
|  | 663 | } | 
|---|
|  | 664 |  | 
|---|
|  | 665 | template <class T> | 
|---|
|  | 666 | AnyDataObj* FIO_NDataBlock<T>::DataObj() | 
|---|
|  | 667 | { | 
|---|
|  | 668 | return(dobj); | 
|---|
|  | 669 | } | 
|---|
|  | 670 |  | 
|---|
|  | 671 |  | 
|---|
|  | 672 | template <class T> | 
|---|
|  | 673 | void FIO_NDataBlock<T>::ReadSelf(PInPersist& is) | 
|---|
|  | 674 | { | 
|---|
|  | 675 | // On lit les 3 premiers uint_8 | 
|---|
|  | 676 | uint_8 itab[3]; | 
|---|
|  | 677 | is.Get(itab, 3); | 
|---|
|  | 678 | if (dobj == NULL) dobj = new NDataBlock<T>(itab[1]); | 
|---|
|  | 679 | else if (itab[1] != dobj->Size()) dobj->ReSize(itab[1]); | 
|---|
|  | 680 | // On lit le tableau de nombres | 
|---|
|  | 681 | PIOSReadArray(is, dobj->Data(), dobj->Size()); | 
|---|
|  | 682 | } | 
|---|
|  | 683 |  | 
|---|
|  | 684 |  | 
|---|
|  | 685 | template <class T> | 
|---|
|  | 686 | void FIO_NDataBlock<T>::WriteSelf(POutPersist& os) const | 
|---|
|  | 687 | { | 
|---|
|  | 688 | if (dobj == NULL)   return;  // Attention - $CHECK$ Reza 26/04/99 | 
|---|
|  | 689 | //  On ecrit 3 uint_8 | 
|---|
|  | 690 | //  0 : Numero de version,  1 : Taille,  2  reserve a l | 
|---|
|  | 691 | uint_8 itab[3]; | 
|---|
|  | 692 | itab[0] = 1; | 
|---|
|  | 693 | itab[1] = dobj->Size(); | 
|---|
|  | 694 | itab[2] = 0; | 
|---|
|  | 695 | os.Put(itab, 3); | 
|---|
|  | 696 | //  On ecrit le tableau de nombres | 
|---|
|  | 697 | PIOSWriteArray(os, dobj->Data(), dobj->Size()); | 
|---|
|  | 698 | } | 
|---|
|  | 699 |  | 
|---|
|  | 700 | /////////////////////////////////////////////////////////////// | 
|---|
|  | 701 | #ifdef __CXX_PRAGMA_TEMPLATES__ | 
|---|
|  | 702 | #pragma define_template NDataBlock<uint_1> | 
|---|
|  | 703 | #pragma define_template NDataBlock<uint_2> | 
|---|
|  | 704 | #pragma define_template NDataBlock<int_2> | 
|---|
|  | 705 | #pragma define_template NDataBlock<int_4> | 
|---|
|  | 706 | #pragma define_template NDataBlock<int_8> | 
|---|
|  | 707 | #pragma define_template NDataBlock<uint_4> | 
|---|
|  | 708 | #pragma define_template NDataBlock<uint_8> | 
|---|
|  | 709 | #pragma define_template NDataBlock<r_4> | 
|---|
|  | 710 | #pragma define_template NDataBlock<r_8> | 
|---|
|  | 711 | #pragma define_template NDataBlock< complex<float> > | 
|---|
|  | 712 | #pragma define_template NDataBlock< complex<double> > | 
|---|
|  | 713 | // Instances des delegues FileIO (PPersist) | 
|---|
|  | 714 | #pragma define_template FIO_NDataBlock<uint_1> | 
|---|
|  | 715 | #pragma define_template FIO_NDataBlock<uint_2> | 
|---|
|  | 716 | #pragma define_template FIO_NDataBlock<int_2> | 
|---|
|  | 717 | #pragma define_template FIO_NDataBlock<int_4> | 
|---|
|  | 718 | #pragma define_template FIO_NDataBlock<int_8> | 
|---|
|  | 719 | #pragma define_template FIO_NDataBlock<uint_4> | 
|---|
|  | 720 | #pragma define_template FIO_NDataBlock<uint_8> | 
|---|
|  | 721 | #pragma define_template FIO_NDataBlock<r_8> | 
|---|
|  | 722 | #pragma define_template FIO_NDataBlock<r_4> | 
|---|
|  | 723 | #pragma define_template FIO_NDataBlock< complex<float> > | 
|---|
|  | 724 | #pragma define_template FIO_NDataBlock< complex<double> > | 
|---|
|  | 725 | #endif | 
|---|
|  | 726 |  | 
|---|
|  | 727 | #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) | 
|---|
|  | 728 | template class NDataBlock<uint_1>; | 
|---|
|  | 729 | template class NDataBlock<uint_2>; | 
|---|
|  | 730 | template class NDataBlock<int_2>; | 
|---|
|  | 731 | template class NDataBlock<int_4>; | 
|---|
|  | 732 | template class NDataBlock<int_8>; | 
|---|
|  | 733 | template class NDataBlock<uint_4>; | 
|---|
|  | 734 | template class NDataBlock<uint_8>; | 
|---|
|  | 735 | template class NDataBlock<r_4>; | 
|---|
|  | 736 | template class NDataBlock<r_8>; | 
|---|
|  | 737 | template class NDataBlock< complex<float> >; | 
|---|
|  | 738 | template class NDataBlock< complex<double> >; | 
|---|
|  | 739 | // Instances des delegues FileIO (PPersist) | 
|---|
|  | 740 | template class FIO_NDataBlock<uint_1>; | 
|---|
|  | 741 | template class FIO_NDataBlock<uint_2>; | 
|---|
|  | 742 | template class FIO_NDataBlock<int_2>; | 
|---|
|  | 743 | template class FIO_NDataBlock<int_4>; | 
|---|
|  | 744 | template class FIO_NDataBlock<int_8>; | 
|---|
|  | 745 | template class FIO_NDataBlock<uint_4>; | 
|---|
|  | 746 | template class FIO_NDataBlock<uint_8>; | 
|---|
|  | 747 | template class FIO_NDataBlock<r_8>; | 
|---|
|  | 748 | template class FIO_NDataBlock<r_4>; | 
|---|
|  | 749 | template class FIO_NDataBlock< complex<float> >; | 
|---|
|  | 750 | template class FIO_NDataBlock< complex<double> >; | 
|---|
|  | 751 | #endif | 
|---|