casa
$Rev:20696$
|
00001 //# variant.h: multi-typed values 00002 //# 00003 //# Copyright (C) 2011 00004 //# Associated Universities, Inc. Washington DC, USA. 00005 //# 00006 //# This library is free software; you can redistribute it and/or modify it 00007 //# under the terms of the GNU Library General Public License as published by 00008 //# the Free Software Foundation; either version 2 of the License, or (at your 00009 //# option) any later version. 00010 //# 00011 //# This library is distributed in the hope that it will be useful, but WITHOUT 00012 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00014 //# License for more details. 00015 //# 00016 //# You should have received a copy of the GNU Library General Public License 00017 //# along with this library; if not, write to the Free Software Foundation, 00018 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00019 //# 00020 //# Correspondence concerning AIPS++ should be addressed as follows: 00021 //# Internet email: aips2-request@nrao.edu. 00022 //# Postal address: AIPS++ Project Office 00023 //# National Radio Astronomy Observatory 00024 //# 520 Edgemont Road 00025 //# Charlottesville, VA 22903-2475 USA 00026 //# 00027 //# $Id$ 00028 00029 #ifndef __casadbus_variant_h__ 00030 #define __casadbus_variant_h__ 00031 00032 #include <string> 00033 #include <vector> 00034 #include <complex> 00035 00036 namespace casa { 00037 namespace dbus { 00038 00039 class record; 00040 00041 class variant { 00042 00043 public: 00044 00045 enum TYPE { RECORD, BOOL, INT, DOUBLE, COMPLEX, STRING, BOOLVEC, INTVEC, DOUBLEVEC, COMPLEXVEC, STRINGVEC }; 00046 00047 static TYPE compatible_type( TYPE one, TYPE two ); 00048 00049 class error { 00050 public: 00051 error( std::string msg ) : message_(msg) { } 00052 const std::string &message( ) const { return message_; } 00053 private: 00054 std::string message_; 00055 }; 00056 00057 class overflow : public error { 00058 public: 00059 overflow( std::string lbl ) : error(lbl + ": overflow error") { } 00060 }; 00061 00062 variant *clone() const { return new variant(*this); } 00063 int compare(const variant*) const; 00064 00065 variant( ); 00066 variant(const variant &); 00067 00068 variant(bool arg) : typev(BOOL), shape_(1,1) { val.b = arg; } 00069 variant(int arg) : typev(INT), shape_(1,1) { val.i = arg; } 00070 variant(double arg) : typev(DOUBLE), shape_(1,1) { val.d = arg; } 00071 variant(std::complex<double> arg) : typev(COMPLEX) { val.c = new std::complex<double>(arg); } 00072 variant(const char *arg) : typev(STRING), shape_(1,1) 00073 { val.s = new std::string(arg); } 00074 variant(const std::string &arg) : typev(STRING), shape_(1,1) 00075 { val.s = new std::string(arg); } 00076 // 00077 variant(const std::vector<bool> &arg) : typev(BOOLVEC), shape_(1,arg.size()) 00078 { val.bv = new std::vector<bool>(arg); } 00079 variant(const std::vector<bool> &arg, const std::vector<int> &theshape) : typev(BOOLVEC), shape_(theshape) 00080 { val.bv = new std::vector<bool>(arg); } 00081 variant(std::vector<bool> *arg) : typev(BOOLVEC), shape_(1,arg->size()) 00082 { val.bv = arg; } 00083 variant(std::vector<bool> *arg, std::vector<int> &theshape) : typev(BOOLVEC), shape_(theshape) 00084 { val.bv = arg; } 00085 // 00086 variant(const std::vector<int> &arg) : typev(INTVEC), shape_(1,arg.size()) 00087 { val.iv = new std::vector<int>(arg); } 00088 variant(const std::vector<int> &arg, const std::vector<int> &theshape) : typev(INTVEC), shape_(theshape) 00089 { val.iv = new std::vector<int>(arg); } 00090 variant(std::vector<int> *arg) : typev(INTVEC), shape_(1, arg->size()) 00091 { val.iv = arg; } 00092 variant(std::vector<int> *arg, std::vector<int> &theshape) : typev(INTVEC), shape_(theshape) 00093 { val.iv = arg; } 00094 // 00095 variant(const std::vector<double> &arg) : typev(DOUBLEVEC), shape_(1,arg.size()) 00096 { val.dv = new std::vector<double>(arg); } 00097 variant(const std::vector<double> &arg, const std::vector<int> &theshape) : typev(DOUBLEVEC), shape_(theshape) 00098 { val.dv = new std::vector<double>(arg); } 00099 variant(std::vector<double> *arg) : typev(DOUBLEVEC), shape_(1,arg->size()) 00100 { val.dv = arg; } 00101 variant(std::vector<double> *arg, std::vector<int> &theshape) : typev(DOUBLEVEC), shape_(theshape) 00102 { val.dv = arg; } 00103 00104 variant(const std::vector<std::complex<double> > &arg) : typev(COMPLEXVEC), shape_(1, arg.size()) 00105 { val.cv = new std::vector<std::complex<double> >(arg); } 00106 variant(const std::vector<std::complex<double> > &arg, const std::vector<int> &theshape) : typev(COMPLEXVEC), shape_(theshape) 00107 { val.cv = new std::vector<std::complex<double> >(arg); } 00108 variant(std::vector<std::complex<double> > *arg) : typev(COMPLEXVEC), shape_(1,arg->size()) 00109 { val.cv = arg; } 00110 variant(std::vector<std::complex<double> > *arg, std::vector<int> &theshape) : typev(COMPLEXVEC), shape_(theshape) 00111 { val.cv = arg; } 00112 // 00113 variant(const std::vector<std::string> &arg, const std::vector<int> &theshape) : typev(STRINGVEC), shape_(theshape) 00114 { val.sv = new std::vector<std::string>(arg); } 00115 variant(const std::vector<std::string> &arg) : typev(STRINGVEC), shape_(1,arg.size()) 00116 { val.sv = new std::vector<std::string>(arg); } 00117 variant(std::vector<std::string> *arg) : typev(STRINGVEC), shape_(1, arg->size()) 00118 { val.sv = arg; } 00119 variant(std::vector<std::string> *arg, std::vector<int> &theshape) : typev(STRINGVEC), shape_(theshape) 00120 { val.sv = arg; } 00121 // 00122 variant(record &arg); 00123 variant(record *arg); 00124 00125 ~variant( ); 00126 00127 bool toBool( ) const; 00128 int toInt( ) const; 00129 double toDouble( ) const; 00130 std::complex<double> toComplex( ) const; 00131 std::string toString( bool no_brackets=false ) const; 00132 std::vector<bool> toBoolVec( ) const; 00133 std::vector<int> toIntVec( ) const; 00134 std::vector<double> toDoubleVec( ) const; 00135 std::vector<std::complex<double> > toComplexVec( ) const; 00136 std::vector<std::string> toStringVec( ) const; 00137 00138 // Yet to be implemented 00139 00140 // Modify 00141 // --------------------------------------------------- 00142 bool &asBool( ); 00143 int &asInt( ); 00144 double &asDouble( ); 00145 std::complex<double> &asComplex( ); 00146 std::string &asString( ); 00147 std::vector<int> &asIntVec( int size=-1 ); 00148 std::vector<bool> &asBoolVec( int size=-1 ); 00149 std::vector<double> &asDoubleVec( int size=-1 ); 00150 std::vector<std::complex<double> > &asComplexVec( int size=-1 ); 00151 std::vector<std::string> &asStringVec( int size=-1 ); 00152 record &asRecord( ); 00153 00154 void as( TYPE t, int size=-1 ); 00155 00156 // Const 00157 // --------------------------------------------------- 00158 const bool getBool( ) const throw(error); 00159 const int getInt( ) const throw(error); 00160 const double getDouble( ) const throw(error); 00161 const std::complex<double> &getComplex( ) const throw(error); 00162 const std::string &getString( ) const throw(error); 00163 const std::vector<int> &getIntVec( ) const throw(error); 00164 const std::vector<bool> &getBoolVec( ) const throw(error); 00165 const std::vector<double> &getDoubleVec( ) const throw(error); 00166 const std::vector<std::complex<double> > &getComplexVec( ) const throw(error); 00167 const std::vector<std::string> &getStringVec( ) const throw(error); 00168 const record &getRecord( ) const throw(error); 00169 const std::vector<int> &shape() const; 00170 const std::vector<int> &arrayshape() const {return shape();} 00171 00172 // Modify 00173 // --------------------------------------------------- 00174 bool &getBoolMod( ) throw(error); 00175 int &getIntMod( ) throw(error); 00176 double &getDoubleMod( ) throw(error); 00177 std::complex<double> &getComplexMod( ) throw(error); 00178 std::string &getStringMod( ) throw(error); 00179 std::vector<int> &getIntVecMod( ) throw(error); 00180 std::vector<bool> &getBoolVecMod( ) throw(error); 00181 std::vector<double> &getDoubleVecMod( ) throw(error); 00182 std::vector<std::complex<double> > &getComplexVecMod( ) throw(error); 00183 std::vector<std::string> &getStringVecMod( ) throw(error); 00184 record &getRecordMod( ) throw(error); 00185 std::vector<int> &shape(); 00186 std::vector<int> &arrayshape() {return shape();} 00187 00188 const std::string &typeString( ) const; 00189 const char *sig( ) const; 00190 TYPE type( ) const { return typev; } 00191 00192 void push(bool, bool conform = true); 00193 void push(int, bool conform = true); 00194 void push(double, bool conform = true); 00195 void push(std::complex<double>, bool conform = true); 00196 void push(const std::string&, bool conform = true); 00197 00198 void place(bool, unsigned int index, bool conform = true); 00199 void place(int, unsigned int index, bool conform = true); 00200 void place(double, unsigned int index, bool conform = true); 00201 void place(std::complex<double>, unsigned int index, bool conform = true); 00202 void place(const std::string&, unsigned int index, bool conform = true); 00203 00204 int size( ) const { return typev >= BOOLVEC ? vec_size() : 1; } 00205 void resize( int size ); 00206 00207 private: 00208 00209 // what size does the shape imply 00210 int shape_size( ) const; 00211 00212 // 4294967295 00213 static unsigned int record_id_count; 00214 00215 int vec_size( ) const; 00216 TYPE typev; 00217 union { 00218 bool b; 00219 std::vector<bool> *bv; 00220 int i; 00221 std::vector<int> *iv; 00222 double d; 00223 std::vector<double> *dv; 00224 std::complex<double> *c; 00225 std::vector<std::complex<double> > *cv; 00226 std::string *s; 00227 std::vector<std::string> *sv; 00228 record *recordv; 00229 } val; 00230 std::vector<int> shape_; 00231 00232 std::string create_message( const std::string s ) const; 00233 }; 00234 00235 } // dbus namespace 00236 } // casa namespace 00237 #endif