00001 #ifndef JARRAY_H
00002 #define JARRAY_H
00003
00004 #include <vector>
00005 #include <string>
00006 #include <complex>
00007 #include <istream>
00008 #include <ostream>
00009 #include <cassert>
00010 #include "sha1.h"
00011
00012 class jengine;
00013
00024 class jarray {
00025 public:
00026
00027
00028
00029 typedef char B;
00030 typedef char C;
00031 typedef short S;
00032 typedef long I;
00033 typedef double D;
00035 typedef struct {
00036 D re,
00037 im;
00038 } Z;
00039
00040 friend class jengine;
00041
00042 public:
00044 enum errorType {
00045 ERR_CONV=10,
00046 ERR_SHAPE=11
00047 };
00048
00050 enum elementType {
00051 T_B01 =1,
00052 T_LIT =2,
00053 T_INT =4,
00054 T_FL =8,
00055 T_CMPX =16
00056 };
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 protected:
00079 typedef struct {
00080 I offset,
00081 flag,
00082 maxbytes,
00083 type,
00084 refcnt,
00085 n,
00086 rank,
00087 shape[1];
00088 } header;
00089 header *hdr;
00090 jengine *je;
00094 typedef struct {I*a;S j;C mflag,unused;} MS;
00095
00105 bool allocate(jengine *je_, elementType type, const I rank, const I* shape);
00106
00108
00109 inline static int fromB01(bool& v, const B d) {v=(d!=0); return 0;};
00110 inline static int fromLIT(bool& v, const C d) {return ERR_CONV;};
00111 inline static int fromINT(bool& v, const I d) {return ERR_CONV;};
00112 inline static int fromFL(bool& v, const D d) {return ERR_CONV;};
00113 inline static int fromCMPX(bool& v, const Z d) {return ERR_CONV;};
00114 inline static int toB01(const bool v, B& d) {d=v; return 0;};
00115 inline static int toLIT(const bool v, C& d) {return ERR_CONV;};
00116 inline static int toINT(const bool v, I& d) {d=v; return 0;};
00117 inline static int toFL(const bool v, D& d) {d=v; return 0;};
00118 inline static int toCMPX(const bool v, Z& d) {d.re=v; d.im=0; return 0;};
00119
00120
00121
00122
00123 inline static int fromB01(char& v, const B d) {return ERR_CONV;};
00124 inline static int fromLIT(char& v, const C d) {v=d; return 0;};
00125 inline static int fromINT(char& v, const I d) {return ERR_CONV;};
00126 inline static int fromFL(char& v, const D d) {return ERR_CONV;};
00127 inline static int fromCMPX(char& v, const Z d) {return ERR_CONV;};
00128 inline static int toB01(const char v, B& d) {return ERR_CONV;};
00129 inline static int toLIT(const char v, C& d) {d=v; return 0;};
00130 inline static int toINT(const char v, I& d) {d=v; return 0;};
00131 inline static int toFL(const char v, D& d) {d=v; return 0;};
00132 inline static int toCMPX(const char v, Z& d) {d.re=v; d.im=0; return 0;};
00133
00134
00135 inline static int fromB01(int& v, const B d) {v=d; return 0;};
00136 inline static int fromLIT(int& v, const C d) {v=d; return 0;};
00137 inline static int fromINT(int& v, const I d) {v=d; return 0;};
00138 inline static int fromFL(int& v, const D d) {return ERR_CONV;};
00139 inline static int fromCMPX(int& v, const Z d) {return ERR_CONV;};
00140 inline static int toB01(const int v, B& d) {return ERR_CONV;};
00141 inline static int toLIT(const int v, C& d) {return ERR_CONV;};
00142 inline static int toINT(const int v, I& d) {d=v; return 0;};
00143 inline static int toFL(const int v, D& d) {d=v; return 0;};
00144 inline static int toCMPX(const int v, Z& d) {d.re=v; d.im=0; return 0;};
00145
00146
00147 inline static int fromB01(long& v, const B d) {v=d; return 0;};
00148 inline static int fromLIT(long& v, const C d) {v=d; return 0;};
00149 inline static int fromINT(long& v, const I d) {v=d; return 0;};
00150 inline static int fromFL(long& v, const D d) {return ERR_CONV;};
00151 inline static int fromCMPX(long& v, const Z d) {return ERR_CONV;};
00152 inline static int toB01(const long v, B& d) {return ERR_CONV;};
00153 inline static int toLIT(const long v, C& d) {return ERR_CONV;};
00154 inline static int toINT(const long v, I& d) {d=v; return 0;};
00155 inline static int toFL(const long v, D& d) {d=v; return 0;};
00156 inline static int toCMPX(const long v, Z& d) {d.re=v; d.im=0; return 0;};
00157
00158
00159 inline static int fromB01(double& v, const B d) {v=d; return 0;};
00160 inline static int fromLIT(double& v, const C d) {v=d; return 0;};
00161 inline static int fromINT(double& v, const I d) {v=d; return 0;};
00162 inline static int fromFL(double& v, const D d) {v=d; return 0;};
00163 inline static int fromCMPX(double& v, const Z d) {return ERR_CONV;};
00164 inline static int toB01(const double v, B& d) {return ERR_CONV;};
00165 inline static int toLIT(const double v, C& d) {return ERR_CONV;};
00166 inline static int toINT(const double v, I& d) {d=v; return 0;};
00167 inline static int toFL(const double v, D& d) {d=v; return 0;};
00168 inline static int toCMPX(const double v, Z& d) {d.re=v; d.im=0; return 0;};
00169
00170
00171 inline static int fromB01(std::complex<double>& v, const B d) {
00172 return ERR_CONV;};
00173 inline static int fromLIT(std::complex<double>& v, const C d) {
00174 v=d; return 0;};
00175 inline static int fromINT(std::complex<double>& v, const I d) {
00176 v=d; return 0;};
00177 inline static int fromFL(std::complex<double>& v, const D d) {
00178 v=d; return 0;};
00179 inline static int fromCMPX(std::complex<double>& v, const Z d) {
00180 std::complex<double> c(d.re, d.im); v=c; return 0;};
00181 inline static int toB01(const std::complex<double> v, B& d) {
00182 return ERR_CONV;};
00183 inline static int toLIT(const std::complex<double> v, C& d) {
00184 return ERR_CONV;};
00185 inline static int toINT(const std::complex<double> v, I& d) {
00186 return ERR_CONV;};
00187 inline static int toFL(const std::complex<double> v, D& d) {
00188 return ERR_CONV;};
00189 inline static int toCMPX(const std::complex<double> v, Z& d) {
00190 d.re=v.real(); d.im=v.imag(); return 0;};
00194 void grab() const;
00195
00197 void release();
00198
00199
00200
00201
00202 inline I getHeader(bool give_up_ownership=true) const {
00203 if (give_up_ownership) hdr->flag|=OWNED_BY_J;
00204 return (I)hdr;
00205 };
00206
00207 private:
00208
00209
00210 const static int OWNED_BY_J=131072;
00211
00212 const static int OWNED_BY_JPLUS=262144;
00213
00214 public:
00217 I getRefcount() const {return hdr->refcnt;};
00218
00225 template<class T> inline int get(T& v, const int i) const {
00226 switch(hdr->type) {
00227 case T_B01: return fromB01(v,((B*)(((B*)hdr)+hdr->offset))[i]);
00228 case T_LIT: return fromLIT(v,((C*)(((B*)hdr)+hdr->offset))[i]);
00229 case T_INT: return fromINT(v,((I*)(((B*)hdr)+hdr->offset))[i]);
00230 case T_FL: return fromFL(v,((D*)(((B*)hdr)+hdr->offset))[i]);
00231 case T_CMPX: return fromCMPX(v,((Z*)(((B*)hdr)+hdr->offset))[i]);
00232 default: return ERR_CONV;
00233 };
00234 };
00235
00241 template<class T> inline int set(const int i, const T v) {
00242 switch(hdr->type) {
00243 case T_B01: return toB01(v,((B*)(((B*)hdr)+hdr->offset))[i]);
00244 case T_LIT: return toLIT(v,((C*)(((B*)hdr)+hdr->offset))[i]);
00245 case T_INT: return toINT(v,((I*)(((B*)hdr)+hdr->offset))[i]);
00246 case T_FL: return toFL(v,((D*)(((B*)hdr)+hdr->offset))[i]);
00247 case T_CMPX: return toCMPX(v,((Z*)(((B*)hdr)+hdr->offset))[i]);
00248 default: return ERR_CONV;
00249 };
00250 };
00251
00256 template<class T> int get(std::vector<T>& v) const {
00257 std::vector<T> r;
00258 r.reserve(hdr->n);
00259 int e;
00260 switch(hdr->type) {
00261 case T_B01: for(int i=0;i<hdr->n;i++)
00262 if (e=fromB01(v[i],((B*)(((B*)hdr)+hdr->offset))[i])) return e;
00263 break;
00264 case T_LIT: for(int i=0;i<hdr->n;i++)
00265 if (e=fromLIT(v[i],((C*)(((B*)hdr)+hdr->offset))[i])) return e;
00266 break;
00267 case T_INT: for(int i=0;i<hdr->n;i++)
00268 if (e=fromINT(v[i],((I*)(((B*)hdr)+hdr->offset))[i])) return e;
00269 break;
00270 case T_FL: for(int i=0;i<hdr->n;i++)
00271 if (e=fromFL(v[i],((D*)(((B*)hdr)+hdr->offset))[i])) return e;
00272 break;
00273 case T_CMPX: for(int i=0;i<hdr->n;i++)
00274 if (e=fromCMPX(v[i],((Z*)(((B*)hdr)+hdr->offset))[i])) return e;
00275 break;
00276 default: return ERR_CONV;
00277 };
00278 r.swap(v);
00279 return 0;
00280 };
00281
00287 template<class T> int get(T& v);
00288
00290 jarray();
00291
00296 jarray(jengine *je_, std::istream& in);
00297
00301 static jarray::I esize(elementType type);
00302
00304 jarray::I esize() const;
00305
00308 void addhash(SHA1 &sha);
00309
00314 bool write(std::ostream& out);
00315
00318 inline bool isValid() const {
00319 return hdr!=NULL;
00320 };
00321
00324 inline const I type() const {
00325 return hdr->type;
00326 };
00327
00330 inline const I rank() const {
00331 return hdr->rank;
00332 };
00333
00336 inline I* shape() const {
00337 return &hdr->shape[0];
00338 };
00339
00343 int extent(int dimension) const {
00344 assert((dimension>=0)&&(dimension<rank()));
00345 return shape()[dimension];
00346 };
00347
00350 inline void shape(std::vector<I> &shape) const {
00351 std::vector<I> r(&hdr->shape[0],&hdr->shape[rank()]);
00352 r.swap(shape);
00353 };
00354
00357 inline const int size() const {
00358 int n=1;
00359 for (int i=0;i<rank();i++) n*=hdr->shape[i];
00360 return n;
00361 };
00362
00365 inline I* data() const {
00366 return (I*)(((B*)hdr)+hdr->offset);
00367 };
00368
00374 jengine* getEngine() const {
00375 return je;
00376 };
00377
00380 jarray(jengine *je_, void *hdr_);
00381
00387 jarray(jengine *je_, elementType type, I rank, I* shape);
00388
00393 jarray(jengine *je_, elementType type, const std::vector<I>& shape);
00394
00398 jarray(jengine *je_,const std::string &str);
00399
00402 jarray(const jarray &other);
00403
00408 jarray& assign(const jarray& other);
00409
00413 inline jarray& operator=(const jarray& other) {
00414 return assign(other);
00415 };
00416
00422 bool operator== ( const jarray& rhs ) const;
00423
00425 ~jarray();
00426 };
00427
00432 std::ostream& operator<< (std::ostream& stream, const jarray& array);
00433
00436 template<class T> class jarray_of_type: public jarray {
00437 private:
00438 static elementType jtype(I dummy) {return T_INT;};
00439 static elementType jtype(D dummy) {return T_FL;};
00440 static elementType jtype(Z dummy) {return T_CMPX;};
00441 static elementType jtype(std::complex<D> dummy) {return T_CMPX;};
00442
00443 public:
00452 jarray_of_type(const jarray &ja):jarray() {
00453 T dummy;
00454 elementType type=jtype(dummy);
00455 if (type!=ja.type()) {
00456 allocate(ja.getEngine(), type, ja.rank(), ja.shape());
00457 int n=ja.size();
00458 for (int i=0;i<n;i++) {
00459 T v;
00460 ja.get(v,i);
00461 set(i,v);
00462 };
00463 } else assign(ja);
00464 };
00465
00469 T& operator[](const I i) {
00470
00471 return ((T*)data())[i];
00472 };
00473
00477 const T& operator[](const I i) const {
00478
00479 return ((T*)data())[i];
00480 };
00481
00484 jarray_of_type(jengine *je_) {
00485 T dummy; I shape[]={}; allocate(je_, jtype(dummy), 0, shape);
00486 };
00487
00491 jarray_of_type(jengine *je_, const I l0) {
00492 T dummy; I shape[]={l0}; allocate(je_, jtype(dummy), 1, shape);
00493 };
00497 T& operator()(const I i0) {
00498 assert(rank()==1); return ((T*)data())[i0];
00499 };
00503 const T& operator()(const I i0) const {
00504 assert(rank()==1); return ((T*)data())[i0];
00505 };
00506
00511 jarray_of_type(jengine *je_, const I l0, const I l1) {
00512 T dummy; I shape[]={l0,l1}; allocate(je_,jtype(dummy), 2, shape);
00513 };
00514
00519 T& operator()(const I i0,const I i1) {
00520 assert(rank()==2); return ((T*)data())[i0*extent(1)+i1];
00521 };
00526 const T& operator()(const I i0,const I i1) const {
00527 assert(rank()==2); return ((T*)data())[i0*extent(1)+i1];
00528 };
00529
00535 jarray_of_type(jengine *je_, const I l0, const I l1, const I l2) {
00536 T dummy; I shape[]={l0,l1,l2}; allocate(je_, jtype(dummy), 3, shape);
00537 };
00538
00544 T& operator()(const I i0,const I i1,const I i2) {
00545 assert(rank()==3); return ((T*)data())[(i0*extent(1)+i1)*extent(2)+i2];
00546 };
00547
00553 const T& operator()(const I i0,const I i1,const I i2) const {
00554 assert(rank()==3); return ((T*)data())[(i0*extent(1)+i1)*extent(2)+i2];
00555 };
00556
00563 jarray_of_type(jengine *je_, const I l0, const I l1, const I l2,
00564 const I l3) {
00565 T dummy; I shape[]={l0,l1,l2,l3}; allocate(je_,jtype(dummy), 4, shape);
00566 };
00567
00574 T& operator()(const I i0,const I i1,const I i2,const I i3) {
00575 assert(rank()==4);
00576 return ((T*)data())[((i0*extent(1)+i1)*extent(2)+i2)*extent(3)+i3];
00577 };
00578
00585 const T& operator()(const I i0,const I i1,const I i2,const I i3) const {
00586 assert(rank()==4);
00587 return ((T*)data())[((i0*extent(1)+i1)*extent(2)+i2)*extent(3)+i3];
00588 };
00589
00597 jarray_of_type(jengine *je_, const I l0, const I l1, const I l2,
00598 const I l3, const I l4) {
00599 T dummy; I shape[]={l0,l1,l2,l3,l4}; allocate(je_,jtype(dummy), 5, shape);
00600 };
00601
00609 T& operator()(const I i0,const I i1,const I i2,const I i3,const I i4) {
00610 assert(rank()==4);
00611 return ((T*)data())[(((i0*extent(1)+i1)*extent(2)+i2)*extent(3)+i3)*extent(4)+i4];
00612 };
00613
00621 const T& operator()(const I i0,const I i1,const I i2,const I i3,const I i4) const {
00622 assert(rank()==4);
00623 return ((T*)data())[(((i0*extent(1)+i1)*extent(2)+i2)*extent(3)+i3)*extent(4)+i4];
00624 };
00625
00626
00631 jarray_of_type(jengine *je_, const I rank, const I *shape) {
00632 T dummy; allocate(je_, jtype(dummy), rank, shape);
00633 };
00634
00638 jarray_of_type(jengine *je_, const std::vector<I> &shape) {
00639 T dummy; allocate(je_, jtype(dummy), shape.size(), &shape[0]);
00640 };
00641
00646 T& operator()(const std::vector<I> &subscripts) {
00647 assert(rank()==subscripts.size());
00648 I pos=0;
00649 for(int i=0;i<subscripts.size();i++) pos=pos*extent(i)+subscripts[i];
00650 return ((T*)data())[pos];
00651 };
00655 const T& operator()(const std::vector<I> &subscripts) const {
00656 assert(rank()==subscripts.size());
00657 I pos=0;
00658 for(int i=0;i<subscripts.size();i++) pos=pos*extent(i)+subscripts[i];
00659 return ((T*)data())[pos];
00660 };
00665 T& operator()(const I *subscripts) {
00666 I pos=0;
00667 for(int i=0;i<rank();i++) pos=pos*extent(i)+subscripts[i];
00668 return ((T*)data())[pos];
00669 };
00674 const T& operator()(const I *subscripts) const {
00675 I pos=0;
00676 for(int i=0;i<rank();i++) pos=pos*extent(i)+subscripts[i];
00677 return ((T*)data())[pos];
00678 };
00679
00680 };
00681 #endif