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;
00093 typedef struct {I*a;S j;C mflag,unused;} MS;
00094
00102 bool allocate(elementType type, const I rank, const I* shape);
00103
00105
00106 inline static int fromB01(bool& v, const B d) {v=(d!=0); return 0;};
00107 inline static int fromLIT(bool& v, const C d) {return ERR_CONV;};
00108 inline static int fromINT(bool& v, const I d) {return ERR_CONV;};
00109 inline static int fromFL(bool& v, const D d) {return ERR_CONV;};
00110 inline static int fromCMPX(bool& v, const Z d) {return ERR_CONV;};
00111 inline static int toB01(const bool v, B& d) {d=v; return 0;};
00112 inline static int toLIT(const bool v, C& d) {return ERR_CONV;};
00113 inline static int toINT(const bool v, I& d) {d=v; return 0;};
00114 inline static int toFL(const bool v, D& d) {d=v; return 0;};
00115 inline static int toCMPX(const bool v, Z& d) {d.re=v; d.im=0; return 0;};
00116
00117
00118
00119
00120 inline static int fromB01(char& v, const B d) {return ERR_CONV;};
00121 inline static int fromLIT(char& v, const C d) {v=d; return 0;};
00122 inline static int fromINT(char& v, const I d) {return ERR_CONV;};
00123 inline static int fromFL(char& v, const D d) {return ERR_CONV;};
00124 inline static int fromCMPX(char& v, const Z d) {return ERR_CONV;};
00125 inline static int toB01(const char v, B& d) {return ERR_CONV;};
00126 inline static int toLIT(const char v, C& d) {d=v; return 0;};
00127 inline static int toINT(const char v, I& d) {d=v; return 0;};
00128 inline static int toFL(const char v, D& d) {d=v; return 0;};
00129 inline static int toCMPX(const char v, Z& d) {d.re=v; d.im=0; return 0;};
00130
00131
00132 inline static int fromB01(int& v, const B d) {v=d; return 0;};
00133 inline static int fromLIT(int& v, const C d) {v=d; return 0;};
00134 inline static int fromINT(int& v, const I d) {v=d; return 0;};
00135 inline static int fromFL(int& v, const D d) {return ERR_CONV;};
00136 inline static int fromCMPX(int& v, const Z d) {return ERR_CONV;};
00137 inline static int toB01(const int v, B& d) {return ERR_CONV;};
00138 inline static int toLIT(const int v, C& d) {return ERR_CONV;};
00139 inline static int toINT(const int v, I& d) {d=v; return 0;};
00140 inline static int toFL(const int v, D& d) {d=v; return 0;};
00141 inline static int toCMPX(const int v, Z& d) {d.re=v; d.im=0; return 0;};
00142
00143
00144 inline static int fromB01(long& v, const B d) {v=d; return 0;};
00145 inline static int fromLIT(long& v, const C d) {v=d; return 0;};
00146 inline static int fromINT(long& v, const I d) {v=d; return 0;};
00147 inline static int fromFL(long& v, const D d) {return ERR_CONV;};
00148 inline static int fromCMPX(long& v, const Z d) {return ERR_CONV;};
00149 inline static int toB01(const long v, B& d) {return ERR_CONV;};
00150 inline static int toLIT(const long v, C& d) {return ERR_CONV;};
00151 inline static int toINT(const long v, I& d) {d=v; return 0;};
00152 inline static int toFL(const long v, D& d) {d=v; return 0;};
00153 inline static int toCMPX(const long v, Z& d) {d.re=v; d.im=0; return 0;};
00154
00155
00156 inline static int fromB01(double& v, const B d) {v=d; return 0;};
00157 inline static int fromLIT(double& v, const C d) {v=d; return 0;};
00158 inline static int fromINT(double& v, const I d) {v=d; return 0;};
00159 inline static int fromFL(double& v, const D d) {v=d; return 0;};
00160 inline static int fromCMPX(double& v, const Z d) {return ERR_CONV;};
00161 inline static int toB01(const double v, B& d) {return ERR_CONV;};
00162 inline static int toLIT(const double v, C& d) {return ERR_CONV;};
00163 inline static int toINT(const double v, I& d) {d=v; return 0;};
00164 inline static int toFL(const double v, D& d) {d=v; return 0;};
00165 inline static int toCMPX(const double v, Z& d) {d.re=v; d.im=0; return 0;};
00166
00167
00168 inline static int fromB01(std::complex<double>& v, const B d) {
00169 return ERR_CONV;};
00170 inline static int fromLIT(std::complex<double>& v, const C d) {
00171 v=d; return 0;};
00172 inline static int fromINT(std::complex<double>& v, const I d) {
00173 v=d; return 0;};
00174 inline static int fromFL(std::complex<double>& v, const D d) {
00175 v=d; return 0;};
00176 inline static int fromCMPX(std::complex<double>& v, const Z d) {
00177 std::complex<double> c(d.re, d.im); v=c; return 0;};
00178 inline static int toB01(const std::complex<double> v, B& d) {
00179 return ERR_CONV;};
00180 inline static int toLIT(const std::complex<double> v, C& d) {
00181 return ERR_CONV;};
00182 inline static int toINT(const std::complex<double> v, I& d) {
00183 return ERR_CONV;};
00184 inline static int toFL(const std::complex<double> v, D& d) {
00185 return ERR_CONV;};
00186 inline static int toCMPX(const std::complex<double> v, Z& d) {
00187 d.re=v.real(); d.im=v.imag(); return 0;};
00191 void grab() const;
00192
00194 void release();
00195
00196
00197
00198
00199 inline I getHeader(bool give_up_ownership=true) const {
00200 if (give_up_ownership) hdr->flag|=OWNED_BY_J;
00201 return (I)hdr;
00202 };
00203
00204 private:
00205
00206
00207 const static int OWNED_BY_J=131072;
00208
00209 const static int OWNED_BY_JPLUS=262144;
00210
00211 public:
00218 template<class T> inline int get(T& v, const int i) const {
00219 switch(hdr->type) {
00220 case T_B01: return fromB01(v,((B*)(((B*)hdr)+hdr->offset))[i]);
00221 case T_LIT: return fromLIT(v,((C*)(((B*)hdr)+hdr->offset))[i]);
00222 case T_INT: return fromINT(v,((I*)(((B*)hdr)+hdr->offset))[i]);
00223 case T_FL: return fromFL(v,((D*)(((B*)hdr)+hdr->offset))[i]);
00224 case T_CMPX: return fromCMPX(v,((Z*)(((B*)hdr)+hdr->offset))[i]);
00225 default: return ERR_CONV;
00226 };
00227 };
00228
00234 template<class T> inline int set(const int i, const T v) {
00235 switch(hdr->type) {
00236 case T_B01: return toB01(v,((B*)(((B*)hdr)+hdr->offset))[i]);
00237 case T_LIT: return toLIT(v,((C*)(((B*)hdr)+hdr->offset))[i]);
00238 case T_INT: return toINT(v,((I*)(((B*)hdr)+hdr->offset))[i]);
00239 case T_FL: return toFL(v,((D*)(((B*)hdr)+hdr->offset))[i]);
00240 case T_CMPX: return toCMPX(v,((Z*)(((B*)hdr)+hdr->offset))[i]);
00241 default: return ERR_CONV;
00242 };
00243 };
00244
00249 template<class T> int get(std::vector<T>& v) const {
00250 std::vector<T> r;
00251 r.reserve(hdr->n);
00252 int e;
00253 switch(hdr->type) {
00254 case T_B01: for(int i=0;i<hdr->n;i++)
00255 if (e=fromB01(v[i],((B*)(((B*)hdr)+hdr->offset))[i])) return e;
00256 break;
00257 case T_LIT: for(int i=0;i<hdr->n;i++)
00258 if (e=fromLIT(v[i],((C*)(((B*)hdr)+hdr->offset))[i])) return e;
00259 break;
00260 case T_INT: for(int i=0;i<hdr->n;i++)
00261 if (e=fromINT(v[i],((I*)(((B*)hdr)+hdr->offset))[i])) return e;
00262 break;
00263 case T_FL: for(int i=0;i<hdr->n;i++)
00264 if (e=fromFL(v[i],((D*)(((B*)hdr)+hdr->offset))[i])) return e;
00265 break;
00266 case T_CMPX: for(int i=0;i<hdr->n;i++)
00267 if (e=fromCMPX(v[i],((Z*)(((B*)hdr)+hdr->offset))[i])) return e;
00268 break;
00269 default: return ERR_CONV;
00270 };
00271 r.swap(v);
00272 return 0;
00273 };
00274
00280 template<class T> int get(T& v);
00281
00283 jarray();
00284
00288 jarray(std::istream& in);
00289
00293 static jarray::I esize(elementType type);
00294
00296 jarray::I esize() const;
00297
00300 void addhash(SHA1 &sha);
00301
00306 bool write(std::ostream& out);
00307
00310 inline bool isValid() const {
00311 return hdr!=NULL;
00312 };
00313
00316 inline const I type() const {
00317 return hdr->type;
00318 };
00319
00322 inline const I rank() const {
00323 return hdr->rank;
00324 };
00325
00328 inline I* shape() const {
00329 return &hdr->shape[0];
00330 };
00331
00335 int extent(int dimension) const {
00336 assert((dimension>=0)&&(dimension<rank()));
00337 return shape()[dimension];
00338 };
00339
00342 inline void shape(std::vector<I> &shape) const {
00343 std::vector<I> r(&hdr->shape[0],&hdr->shape[rank()]);
00344 r.swap(shape);
00345 };
00346
00349 inline const int size() const {
00350 int n=1;
00351 for (int i=0;i<rank();i++) n*=hdr->shape[i];
00352 return n;
00353 };
00354
00357 inline I* data() const {
00358 return (I*)(((B*)hdr)+hdr->offset);
00359 };
00360
00363 jarray(void *hdr_);
00364
00369 jarray(elementType type, I rank, I* shape);
00370
00374 jarray(elementType type, const std::vector<I>& shape);
00375
00378 jarray(const std::string &str);
00379
00382 jarray(const jarray &other);
00383
00388 jarray& assign(const jarray& other);
00389
00393 inline jarray& operator=(const jarray& other) {
00394 return assign(other);
00395 };
00396
00402 bool operator== ( const jarray& rhs ) const;
00403
00405 ~jarray();
00406 };
00407
00412 std::ostream& operator<< (std::ostream& stream, const jarray& array);
00413
00416 template<class T> class jarray_of_type: public jarray {
00417 private:
00418 static elementType jtype(I dummy) {return T_INT;};
00419 static elementType jtype(D dummy) {return T_FL;};
00420 static elementType jtype(Z dummy) {return T_CMPX;};
00421 static elementType jtype(std::complex<D> dummy) {return T_CMPX;};
00422
00423 public:
00432 jarray_of_type(const jarray &ja):jarray() {
00433 T dummy;
00434 elementType type=jtype(dummy);
00435 if (type!=ja.type()) {
00436 allocate(type, ja.rank(), ja.shape());
00437 int n=ja.size();
00438 for (int i=0;i<n;i++) {
00439 T v;
00440 ja.get(v,i);
00441 set(i,v);
00442 };
00443 } else assign(ja);
00444 };
00445
00449 T& operator[](const I i) {
00450
00451 return ((T*)data())[i];
00452 };
00453
00457 const T& operator[](const I i) const {
00458
00459 return ((T*)data())[i];
00460 };
00461
00463 jarray_of_type() {
00464 T dummy; I shape[]={}; allocate(jtype(dummy), 0, shape);
00465 };
00466
00469 jarray_of_type(const I l0) {
00470 T dummy; I shape[]={l0}; allocate(jtype(dummy), 1, shape);
00471 };
00475 T& operator()(const I i0) {
00476 assert(rank()==1); return ((T*)data())[i0];
00477 };
00481 const T& operator()(const I i0) const {
00482 assert(rank()==1); return ((T*)data())[i0];
00483 };
00484
00488 jarray_of_type(const I l0, const I l1) {
00489 T dummy; I shape[]={l0,l1}; allocate(jtype(dummy), 2, shape);
00490 };
00491
00496 T& operator()(const I i0,const I i1) {
00497 assert(rank()==2); return ((T*)data())[i0*extent(1)+i1];
00498 };
00503 const T& operator()(const I i0,const I i1) const {
00504 assert(rank()==2); return ((T*)data())[i0*extent(1)+i1];
00505 };
00506
00511 jarray_of_type(const I l0, const I l1, const I l2) {
00512 T dummy; I shape[]={l0,l1,l2}; allocate(jtype(dummy), 3, shape);
00513 };
00514
00520 T& operator()(const I i0,const I i1,const I i2) {
00521 assert(rank()==3); return ((T*)data())[(i0*extent(1)+i1)*extent(2)+i2];
00522 };
00523
00529 const T& operator()(const I i0,const I i1,const I i2) const {
00530 assert(rank()==3); return ((T*)data())[(i0*extent(1)+i1)*extent(2)+i2];
00531 };
00532
00538 jarray_of_type(const I l0, const I l1, const I l2, const I l3) {
00539 T dummy; I shape[]={l0,l1,l2,l3}; allocate(jtype(dummy), 4, shape);
00540 };
00541
00548 T& operator()(const I i0,const I i1,const I i2,const I i3) {
00549 assert(rank()==4);
00550 return ((T*)data())[((i0*extent(1)+i1)*extent(2)+i2)*extent(3)+i3];
00551 };
00552
00559 const T& operator()(const I i0,const I i1,const I i2,const I i3) const {
00560 assert(rank()==4);
00561 return ((T*)data())[((i0*extent(1)+i1)*extent(2)+i2)*extent(3)+i3];
00562 };
00563
00570 jarray_of_type(const I l0, const I l1, const I l2, const I l3, const I l4) {
00571 T dummy; I shape[]={l0,l1,l2,l3,l4}; allocate(jtype(dummy), 5, shape);
00572 };
00573
00581 T& operator()(const I i0,const I i1,const I i2,const I i3,const I i4) {
00582 assert(rank()==4);
00583 return ((T*)data())[(((i0*extent(1)+i1)*extent(2)+i2)*extent(3)+i3)*extent(4)+i4];
00584 };
00585
00593 const T& operator()(const I i0,const I i1,const I i2,const I i3,const I i4) const {
00594 assert(rank()==4);
00595 return ((T*)data())[(((i0*extent(1)+i1)*extent(2)+i2)*extent(3)+i3)*extent(4)+i4];
00596 };
00597
00598
00602 jarray_of_type(const I rank, const I *shape) {
00603 T dummy; allocate(jtype(dummy), rank, shape);
00604 };
00605
00608 jarray_of_type(const std::vector<I> &shape) {
00609 T dummy; allocate(jtype(dummy), shape.size(), &shape[0]);
00610 };
00611
00615 T& operator()(const std::vector<I> &subscripts) {
00616 assert(rank()==subscripts.size());
00617 I pos=0;
00618 for(int i=0;i<subscripts.size();i++) pos=pos*extent(i)+subscripts[i];
00619 return ((T*)data())[pos];
00620 };
00624 const T& operator()(const std::vector<I> &subscripts) const {
00625 assert(rank()==subscripts.size());
00626 I pos=0;
00627 for(int i=0;i<subscripts.size();i++) pos=pos*extent(i)+subscripts[i];
00628 return ((T*)data())[pos];
00629 };
00634 T& operator()(const I *subscripts) {
00635 I pos=0;
00636 for(int i=0;i<rank();i++) pos=pos*extent(i)+subscripts[i];
00637 return ((T*)data())[pos];
00638 };
00643 const T& operator()(const I *subscripts) const {
00644 I pos=0;
00645 for(int i=0;i<rank();i++) pos=pos*extent(i)+subscripts[i];
00646 return ((T*)data())[pos];
00647 };
00648
00649 };
00650 #endif