casa
$Rev:20696$
|
00001 #ifndef __casac_variant_h__ 00002 #define __casac_variant_h__ 00003 00004 #include <string> 00005 #include <vector> 00006 #include <complex> 00007 00008 namespace casac { 00009 00010 class record; 00011 00012 class variant { 00013 00014 public: 00015 00016 enum TYPE { RECORD, BOOL, INT, DOUBLE, COMPLEX, STRING, BOOLVEC, INTVEC, DOUBLEVEC, COMPLEXVEC, STRINGVEC }; 00017 00018 static TYPE compatible_type( TYPE one, TYPE two ); 00019 00020 class error { 00021 public: 00022 error( std::string msg ) : message_(msg) { } 00023 const std::string &message( ) const { return message_; } 00024 private: 00025 std::string message_; 00026 }; 00027 00028 class overflow : public error { 00029 public: 00030 overflow( std::string lbl ) : error(lbl + ": overflow error") { } 00031 }; 00032 00033 variant *clone() const { return new variant(*this); } 00034 int compare(const variant*) const; 00035 00036 variant( ); 00037 variant(const variant &); 00038 00039 variant(bool arg) : typev(BOOL), shape_(1,1) { val.b = arg; } 00040 variant(int arg) : typev(INT), shape_(1,1) { val.i = arg; } 00041 variant(double arg) : typev(DOUBLE), shape_(1,1) { val.d = arg; } 00042 variant(std::complex<double> arg) : typev(COMPLEX) { val.c = new std::complex<double>(arg); } 00043 variant(const char *arg) : typev(STRING), shape_(1,1) 00044 { val.s = new std::string(arg); } 00045 variant(const std::string &arg) : typev(STRING), shape_(1,1) 00046 { val.s = new std::string(arg); } 00047 // 00048 variant(const std::vector<bool> &arg) : typev(BOOLVEC), shape_(1,arg.size()) 00049 { val.bv = new std::vector<bool>(arg); } 00050 variant(const std::vector<bool> &arg, const std::vector<int> &theshape) : typev(BOOLVEC), shape_(theshape) 00051 { val.bv = new std::vector<bool>(arg); } 00052 variant(std::vector<bool> *arg) : typev(BOOLVEC), shape_(1,arg->size()) 00053 { val.bv = arg; } 00054 variant(std::vector<bool> *arg, std::vector<int> &theshape) : typev(BOOLVEC), shape_(theshape) 00055 { val.bv = arg; } 00056 // 00057 variant(const std::vector<int> &arg) : typev(INTVEC), shape_(1,arg.size()) 00058 { val.iv = new std::vector<int>(arg); } 00059 variant(const std::vector<int> &arg, const std::vector<int> &theshape) : typev(INTVEC), shape_(theshape) 00060 { val.iv = new std::vector<int>(arg); } 00061 variant(std::vector<int> *arg) : typev(INTVEC), shape_(1, arg->size()) 00062 { val.iv = arg; } 00063 variant(std::vector<int> *arg, std::vector<int> &theshape) : typev(INTVEC), shape_(theshape) 00064 { val.iv = arg; } 00065 // 00066 variant(const std::vector<double> &arg) : typev(DOUBLEVEC), shape_(1,arg.size()) 00067 { val.dv = new std::vector<double>(arg); } 00068 variant(const std::vector<double> &arg, const std::vector<int> &theshape) : typev(DOUBLEVEC), shape_(theshape) 00069 { val.dv = new std::vector<double>(arg); } 00070 variant(std::vector<double> *arg) : typev(DOUBLEVEC), shape_(1,arg->size()) 00071 { val.dv = arg; } 00072 variant(std::vector<double> *arg, std::vector<int> &theshape) : typev(DOUBLEVEC), shape_(theshape) 00073 { val.dv = arg; } 00074 00075 variant(const std::vector<std::complex<double> > &arg) : typev(COMPLEXVEC), shape_(1, arg.size()) 00076 { val.cv = new std::vector<std::complex<double> >(arg); } 00077 variant(const std::vector<std::complex<double> > &arg, const std::vector<int> &theshape) : typev(COMPLEXVEC), shape_(theshape) 00078 { val.cv = new std::vector<std::complex<double> >(arg); } 00079 variant(std::vector<std::complex<double> > *arg) : typev(COMPLEXVEC), shape_(1,arg->size()) 00080 { val.cv = arg; } 00081 variant(std::vector<std::complex<double> > *arg, std::vector<int> &theshape) : typev(COMPLEXVEC), shape_(theshape) 00082 { val.cv = arg; } 00083 // 00084 variant(const std::vector<std::string> &arg, const std::vector<int> &theshape) : typev(STRINGVEC), shape_(theshape) 00085 { val.sv = new std::vector<std::string>(arg); } 00086 variant(const std::vector<std::string> &arg) : typev(STRINGVEC), shape_(1,arg.size()) 00087 { val.sv = new std::vector<std::string>(arg); } 00088 variant(std::vector<std::string> *arg) : typev(STRINGVEC), shape_(1, arg->size()) 00089 { val.sv = arg; } 00090 variant(std::vector<std::string> *arg, std::vector<int> &theshape) : typev(STRINGVEC), shape_(theshape) 00091 { val.sv = arg; } 00092 // 00093 variant(record &arg); 00094 variant(record *arg); 00095 00096 ~variant( ); 00097 00098 bool toBool( ) const; 00099 int toInt( ) const; 00100 double toDouble( ) const; 00101 std::complex<double> toComplex( ) const; 00102 std::string toString( bool no_brackets=false ) const; 00103 std::vector<bool> toBoolVec( ) const; 00104 std::vector<int> toIntVec( ) const; 00105 std::vector<double> toDoubleVec( ) const; 00106 std::vector<std::complex<double> > toComplexVec( ) const; 00107 std::vector<std::string> toStringVec( ) const; 00108 00109 // Yet to be implemented 00110 00111 // Modify 00112 // --------------------------------------------------- 00113 bool &asBool( ); 00114 int &asInt( ); 00115 double &asDouble( ); 00116 std::complex<double> &asComplex( ); 00117 std::string &asString( ); 00118 std::vector<int> &asIntVec( int size=-1 ); 00119 std::vector<bool> &asBoolVec( int size=-1 ); 00120 std::vector<double> &asDoubleVec( int size=-1 ); 00121 std::vector<std::complex<double> > &asComplexVec( int size=-1 ); 00122 std::vector<std::string> &asStringVec( int size=-1 ); 00123 casac::record &asRecord( ); 00124 00125 void as( TYPE t, int size=-1 ); 00126 00127 // Const 00128 // --------------------------------------------------- 00129 const bool getBool( ) const throw(error); 00130 const int getInt( ) const throw(error); 00131 const double getDouble( ) const throw(error); 00132 const std::complex<double> &getComplex( ) const throw(error); 00133 const std::string &getString( ) const throw(error); 00134 const std::vector<int> &getIntVec( ) const throw(error); 00135 const std::vector<bool> &getBoolVec( ) const throw(error); 00136 const std::vector<double> &getDoubleVec( ) const throw(error); 00137 const std::vector<std::complex<double> > &getComplexVec( ) const throw(error); 00138 const std::vector<std::string> &getStringVec( ) const throw(error); 00139 const record &getRecord( ) const throw(error); 00140 const std::vector<int> &shape() const; 00141 const std::vector<int> &arrayshape() const {return shape();} 00142 00143 // Modify 00144 // --------------------------------------------------- 00145 bool &getBoolMod( ) throw(error); 00146 int &getIntMod( ) throw(error); 00147 double &getDoubleMod( ) throw(error); 00148 std::complex<double> &getComplexMod( ) throw(error); 00149 std::string &getStringMod( ) throw(error); 00150 std::vector<int> &getIntVecMod( ) throw(error); 00151 std::vector<bool> &getBoolVecMod( ) throw(error); 00152 std::vector<double> &getDoubleVecMod( ) throw(error); 00153 std::vector<std::complex<double> > &getComplexVecMod( ) throw(error); 00154 std::vector<std::string> &getStringVecMod( ) throw(error); 00155 record &getRecordMod( ) throw(error); 00156 std::vector<int> &shape(); 00157 std::vector<int> &arrayshape() {return shape();} 00158 00159 const std::string &typeString( ) const; 00160 TYPE type( ) const { return typev; } 00161 00162 void push(bool, bool conform = true); 00163 void push(int, bool conform = true); 00164 void push(double, bool conform = true); 00165 void push(std::complex<double>, bool conform = true); 00166 void push(const std::string&, bool conform = true); 00167 00168 void place(bool, unsigned int index, bool conform = true); 00169 void place(int, unsigned int index, bool conform = true); 00170 void place(double, unsigned int index, bool conform = true); 00171 void place(std::complex<double>, unsigned int index, bool conform = true); 00172 void place(const std::string&, unsigned int index, bool conform = true); 00173 00174 int size( ) const { return typev >= BOOLVEC ? vec_size() : 1; } 00175 void resize( int size ); 00176 00177 private: 00178 00179 // what size does the shape imply 00180 int shape_size( ) const; 00181 00182 // 4294967295 00183 static unsigned int record_id_count; 00184 00185 int vec_size( ) const; 00186 TYPE typev; 00187 union { 00188 bool b; 00189 std::vector<bool> *bv; 00190 int i; 00191 std::vector<int> *iv; 00192 double d; 00193 std::vector<double> *dv; 00194 std::complex<double> *c; 00195 std::vector<std::complex<double> > *cv; 00196 std::string *s; 00197 std::vector<std::string> *sv; 00198 record *recordv; 00199 } val; 00200 std::vector<int> shape_; 00201 00202 std::string create_message( const std::string s ) const; 00203 }; 00204 00205 } // casac namespace 00206 00207 #endif