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