Line data Source code
1 : #ifndef __casac_variant_h__
2 : #define __casac_variant_h__
3 :
4 : #include <string>
5 : #include <vector>
6 : #include <complex>
7 :
8 : namespace casac {
9 :
10 : class record;
11 :
12 : class variant {
13 :
14 : public:
15 :
16 : enum TYPE { RECORD, BOOL, INT, UINT, DOUBLE, COMPLEX, STRING, BOOLVEC, INTVEC, UINTVEC, DOUBLEVEC, COMPLEXVEC, STRINGVEC };
17 :
18 : static TYPE compatible_type( TYPE one, TYPE two );
19 :
20 : class error {
21 : public:
22 : error( std::string msg ) : message_(msg) { }
23 : const std::string &message( ) const { return message_; }
24 : private:
25 : std::string message_;
26 : };
27 :
28 : class overflow : public error {
29 : public:
30 : overflow( std::string lbl ) : error(lbl + ": overflow error") { }
31 : };
32 :
33 : variant *clone() const { return new variant(*this); }
34 : int compare(const variant*) const;
35 :
36 : variant( );
37 : variant(const variant &);
38 :
39 0 : variant(bool arg) : typev(BOOL), shape_(1,1) { val.b = arg; }
40 938 : variant(long arg) : typev(INT), shape_(1,1) { val.i = arg; }
41 0 : variant(unsigned long arg) : typev(UINT), shape_(1,1) { val.ui = arg; }
42 39703 : variant(double arg) : typev(DOUBLE), shape_(1,1) { val.d = arg; }
43 0 : variant(std::complex<double> arg) : typev(COMPLEX) { val.c = new std::complex<double>(arg); }
44 0 : variant(const char *arg) : typev(STRING), shape_(1,1)
45 0 : { val.s = new std::string(arg); }
46 0 : variant(const std::string &arg) : typev(STRING), shape_(1,1)
47 0 : { val.s = new std::string(arg); }
48 : //
49 : variant(const std::vector<bool> &arg) : typev(BOOLVEC), shape_(1,arg.size())
50 : { val.bv = new std::vector<bool>(arg); }
51 29 : variant(const std::vector<bool> &arg, const std::vector<ssize_t> &theshape) : typev(BOOLVEC), shape_(theshape)
52 29 : { val.bv = new std::vector<bool>(arg); }
53 : variant(std::vector<bool> *arg) : typev(BOOLVEC), shape_(1,arg->size())
54 : { val.bv = arg; }
55 : variant(std::vector<bool> *arg, std::vector<ssize_t> &theshape) : typev(BOOLVEC), shape_(theshape)
56 : { val.bv = arg; }
57 : //
58 : variant(const std::vector<long> &arg) : typev(INTVEC), shape_(1,arg.size())
59 : { val.iv = new std::vector<long>(arg); }
60 19 : variant(const std::vector<long> &arg, const std::vector<ssize_t> &theshape) : typev(INTVEC), shape_(theshape)
61 19 : { val.iv = new std::vector<long>(arg); }
62 : variant(std::vector<long> *arg) : typev(INTVEC), shape_(1, arg->size())
63 : { val.iv = arg; }
64 : variant(std::vector<long> *arg, std::vector<ssize_t> &theshape) : typev(INTVEC), shape_(theshape)
65 : { val.iv = arg; }
66 :
67 : variant(const std::vector<unsigned long> &arg) : typev(UINTVEC), shape_(1,arg.size())
68 : { val.uiv = new std::vector<unsigned long>(arg); }
69 0 : variant(const std::vector<unsigned long> &arg, const std::vector<ssize_t> &theshape) : typev(UINTVEC), shape_(theshape)
70 0 : { val.uiv = new std::vector<unsigned long>(arg); }
71 : variant(std::vector<unsigned long> *arg) : typev(UINTVEC), shape_(1, arg->size())
72 : { val.uiv = arg; }
73 : variant(std::vector<unsigned long> *arg, std::vector<ssize_t> &theshape) : typev(UINTVEC), shape_(theshape)
74 : { val.uiv = arg; }
75 :
76 : //
77 : variant(const std::vector<double> &arg) : typev(DOUBLEVEC), shape_(1,arg.size())
78 : { val.dv = new std::vector<double>(arg); }
79 0 : variant(const std::vector<double> &arg, const std::vector<ssize_t> &theshape) : typev(DOUBLEVEC), shape_(theshape)
80 0 : { val.dv = new std::vector<double>(arg); }
81 : variant(std::vector<double> *arg) : typev(DOUBLEVEC), shape_(1,arg->size())
82 : { val.dv = arg; }
83 : variant(std::vector<double> *arg, std::vector<ssize_t> &theshape) : typev(DOUBLEVEC), shape_(theshape)
84 : { val.dv = arg; }
85 :
86 : variant(const std::vector<std::complex<double> > &arg) : typev(COMPLEXVEC), shape_(1, arg.size())
87 : { val.cv = new std::vector<std::complex<double> >(arg); }
88 0 : variant(const std::vector<std::complex<double> > &arg, const std::vector<ssize_t> &theshape) : typev(COMPLEXVEC), shape_(theshape)
89 0 : { val.cv = new std::vector<std::complex<double> >(arg); }
90 : variant(std::vector<std::complex<double> > *arg) : typev(COMPLEXVEC), shape_(1,arg->size())
91 : { val.cv = arg; }
92 : variant(std::vector<std::complex<double> > *arg, std::vector<ssize_t> &theshape) : typev(COMPLEXVEC), shape_(theshape)
93 : { val.cv = arg; }
94 : //
95 18 : variant(const std::vector<std::string> &arg, const std::vector<ssize_t> &theshape) : typev(STRINGVEC), shape_(theshape)
96 18 : { val.sv = new std::vector<std::string>(arg); }
97 : variant(const std::vector<std::string> &arg) : typev(STRINGVEC), shape_(1,arg.size())
98 : { val.sv = new std::vector<std::string>(arg); }
99 : variant(std::vector<std::string> *arg) : typev(STRINGVEC), shape_(1, arg->size())
100 : { val.sv = arg; }
101 : variant(std::vector<std::string> *arg, std::vector<ssize_t> &theshape) : typev(STRINGVEC), shape_(theshape)
102 : { val.sv = arg; }
103 : //
104 : variant(const record &arg);
105 : variant(record *arg);
106 :
107 : ~variant( );
108 :
109 : variant & operator= (const variant &other);
110 :
111 : bool toBool( ) const;
112 : long toInt( ) const;
113 : unsigned long touInt( ) const;
114 : double toDouble( ) const;
115 : std::complex<double> toComplex( ) const;
116 : std::string toString( bool no_brackets=false ) const;
117 : std::vector<bool> toBoolVec( ) const;
118 : std::vector<long> toIntVec( ) const;
119 : std::vector<unsigned long> touIntVec( ) const;
120 : std::vector<double> toDoubleVec( ) const;
121 : std::vector<std::complex<double> > toComplexVec( ) const;
122 : std::vector<std::string> toStringVec( ) const;
123 :
124 : // Yet to be implemented
125 :
126 : // Modify
127 : // ---------------------------------------------------
128 : bool &asBool( );
129 : long &asInt( );
130 : unsigned long &asuInt( );
131 : double &asDouble( );
132 : std::complex<double> &asComplex( );
133 : std::string &asString( );
134 : std::vector<long> &asIntVec( ssize_t size=-1 );
135 : std::vector<unsigned long> &asuIntVec( ssize_t size=-1 );
136 : std::vector<bool> &asBoolVec( ssize_t size=-1 );
137 : std::vector<double> &asDoubleVec( ssize_t size=-1 );
138 : std::vector<std::complex<double> > &asComplexVec( ssize_t size=-1 );
139 : std::vector<std::string> &asStringVec( ssize_t size=-1 );
140 : casac::record &asRecord( );
141 :
142 : void as( TYPE t, ssize_t size=-1 );
143 :
144 : // Const
145 : // ---------------------------------------------------
146 : bool getBool( ) const;
147 : long getInt( ) const;
148 : unsigned long getuInt( ) const;
149 : double getDouble( ) const;
150 : const std::complex<double> &getComplex( ) const;
151 : const std::string &getString( ) const;
152 : const std::vector<long> &getIntVec( ) const;
153 : const std::vector<unsigned long> &getuIntVec( ) const;
154 : const std::vector<bool> &getBoolVec( ) const;
155 : const std::vector<double> &getDoubleVec( ) const;
156 : const std::vector<std::complex<double> > &getComplexVec( ) const;
157 : const std::vector<std::string> &getStringVec( ) const;
158 : const record &getRecord( ) const;
159 : const std::vector<ssize_t> &shape() const;
160 240 : const std::vector<ssize_t> &arrayshape() const {return shape();}
161 :
162 : // Modify
163 : // ---------------------------------------------------
164 : bool &getBoolMod( );
165 : long &getIntMod( );
166 : unsigned long &getuIntMod( );
167 : double &getDoubleMod( );
168 : std::complex<double> &getComplexMod( );
169 : std::string &getStringMod( );
170 : std::vector<long> &getIntVecMod( );
171 : std::vector<unsigned long> &getuIntVecMod( );
172 : std::vector<bool> &getBoolVecMod( );
173 : std::vector<double> &getDoubleVecMod( );
174 : std::vector<std::complex<double> > &getComplexVecMod( );
175 : std::vector<std::string> &getStringVecMod( );
176 : record &getRecordMod( );
177 : std::vector<ssize_t> &shape();
178 : std::vector<ssize_t> &arrayshape() {return shape();}
179 :
180 : const std::string &typeString( ) const;
181 11633 : TYPE type( ) const { return typev; }
182 :
183 : void push(bool, bool conform = true);
184 : void push(long, bool conform = true);
185 : void push(unsigned long, bool conform = true);
186 : void push(long long, bool conform = true);
187 : void push(double, bool conform = true);
188 : void push(std::vector<long long>, bool conform = true);
189 : void push(std::complex<double>, bool conform = true);
190 : void push(const std::string&, bool conform = true);
191 : void push(const char*, bool conform = true);
192 :
193 : void place(bool, unsigned int index, bool conform = true);
194 : void place(long, unsigned int index, bool conform = true);
195 : void place(unsigned long, unsigned int index, bool conform = true);
196 : void place(long long, unsigned int index, bool conform = true);
197 : void place(double, unsigned int index, bool conform = true);
198 : void place(std::vector<long long>, unsigned int index, bool conform = true);
199 : void place(std::complex<double>, unsigned int index, bool conform = true);
200 : void place(const std::string&, unsigned int index, bool conform = true);
201 : void place(const char*, unsigned int index, bool conform = true);
202 :
203 0 : ssize_t size( ) const { return typev >= BOOLVEC ? vec_size() : 1; }
204 : void resize( ssize_t size );
205 :
206 : // return true if empty string, empty record, or size 0 vector.
207 : // always returns false if object is a non-array bool or numerical type
208 : bool empty() const;
209 :
210 : private:
211 :
212 : void freeStorage ();
213 :
214 : // what size does the shape imply
215 : ssize_t shape_size( ) const;
216 :
217 : // 4294967295
218 : static unsigned int record_id_count;
219 :
220 : ssize_t vec_size( ) const;
221 : TYPE typev;
222 : union {
223 : bool b;
224 : std::vector<bool> *bv;
225 : long i;
226 : unsigned long ui;
227 : std::vector<long> *iv;
228 : std::vector<unsigned long> *uiv;
229 : double d;
230 : std::vector<double> *dv;
231 : std::complex<double> *c;
232 : std::vector<std::complex<double> > *cv;
233 : std::string *s;
234 : std::vector<std::string> *sv;
235 : record *recordv;
236 : } val;
237 : std::vector<ssize_t> shape_;
238 :
239 : std::string create_message( const std::string s ) const;
240 : };
241 :
242 : variant initialize_variant( const std::string & );
243 : } // casac namespace
244 :
245 : #endif
|