casa  $Rev:20696$
variant.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines