Line data Source code
1 : #include <casacore/casa/Exceptions/Error.h>
2 :
3 : #include <cstdlib>
4 : #include <stdcasa/variant.h>
5 : #include <stdcasa/record.h>
6 : #include <cstring>
7 : #include <iostream>
8 :
9 : using namespace casacore;
10 : namespace casac {
11 :
12 : typedef std::string std_string;
13 :
14 : unsigned int variant::record_id_count = 0;
15 :
16 40 : variant::variant( ) : typev(BOOLVEC), shape_(1,0) {
17 40 : val.bv = new std::vector<bool>( );
18 40 : }
19 :
20 0 : const std::vector<ssize_t> &variant::shape() const {
21 0 : if ( typev == RECORD && (shape_.size() != 1 || (int) val.recordv->size() != shape_[0]) )
22 0 : ((variant*)this)->shape_ = std::vector<ssize_t>(1,val.recordv->size());
23 0 : return shape_;
24 : }
25 0 : std::vector<ssize_t> &variant::shape() {
26 0 : if ( typev == RECORD && (shape_.size() != 1 || (int) val.recordv->size() != shape_[0]) )
27 0 : shape_ = std::vector<ssize_t>(1,val.recordv->size());
28 0 : return shape_;
29 : }
30 :
31 0 : int variant::compare(const variant*) const { return -1; }
32 :
33 0 : variant::TYPE variant::compatible_type( TYPE one_, TYPE two_ ) {
34 0 : TYPE one = one_;
35 0 : TYPE two = two_;
36 :
37 : // VEC has priority
38 0 : if ( one >= BOOLVEC || two >= BOOLVEC ) {
39 0 : if ( one < BOOLVEC ) {
40 0 : switch (one) {
41 0 : case BOOL: one = BOOLVEC; break;
42 0 : case INT: one = INTVEC; break;
43 0 : case UINT: one = UINTVEC; break;
44 0 : case DOUBLE: one = DOUBLEVEC; break;
45 0 : case COMPLEX: one = COMPLEXVEC; break;
46 0 : case STRING:
47 0 : default: one = STRINGVEC; break;
48 : }
49 0 : } else if ( two < BOOLVEC ) {
50 0 : switch (two) {
51 0 : case BOOL: two = BOOLVEC; break;
52 0 : case INT: two = INTVEC; break;
53 0 : case UINT: two = UINTVEC; break;
54 0 : case DOUBLE: two = DOUBLEVEC; break;
55 0 : case COMPLEX: two = COMPLEXVEC; break;
56 0 : default: two = STRINGVEC; break;
57 : }
58 : }
59 :
60 0 : switch(one) {
61 0 : case BOOLVEC: return two;
62 0 : case INTVEC: return two == BOOLVEC ? INTVEC : two;
63 0 : case UINTVEC: return two == BOOLVEC ? UINTVEC : two;
64 0 : case DOUBLEVEC: return two == COMPLEXVEC || two == STRINGVEC ? two : DOUBLEVEC;
65 0 : case COMPLEXVEC: return two == STRINGVEC ? STRINGVEC : COMPLEXVEC;
66 0 : default: return STRINGVEC;
67 : }
68 : } else {
69 0 : switch(one) {
70 0 : case BOOL: return two;
71 0 : case INT: return two == BOOL ? INT : two;
72 0 : case UINT: return two == BOOL ? UINT : two;
73 0 : case DOUBLE: return two == COMPLEX || two == STRING ? two : DOUBLE;
74 0 : case COMPLEX: return two == STRING ? STRING : COMPLEX;
75 0 : default: return STRING;
76 : }
77 : }
78 : }
79 :
80 : #include "string_conversions.hpp"
81 :
82 0 : variant::variant(const record &arg) : typev(RECORD), shape_(1,arg.size()) {
83 0 : val.recordv = new record(arg);
84 0 : }
85 :
86 0 : variant::variant(record *arg) : typev(RECORD), shape_(1,arg->size()) {
87 0 : val.recordv = arg;
88 0 : }
89 :
90 73 : variant::variant(const variant &other){
91 :
92 73 : typev = INT; // need to make it something easy for the assignment operator.
93 :
94 73 : * this = other;
95 73 : }
96 :
97 : variant &
98 73 : variant::operator= (const variant &other){
99 :
100 73 : if (& other == this){
101 0 : return * this;
102 : }
103 :
104 73 : freeStorage (); // uses current typev for this
105 :
106 73 : typev = other.typev;
107 73 : shape_ = other.shape_;
108 :
109 73 : switch( typev ) {
110 :
111 0 : case BOOL:
112 0 : val.b = other.val.b;
113 0 : break;
114 0 : case INT:
115 0 : val.i = other.val.i;
116 0 : break;
117 :
118 0 : case UINT:
119 0 : val.ui = other.val.ui;
120 0 : break;
121 21 : case DOUBLE:
122 21 : val.d = other.val.d;
123 21 : break;
124 0 : case COMPLEX:
125 0 : val.c = new std::complex<double>(*other.val.c);
126 0 : break;
127 0 : case BOOLVEC:
128 0 : val.bv = new std::vector<bool>(*other.val.bv);
129 0 : break;
130 0 : case INTVEC:
131 0 : val.iv = new std::vector<long>(*other.val.iv);
132 0 : break;
133 0 : case UINTVEC:
134 0 : val.uiv = new std::vector<unsigned long>(*other.val.uiv);
135 0 : break;
136 0 : case DOUBLEVEC:
137 0 : val.dv = new std::vector<double>(*other.val.dv);
138 0 : break;
139 0 : case COMPLEXVEC:
140 0 : val.cv = new std::vector<std::complex<double> >(*other.val.cv);
141 0 : break;
142 21 : case STRING:
143 21 : val.s = new std::string(*other.val.s);
144 21 : break;
145 0 : case STRINGVEC:
146 0 : val.sv = new std::vector<std::string>(*other.val.sv);
147 0 : break;
148 31 : case RECORD:
149 31 : val.recordv = new record(*other.val.recordv);
150 31 : break;
151 0 : default:
152 0 : typev = BOOL;
153 0 : val.b = false;
154 0 : break;
155 : }
156 :
157 73 : return * this;
158 : }
159 :
160 : void
161 208 : variant::freeStorage ()
162 : {
163 208 : switch( typev ) {
164 11 : case BOOLVEC:
165 11 : delete val.bv;
166 11 : break;
167 0 : case INTVEC:
168 0 : delete val.iv;
169 0 : break;
170 0 : case UINTVEC:
171 0 : delete val.uiv;
172 0 : break;
173 0 : case DOUBLEVEC:
174 0 : delete val.dv;
175 0 : break;
176 0 : case COMPLEX:
177 0 : delete val.c;
178 0 : break;
179 0 : case COMPLEXVEC:
180 0 : delete val.cv;
181 0 : break;
182 34 : case STRING:
183 34 : delete val.s;
184 34 : break;
185 0 : case STRINGVEC:
186 0 : delete val.sv;
187 0 : break;
188 60 : case RECORD:
189 60 : delete val.recordv;
190 60 : break;
191 103 : default:
192 103 : break;
193 : }
194 208 : }
195 :
196 135 : variant::~variant( ) {
197 :
198 135 : freeStorage ();
199 135 : }
200 :
201 0 : const std::string &variant::typeString( ) const {
202 0 : static std::string bs("bool");
203 0 : static std::string bvs("boolvec");
204 0 : static std::string is("int");
205 0 : static std::string uis("uint");
206 0 : static std::string ivs("intvec");
207 0 : static std::string uivs("uintvec");
208 0 : static std::string ls("long");
209 0 : static std::string lvs("longvec");
210 0 : static std::string ds("double");
211 0 : static std::string dvs("doublevec");
212 0 : static std::string cs("complex");
213 0 : static std::string cvs("complexvec");
214 0 : static std::string ss("string");
215 0 : static std::string svs("stringvec");
216 0 : static std::string rec("record");
217 0 : static std::string unknown("unknown");
218 :
219 0 : switch( typev ) {
220 0 : case BOOL: return bs;
221 0 : case BOOLVEC: return bvs;
222 0 : case INT: return is;
223 0 : case UINT: return uis;
224 0 : case INTVEC: return ivs;
225 0 : case UINTVEC: return uivs;
226 0 : case DOUBLE: return ds;
227 0 : case DOUBLEVEC: return dvs;
228 0 : case COMPLEX: return cs;
229 0 : case COMPLEXVEC: return cvs;
230 0 : case STRING: return ss;
231 0 : case STRINGVEC: return svs;
232 0 : case RECORD: return rec;
233 0 : default: return unknown;
234 : }
235 : }
236 :
237 0 : bool variant::toBool( ) const {
238 0 : switch( typev ) {
239 0 : case BOOL:
240 0 : return val.b;
241 0 : case BOOLVEC:
242 0 : return (*val.bv).size() > 0 ? (*val.bv)[0] : false;
243 0 : case INT:
244 0 : return val.i ? true : false;
245 0 : case UINT:
246 0 : return val.ui ? true : false;
247 0 : case INTVEC:
248 0 : return (*val.iv).size() > 0 ? ((*val.iv)[0] ? true : false) : false;
249 0 : case UINTVEC:
250 0 : return (*val.uiv).size() > 0 ? ((*val.uiv)[0] ? true : false) : false;
251 0 : case DOUBLE:
252 0 : return val.d != 0.0 ? true : false;
253 0 : case DOUBLEVEC:
254 0 : return (*val.dv).size() > 0 ? ((*val.dv)[0] != 0.0 ? true : false) : false;
255 0 : case COMPLEX:
256 0 : return ((*val.c).real() != 0.0 || (*val.c).imag() != 0.0) ? true : false;
257 0 : case COMPLEXVEC:
258 0 : return (*val.cv).size() > 0 ? (((*val.cv)[0].real() != 0.0 || (*val.cv)[0].imag() != 0.0) ? true : false) : false;
259 0 : case STRING:
260 0 : return stringtobool( *val.s );
261 0 : case STRINGVEC:
262 0 : return (*val.sv).size() > 0 ? stringtobool((*val.sv)[0]) : false;
263 0 : case RECORD:
264 : default:
265 0 : return false;
266 : }
267 : }
268 :
269 0 : std::vector<bool> variant::toBoolVec( ) const {
270 0 : switch( typev ) {
271 0 : case BOOL:
272 0 : return std::vector<bool>(1,val.b);
273 0 : case INT:
274 0 : return std::vector<bool>(1, val.i != 0 ? true : false);
275 0 : case UINT:
276 0 : return std::vector<bool>(1, val.ui != 0 ? true : false);
277 0 : case DOUBLE:
278 0 : return std::vector<bool>(1, val.d != 0.0 ? true : false);
279 0 : case COMPLEX:
280 0 : return std::vector<bool>(1, ((*val.c).real() != 0.0 || (*val.c).imag() != 0.0) ? true : false);
281 0 : case BOOLVEC:
282 0 : return std::vector<bool>(*val.bv);
283 0 : case INTVEC:
284 : {
285 0 : std::vector<bool> result((*val.iv).size());
286 0 : std::vector<long>::const_iterator from = (*val.iv).begin();
287 0 : for (unsigned int i=0; from != (*val.iv).end(); ++i, ++from)
288 0 : result[i] = *from != 0 ? true : false;
289 0 : return result;
290 0 : }
291 0 : case UINTVEC:
292 : {
293 0 : std::vector<bool> result((*val.uiv).size());
294 0 : std::vector<unsigned long>::const_iterator from = (*val.uiv).begin();
295 0 : for (unsigned int i=0; from != (*val.uiv).end(); ++i, ++from)
296 0 : result[i] = *from != 0 ? true : false;
297 0 : return result;
298 0 : }
299 0 : case DOUBLEVEC:
300 : {
301 0 : std::vector<bool> result((*val.dv).size());
302 0 : std::vector<double>::const_iterator from = (*val.dv).begin();
303 0 : for (unsigned int i=0; from != (*val.dv).end(); ++i, ++from)
304 0 : result[i] = *from != 0.0 ? true : false;
305 0 : return result;
306 0 : }
307 0 : case COMPLEXVEC:
308 : {
309 0 : std::vector<bool> result((*val.dv).size());
310 0 : std::vector<std::complex<double> >::const_iterator from = (*val.cv).begin();
311 0 : for (unsigned int i=0; from != (*val.cv).end(); ++i, ++from) {
312 0 : const std::complex<double> &cpx = *from;
313 0 : result[i] = (cpx.real() != 0.0 || cpx.imag() != 0.0) ? true : false;
314 : }
315 0 : return result;
316 0 : }
317 0 : case STRING:
318 0 : return std::vector<bool>(1,stringtobool( *val.s ));
319 0 : case STRINGVEC:
320 : {
321 0 : std::vector<bool> result((*val.sv).size());
322 0 : std::vector<std::string>::const_iterator from = (*val.sv).begin();
323 0 : for (unsigned int i=0; from != (*val.sv).end(); ++i, ++from)
324 0 : result[i] = stringtobool(*from);
325 0 : return result;
326 0 : }
327 0 : case RECORD:
328 : default:
329 0 : return std::vector<bool>(0);
330 : }
331 : }
332 :
333 : #define VECTOSTRING_CONVERSION(TYPE,IDTYPE,OPEN,CLOSE,DIVIDE,INVAR,OUTVAR,EMPTY) \
334 : if (INVAR.size() > 1) { \
335 : OUTVAR = OPEN; \
336 : std::vector<TYPE>::const_iterator from = INVAR.begin(); \
337 : OUTVAR += IDTYPE ## tostring(*from++); \
338 : while (from != INVAR.end()) \
339 : OUTVAR += DIVIDE + IDTYPE ## tostring(*from++); \
340 : OUTVAR += CLOSE; \
341 : } else if (INVAR.size() == 1) { \
342 : OUTVAR = OPEN + IDTYPE ## tostring(INVAR[0]) + CLOSE; \
343 : } else { \
344 : OUTVAR = EMPTY; \
345 : } \
346 :
347 : #define VECTOSTRING(TYPE,IDTYPE,MEM,SUBMEM,OPEN,CLOSE,DIVIDE,EMPTY) \
348 : { \
349 : std::string result; \
350 : VECTOSTRING_CONVERSION(TYPE,IDTYPE,OPEN,CLOSE,DIVIDE,(*val.MEM) SUBMEM,result,EMPTY) \
351 : return result; \
352 : }
353 : #define VECASSTRING(TYPE,IDTYPE,MEM,SUBMEM,OPEN,CLOSE,DIVIDE,EMPTY) \
354 : { \
355 : std::string *tmp = new std::string(); \
356 : VECTOSTRING_CONVERSION(TYPE,IDTYPE,OPEN,CLOSE,DIVIDE,(*val.MEM) SUBMEM,(*tmp),EMPTY) \
357 : delete val.MEM; \
358 : val.s = tmp; \
359 : break; \
360 : }
361 :
362 : #define VECTOSTRINGVEC(TYPE,IDTYPE,MEM,SUBMEM) \
363 : { \
364 : std::vector<std::string> result; \
365 : std::vector<TYPE>::const_iterator from = (*val.MEM) SUBMEM .begin(); \
366 : for (unsigned int i=0; from != (*val.MEM) SUBMEM .end(); ++i, ++from) \
367 : result[i] = IDTYPE ## tostring(*from); \
368 : return result; \
369 : }
370 :
371 : #define VECASSTRINGVEC(TYPE,IDTYPE,MEM,SUBMEM,OPEN,CLOSE) \
372 : { \
373 : ssize_t current_size = (*val.MEM) SUBMEM .size(); \
374 : newsize = size > current_size ? size : current_size; \
375 : std::vector<std::string> *tmp = new std::vector<std::string>(newsize); \
376 : std::vector<TYPE>::const_iterator from = (*val.MEM) SUBMEM .begin(); \
377 : for (unsigned int i=0; from != (*val.MEM) SUBMEM .end(); ++i, ++from) \
378 : (*tmp)[i] = OPEN IDTYPE ## tostring(*from) CLOSE; \
379 : delete val.MEM; \
380 : val.sv = tmp; \
381 : break; \
382 : }
383 :
384 15 : std::string variant::toString( bool no_brackets ) const {
385 15 : switch( typev ) {
386 0 : case BOOL:
387 0 : return booltostring(val.b);
388 0 : case INT:
389 0 : return inttostring(val.i);
390 0 : case UINT:
391 0 : return inttostring(val.ui);
392 0 : case DOUBLE:
393 0 : return doubletostring(val.d);
394 0 : case COMPLEX:
395 0 : return complextostring(*val.c);
396 0 : case BOOLVEC:
397 0 : VECTOSTRING(bool,bool,bv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
398 0 : case INTVEC:
399 0 : VECTOSTRING(long,int,iv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
400 0 : case UINTVEC:
401 0 : VECTOSTRING(unsigned long,int,uiv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
402 0 : case DOUBLEVEC:
403 0 : VECTOSTRING(double,double,dv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
404 0 : case COMPLEXVEC:
405 0 : VECTOSTRING(std::complex<double>,complex,cv,,(no_brackets?"":"["),(no_brackets?"":"]"),",",(no_brackets?"":"[]"))
406 15 : case STRING:
407 15 : return std::string( *val.s );
408 0 : case STRINGVEC:
409 0 : VECTOSTRING(std_string,std_string,sv,,(no_brackets?"\"":"[\""),(no_brackets?"\"":"\"]"),"\",\"",(no_brackets?"":"[]"))
410 0 : case RECORD:
411 0 : return std::string("{...}");
412 0 : default:
413 0 : return std::string("");
414 : }
415 : }
416 :
417 0 : std::vector<std::string> variant::toStringVec( ) const {
418 0 : switch( typev ) {
419 0 : case BOOL:
420 0 : return std::vector<std::string>(1,booltostring(val.b));
421 0 : case INT:
422 0 : return std::vector<std::string>(1,inttostring(val.i));
423 0 : case UINT:
424 0 : return std::vector<std::string>(1,inttostring(val.ui));
425 0 : case DOUBLE:
426 0 : return std::vector<std::string>(1,doubletostring(val.d));
427 0 : case COMPLEX:
428 0 : return std::vector<std::string>(1,complextostring(*val.c));
429 0 : case BOOLVEC:
430 0 : VECTOSTRINGVEC(bool,bool,bv,)
431 0 : case INTVEC:
432 0 : VECTOSTRINGVEC(long,int,iv,)
433 0 : case UINTVEC:
434 0 : VECTOSTRINGVEC(unsigned long,int,uiv,)
435 0 : case DOUBLEVEC:
436 0 : VECTOSTRINGVEC(double,double,dv,)
437 0 : case COMPLEXVEC:
438 0 : VECTOSTRINGVEC(std::complex<double>,complex,cv,)
439 0 : case STRING:
440 0 : return std::vector<std::string>(1,*val.s);
441 0 : case STRINGVEC:
442 0 : return std::vector<std::string>(*val.sv);
443 0 : case RECORD:
444 0 : return std::vector<std::string>(1,"{...}");
445 0 : default:
446 0 : return std::vector<std::string>(0);
447 : }
448 : }
449 :
450 :
451 : #define TONUMERIC( NAME, TYPE, IDTYPE ) \
452 : TYPE variant::NAME( ) const { \
453 : switch( typev ) { \
454 : case BOOL: \
455 : return (TYPE) (val.b ? 1 : 0); \
456 : case INT: \
457 : return (TYPE) val.i; \
458 : case UINT: \
459 : return (TYPE) val.ui; \
460 : case DOUBLE: \
461 : return (TYPE) val.d; \
462 : case COMPLEX: \
463 : return (TYPE) (*val.c).real(); \
464 : case BOOLVEC: \
465 : return (TYPE) ((*val.bv).size() > 0 ? ((*val.bv)[0] ? 1 : 0) : 0); \
466 : case INTVEC: \
467 : return (TYPE) ((*val.iv).size() > 0 ? (*val.iv)[0] : 0); \
468 : case UINTVEC: \
469 : return (TYPE) ((*val.uiv).size() > 0 ? (*val.uiv)[0] : 0); \
470 : case DOUBLEVEC: \
471 : return (TYPE) ((*val.dv).size() > 0 ? (*val.dv)[0] : 0); \
472 : case COMPLEXVEC: \
473 : return (TYPE) ((*val.cv).size() > 0 ? (*val.cv)[0].real() : 0); \
474 : case STRING: \
475 : return stringto ## IDTYPE( *val.s ); \
476 : case STRINGVEC: \
477 : return (*val.sv).size() > 0 ? stringto ## IDTYPE((*val.sv)[0]) : 0; \
478 : case RECORD: \
479 : default: \
480 : return (TYPE) 0; \
481 : } \
482 : }
483 :
484 0 : TONUMERIC(toInt,long,int)
485 0 : TONUMERIC(touInt,unsigned long,uInt)
486 8 : TONUMERIC(toDouble,double,double)
487 :
488 0 : std::complex<double> variant::toComplex( ) const {
489 0 : switch( typev ) {
490 0 : case BOOL:
491 0 : return std::complex<double>(val.b ? 1.0 : 0.0, 0.0);
492 0 : case INT:
493 0 : return std::complex<double>(val.i, 0.0);
494 0 : case UINT:
495 0 : return std::complex<double>(val.ui, 0.0);
496 0 : case DOUBLE:
497 0 : return std::complex<double>(val.d, 0.0);
498 0 : case COMPLEX:
499 0 : return std::complex<double>(*val.c);
500 0 : case BOOLVEC:
501 0 : return std::complex<double>(((*val.bv).size() > 0 ? ((*val.bv)[0] ? 1.0 : 0.0) : 0.0),0.0);;
502 0 : case INTVEC:
503 0 : return std::complex<double>(((*val.iv).size() > 0 ? (*val.iv)[0] : 0),0.0);
504 0 : case UINTVEC:
505 0 : return std::complex<double>(((*val.uiv).size() > 0 ? (*val.uiv)[0] : 0),0.0);
506 0 : case DOUBLEVEC:
507 0 : return std::complex<double>(((*val.dv).size() > 0 ? (*val.dv)[0] : 0),0);
508 0 : case COMPLEXVEC:
509 0 : return (*val.cv).size() > 0 ? std::complex<double>((*val.cv)[0]) : std::complex<double>(0.0,0.0);
510 0 : case STRING:
511 0 : return stringtocomplex( *val.s );
512 0 : case STRINGVEC:
513 0 : return (*val.sv).size() > 0 ? stringtocomplex((*val.sv)[0]) : 0;
514 0 : case RECORD:
515 : default:
516 0 : return std::complex<double>( 0.0, 0.0 );
517 : }
518 : }
519 :
520 :
521 : #define TONUMERICVEC( NAME, TYPE, IDTYPE, TYPET, TYPEM, ONE, ONET, ONEM ) \
522 : std::vector<TYPE> variant::NAME( ) const { \
523 : switch( typev ) { \
524 : case BOOL: \
525 : return std::vector<TYPE>(1,(TYPE)(val.b ? 1 : 0)); \
526 : case INT: \
527 : return std::vector<TYPE>(1,(TYPE) val.i); \
528 : case UINT: \
529 : return std::vector<TYPE>(1,(TYPE) val.ui); \
530 : case DOUBLE: \
531 : return std::vector<TYPE>(1,(TYPE) val.d); \
532 : case COMPLEX: \
533 : return std::vector<TYPE>(1,(TYPE) (*val.c).real()); \
534 : case BOOLVEC: \
535 : { \
536 : std::vector<TYPE> result((*val.bv).size()); \
537 : std::vector<bool>::const_iterator from = (*val.bv).begin(); \
538 : for (unsigned int i=0; from != (*val.bv).end(); ++i, ++from) \
539 : result[i] = (TYPE)(*from ? 1 : 0); \
540 : return result; \
541 : } \
542 : case TYPET: \
543 : return std::vector<TYPE>(*val.TYPEM); \
544 : case ONET: \
545 : { \
546 : std::vector<TYPE> result((*val.ONEM).size()); \
547 : std::vector<ONE>::const_iterator from = (*val.ONEM).begin(); \
548 : for (unsigned int i=0; from != (*val.ONEM).end(); ++i, ++from) \
549 : result[i] = (TYPE)(*from); \
550 : return result; \
551 : } \
552 : case COMPLEXVEC: \
553 : { \
554 : std::vector<TYPE> result((*val.cv).size()); \
555 : std::vector<std::complex<double> >::const_iterator from = (*val.cv).begin();\
556 : for (unsigned int i=0; from != (*val.cv).end(); ++i, ++from) \
557 : result[i] = (TYPE)((*from).real()); \
558 : return result; \
559 : } \
560 : case STRING: \
561 : return std::vector<TYPE>(1,stringto ## IDTYPE( *val.s )); \
562 : case STRINGVEC: \
563 : { \
564 : std::vector<TYPE> result((*val.sv).size()); \
565 : std::vector<std::string>::const_iterator from = (*val.sv).begin(); \
566 : for (unsigned int i=0; from != (*val.sv).end(); ++i, ++from) \
567 : result[i] = stringto ## IDTYPE(*from); \
568 : return result; \
569 : } \
570 : case RECORD: \
571 : default: \
572 : return std::vector<TYPE>(0); \
573 : } \
574 : }
575 :
576 :
577 :
578 0 : TONUMERICVEC(toIntVec, long, int, INTVEC, iv,double,DOUBLEVEC,dv)
579 0 : TONUMERICVEC(toDoubleVec,double,double,DOUBLEVEC,dv,long, INTVEC, iv)
580 :
581 0 : std::vector<unsigned long> variant::touIntVec() const {
582 0 : return std::vector<unsigned long>(1,(unsigned long) val.ui);
583 : }
584 :
585 0 : std::vector<std::complex<double> > variant::toComplexVec( ) const {
586 0 : switch( typev ) {
587 0 : case BOOL:
588 0 : return std::vector<std::complex<double> >(1,std::complex<double>((val.b ? 1 : 0),0.0));
589 0 : case INT:
590 0 : return std::vector<std::complex<double> >(1,std::complex<double>(val.i,0.0));
591 0 : case UINT:
592 0 : return std::vector<std::complex<double> >(1,std::complex<double>(val.ui,0.0));
593 0 : case DOUBLE:
594 0 : return std::vector<std::complex<double> >(1,std::complex<double>(val.d,0.0));
595 0 : case COMPLEX:
596 0 : return std::vector<std::complex<double> >(1,*val.c);
597 0 : case BOOLVEC:
598 : {
599 0 : std::vector<std::complex<double> > result((*val.bv).size());
600 0 : std::vector<bool>::const_iterator from = (*val.bv).begin();
601 0 : for (unsigned int i=0; from != (*val.bv).end(); ++i, ++from)
602 0 : result[i] = std::complex<double>((*from ? 1 : 0),0.0);
603 0 : return result;
604 0 : }
605 0 : case COMPLEXVEC:
606 0 : return std::vector<std::complex<double> >(*val.cv);
607 0 : case INTVEC:
608 : {
609 0 : std::vector<std::complex<double> > result((*val.iv).size());
610 0 : std::vector<long>::const_iterator from = (*val.iv).begin();
611 0 : for (unsigned int i=0; from != (*val.iv).end(); ++i, ++from)
612 0 : result[i] = std::complex<double>(*from,0.0);
613 0 : return result;
614 0 : }
615 0 : case UINTVEC:
616 : {
617 0 : std::vector<std::complex<double> > result((*val.uiv).size());
618 0 : std::vector<unsigned long>::const_iterator from = (*val.uiv).begin();
619 0 : for (unsigned int i=0; from != (*val.uiv).end(); ++i, ++from)
620 0 : result[i] = std::complex<double>(*from,0.0);
621 0 : return result;
622 0 : }
623 0 : case DOUBLEVEC:
624 : {
625 0 : std::vector<std::complex<double> > result((*val.dv).size());
626 0 : std::vector<double>::const_iterator from = (*val.dv).begin();
627 0 : for (unsigned int i=0; from != (*val.dv).end(); ++i, ++from)
628 0 : result[i] = std::complex<double>(*from,0.0);
629 0 : return result;
630 0 : }
631 0 : case STRING:
632 0 : return std::vector<std::complex<double> >(1,stringtocomplex( *val.s ));
633 0 : case STRINGVEC:
634 : {
635 0 : std::vector<std::complex<double> > result((*val.sv).size());
636 0 : std::vector<std::string>::const_iterator from = (*val.sv).begin();
637 0 : for(unsigned int i=0; from != (*val.sv).end(); ++i, ++from)
638 0 : result[i] = stringtocomplex(*from);
639 0 : return result;
640 0 : }
641 0 : case RECORD:
642 : default:
643 0 : return std::vector<std::complex<double> >(0);
644 : }
645 : }
646 :
647 : // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
648 : #define ASNUMERIC( NAME, TYPE, IDTYPE, TYPETAG, VAL ) \
649 : TYPE &variant::NAME( ) { \
650 : if ( typev != TYPETAG ) { \
651 : switch( typev ) { \
652 : case BOOL: \
653 : val.VAL = (TYPE) (val.b ? 1 : 0); \
654 : break; \
655 : case INT: \
656 : val.VAL = (TYPE) val.i; \
657 : break; \
658 : case UINT: \
659 : val.VAL = (TYPE) val.ui; \
660 : break; \
661 : case DOUBLE: \
662 : val.VAL = (TYPE) val.d; \
663 : break; \
664 : case COMPLEX: \
665 : { \
666 : std::complex<double> *tmp = val.c; \
667 : val.VAL = (TYPE) (*tmp).real(); \
668 : delete tmp; \
669 : break; \
670 : } \
671 : case BOOLVEC: \
672 : { \
673 : std::vector<bool> *tmp = val.bv; \
674 : val.VAL = (TYPE) ((*tmp).size() > 0 ? ((*tmp)[0] ? 1 : 0) : 0); \
675 : delete tmp; \
676 : break; \
677 : } \
678 : case INTVEC: \
679 : { \
680 : std::vector<long> *tmp = val.iv; \
681 : val.VAL = (TYPE) ((*tmp).size() > 0 ? (*tmp)[0] : 0); \
682 : delete tmp; \
683 : break; \
684 : } \
685 : case UINTVEC: \
686 : { \
687 : std::vector<unsigned long> *tmp = val.uiv; \
688 : val.VAL = (TYPE) ((*tmp).size() > 0 ? (*tmp)[0] : 0); \
689 : delete tmp; \
690 : break; \
691 : } \
692 : case DOUBLEVEC: \
693 : { \
694 : std::vector<double> *tmp = val.dv; \
695 : val.VAL = (TYPE) ((*tmp).size() > 0 ? (*tmp)[0] : 0); \
696 : delete tmp; \
697 : break; \
698 : } \
699 : case COMPLEXVEC: \
700 : { \
701 : std::vector<std::complex<double> > *tmp = val.cv; \
702 : val.VAL = (TYPE) ((*tmp).size() > 0 ? (*tmp)[0].real() : 0); \
703 : delete tmp; \
704 : break; \
705 : } \
706 : case STRING: \
707 : { \
708 : std::string *tmp = val.s; \
709 : val.VAL = stringto ## IDTYPE( *tmp ); \
710 : delete tmp; \
711 : break; \
712 : } \
713 : case STRINGVEC: \
714 : { \
715 : std::vector<std::string> *tmp = val.sv; \
716 : val.VAL = (*tmp).size() > 0 ? stringto ## IDTYPE((*tmp)[0]) : 0;\
717 : delete tmp; \
718 : break; \
719 : } \
720 : case RECORD: \
721 : delete val.recordv; \
722 : default: \
723 : val.VAL = (TYPE) 0; \
724 : break; \
725 : } \
726 : \
727 : typev = TYPETAG; \
728 : shape_ = std::vector<ssize_t>(1,1); \
729 : \
730 : } \
731 : \
732 : return val.VAL; \
733 : }
734 :
735 0 : ASNUMERIC(asInt,long,int,INT,i)
736 0 : ASNUMERIC(asuInt,unsigned long,uInt,UINT,ui)
737 0 : ASNUMERIC(asDouble,double,double,DOUBLE,d)
738 :
739 :
740 0 : std::complex<double> &variant::asComplex( ) {
741 0 : if ( typev != COMPLEX ) {
742 0 : switch( typev ) {
743 0 : case BOOL:
744 0 : val.c = new std::complex<double>(val.b ? 1 : 0,0.0);
745 0 : break;
746 0 : case INT:
747 0 : val.c = new std::complex<double>(val.i,0.0);
748 0 : break;
749 0 : case UINT:
750 0 : val.c = new std::complex<double>(val.ui,0.0);
751 0 : break;
752 0 : case DOUBLE:
753 0 : val.c = new std::complex<double>(val.d,0.0);
754 0 : break;
755 0 : case COMPLEX:
756 0 : break;
757 0 : case BOOLVEC:
758 : {
759 0 : std::vector<bool> *tmp = val.bv;
760 0 : val.c = new std::complex<double>((*tmp).size() > 0 ? ((*tmp)[0] ? 1 : 0) : 0,0.0);
761 0 : delete tmp;
762 0 : break;
763 : }
764 0 : case INTVEC:
765 : {
766 0 : std::vector<long> *tmp = val.iv;
767 0 : val.c = new std::complex<double>((*tmp).size() > 0 ? (*tmp)[0] : 0,0.0);
768 0 : delete tmp;
769 0 : break;
770 : }
771 0 : case UINTVEC:
772 : {
773 0 : std::vector<unsigned long> *tmp = val.uiv;
774 0 : val.c = new std::complex<double>((*tmp).size() > 0 ? (*tmp)[0] : 0,0.0);
775 0 : delete tmp;
776 0 : break;
777 : }
778 0 : case DOUBLEVEC:
779 : {
780 0 : std::vector<double> *tmp = val.dv;
781 0 : val.c = new std::complex<double>((*tmp).size() > 0 ? (*tmp)[0] : 0,0.0);
782 0 : delete tmp;
783 0 : break;
784 : }
785 0 : case COMPLEXVEC:
786 : {
787 0 : std::vector<std::complex<double> > *tmp = val.cv;
788 0 : val.c = (*tmp).size() > 0 ? new std::complex<double>((*tmp)[0]) : new std::complex<double>(0.0,0.0);
789 0 : delete tmp;
790 0 : break;
791 : }
792 0 : case STRING:
793 : {
794 0 : std::string *tmp = val.s;
795 0 : val.c = new std::complex<double>(stringtocomplex( *tmp ));
796 0 : delete tmp;
797 0 : break;
798 : }
799 0 : case STRINGVEC:
800 : {
801 0 : std::vector<std::string> *tmp = val.sv;
802 0 : val.c = (*tmp).size() > 0 ? new std::complex<double>(stringtocomplex((*tmp)[0])) : new std::complex<double>(0.0,0.0);
803 0 : delete tmp;
804 0 : break;
805 : }
806 0 : case RECORD:
807 0 : delete val.recordv;
808 : default:
809 0 : val.c = new std::complex<double>(0.0,0.0);
810 0 : break;
811 : }
812 :
813 0 : typev = COMPLEX;
814 0 : shape_ = std::vector<ssize_t>(1,1);
815 :
816 : }
817 :
818 0 : return *val.c;
819 : }
820 :
821 : #define ASNUMERICVEC( NAME, TYPE, IDTYPE, TYPETAG, VAL ) \
822 : std::vector<TYPE> &variant::NAME( ssize_t size ) { \
823 : ssize_t newsize = -1; \
824 : if ( typev != TYPETAG ) { \
825 : switch( typev ) { \
826 : case BOOL: \
827 : newsize = size > 1 ? size : 1; \
828 : val.VAL = new std::vector<TYPE>(newsize,(TYPE)(val.b ? 1 : 0)); \
829 : break; \
830 : case INT: \
831 : newsize = size > 1 ? size : 1; \
832 : val.VAL = new std::vector<TYPE>(newsize,(TYPE) val.i); \
833 : break; \
834 : case UINT: \
835 : newsize = size > 1 ? size : 1; \
836 : val.VAL = new std::vector<TYPE>(newsize,(TYPE) val.ui); \
837 : break; \
838 : case DOUBLE: \
839 : newsize = size > 1 ? size : 1; \
840 : val.VAL = new std::vector<TYPE>(newsize,(TYPE) val.d); \
841 : break; \
842 : case COMPLEX: \
843 : { \
844 : newsize = size > 1 ? size : 1; \
845 : std::complex<double> *tmp = val.c; \
846 : val.VAL = new std::vector<TYPE>(newsize,(TYPE) (*tmp).real()); \
847 : delete tmp; \
848 : break; \
849 : } \
850 : case BOOLVEC: \
851 : { \
852 : std::vector<bool> *tmp = val.bv; \
853 : ssize_t current_size = (*tmp).size(); \
854 : newsize = size > current_size ? size : current_size; \
855 : val.VAL = new std::vector<TYPE>(newsize); \
856 : std::vector<bool>::const_iterator from = (*tmp).begin(); \
857 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) \
858 : (*val.VAL)[i] = *from ? 1 : 0; \
859 : delete tmp; \
860 : break; \
861 : } \
862 : case INTVEC: \
863 : { \
864 : std::vector<long> *tmp = val.iv; \
865 : int current_size = (*tmp).size(); \
866 : newsize = size > current_size ? size : current_size; \
867 : val.VAL = new std::vector<TYPE>(newsize); \
868 : std::vector<long>::const_iterator from = (*tmp).begin(); \
869 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) \
870 : (*val.VAL)[i] = (TYPE)(*from); \
871 : delete tmp; \
872 : break; \
873 : } \
874 : case UINTVEC: \
875 : { \
876 : std::vector<unsigned long> *tmp = val.uiv; \
877 : int current_size = (*tmp).size(); \
878 : newsize = size > current_size ? size : current_size; \
879 : val.VAL = new std::vector<TYPE>(newsize); \
880 : std::vector<unsigned long>::const_iterator from = (*tmp).begin(); \
881 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) \
882 : (*val.VAL)[i] = (TYPE)(*from); \
883 : delete tmp; \
884 : break; \
885 : } \
886 : case DOUBLEVEC: \
887 : { \
888 : std::vector<double> *tmp = val.dv; \
889 : ssize_t current_size = (*tmp).size(); \
890 : newsize = size > current_size ? size : current_size; \
891 : val.VAL = new std::vector<TYPE>(newsize); \
892 : std::vector<double>::const_iterator from = (*tmp).begin(); \
893 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) \
894 : (*val.VAL)[i] = (TYPE)(*from); \
895 : delete tmp; \
896 : break; \
897 : } \
898 : case COMPLEXVEC: \
899 : { \
900 : std::vector<std::complex<double> > *tmp = val.cv; \
901 : ssize_t current_size = (*tmp).size(); \
902 : newsize = size > current_size ? size : current_size; \
903 : val.VAL = new std::vector<TYPE>(newsize); \
904 : std::vector<std::complex<double> >::const_iterator from = (*tmp).begin();\
905 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) \
906 : (*val.VAL)[i] = (TYPE)((*from).real()); \
907 : delete tmp; \
908 : break; \
909 : } \
910 : case STRING: \
911 : { \
912 : std::string *tmp = val.s; \
913 : newsize = size > 1 ? size : 1; \
914 : val.VAL = new std::vector<TYPE>(newsize,stringto ## IDTYPE( *tmp ));\
915 : delete tmp; \
916 : break; \
917 : } \
918 : case STRINGVEC: \
919 : { \
920 : std::vector<std::string> *tmp = val.sv; \
921 : int current_size = (*tmp).size(); \
922 : newsize = size > current_size ? size : current_size; \
923 : val.VAL = new std::vector<TYPE>(newsize); \
924 : std::vector<std::string>::const_iterator from = (*tmp).begin(); \
925 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) \
926 : (*val.VAL)[i] = stringto ## IDTYPE(*from); \
927 : delete tmp; \
928 : break; \
929 : } \
930 : case RECORD: \
931 : delete val.recordv; \
932 : default: \
933 : newsize = 0; \
934 : val.VAL = new std::vector<TYPE>(0); \
935 : break; \
936 : } \
937 : \
938 : typev = TYPETAG; \
939 : if ( shape_.size() == 1 ) \
940 : shape_[0] = newsize; \
941 : else if ( shape_size() != newsize ) \
942 : shape_ = std::vector<ssize_t>(1,newsize); \
943 : \
944 : } else if ( size > 0 && (unsigned int) size > (*val.VAL).size() ) { \
945 : resize(size); \
946 : if ( shape_.size() == 1 ) \
947 : shape_[0] = size; \
948 : else if ( shape_size() != size ) \
949 : shape_ = std::vector<ssize_t>(1,size); \
950 : } \
951 : return *val.VAL; \
952 : }
953 :
954 0 : ASNUMERICVEC(asIntVec,long,int,INTVEC,iv)
955 0 : ASNUMERICVEC(asuIntVec,unsigned long,int,UINTVEC,uiv)
956 0 : ASNUMERICVEC(asDoubleVec,double,double,DOUBLEVEC,dv)
957 :
958 0 : std::vector<std::complex<double> > &variant::asComplexVec( ssize_t size ) {
959 0 : ssize_t newsize = -1;
960 0 : if ( typev != COMPLEXVEC ) {
961 0 : switch( typev ) {
962 0 : case BOOL:
963 0 : newsize = size > 1 ? size : 1;
964 0 : val.cv = new std::vector<std::complex<double> >(newsize,std::complex<double>(val.b ? 1 : 0,0.0));
965 0 : break;
966 0 : case INT:
967 0 : newsize = size > 1 ? size : 1;
968 0 : val.cv = new std::vector<std::complex<double> >(newsize,std::complex<double>(val.i,0.0));
969 0 : break;
970 0 : case UINT:
971 0 : newsize = size > 1 ? size : 1;
972 0 : val.cv = new std::vector<std::complex<double> >(newsize,std::complex<double>(val.ui,0.0));
973 0 : break;
974 0 : case DOUBLE:
975 0 : newsize = size > 1 ? size : 1;
976 0 : val.cv = new std::vector<std::complex<double> >(newsize,std::complex<double>(val.d,0.0));
977 0 : break;
978 0 : case COMPLEX:
979 : {
980 0 : newsize = size > 1 ? size : 1;
981 0 : std::complex<double> *tmp = val.c;
982 0 : val.cv = new std::vector<std::complex<double> >(newsize,*tmp);
983 0 : delete tmp;
984 0 : break;
985 : }
986 0 : case BOOLVEC:
987 : {
988 0 : std::vector<bool> *tmp = val.bv;
989 0 : ssize_t current_size = (*tmp).size();
990 0 : newsize = size > current_size ? size : current_size;
991 0 : val.cv = new std::vector<std::complex<double> >(newsize);
992 0 : std::vector<bool>::const_iterator from = (*tmp).begin();
993 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) {
994 0 : (*val.cv)[i] = std::complex<double>(*from ? 1 : 0,0.0);
995 : }
996 0 : delete tmp;
997 0 : break;
998 : }
999 0 : case INTVEC:
1000 : {
1001 0 : std::vector<long> *tmp = val.iv;
1002 0 : int current_size = (*tmp).size();
1003 0 : newsize = size > current_size ? size : current_size;
1004 0 : val.cv = new std::vector<std::complex<double> >(newsize);
1005 0 : std::vector<long>::const_iterator from = (*tmp).begin();
1006 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
1007 0 : (*val.cv)[i] = std::complex<double>(*from,0.0);
1008 0 : delete tmp;
1009 0 : break;
1010 : }
1011 0 : case UINTVEC:
1012 : {
1013 0 : std::vector<unsigned long> *tmp = val.uiv;
1014 0 : int current_size = (*tmp).size();
1015 0 : newsize = size > current_size ? size : current_size;
1016 0 : val.cv = new std::vector<std::complex<double> >(newsize);
1017 0 : std::vector<unsigned long>::const_iterator from = (*tmp).begin();
1018 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
1019 0 : (*val.cv)[i] = std::complex<double>(*from,0.0);
1020 0 : delete tmp;
1021 0 : break;
1022 : }
1023 0 : case DOUBLEVEC:
1024 : {
1025 0 : std::vector<double> *tmp = val.dv;
1026 0 : ssize_t current_size = (*tmp).size();
1027 0 : newsize = size > current_size ? size : current_size;
1028 0 : val.cv = new std::vector<std::complex<double> >(newsize);
1029 0 : std::vector<double>::const_iterator from = (*tmp).begin();
1030 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
1031 0 : (*val.cv)[i] = std::complex<double>(*from,0.0);
1032 0 : delete tmp;
1033 0 : break;
1034 : }
1035 0 : case STRING:
1036 : {
1037 0 : std::string *tmp = val.s;
1038 0 : newsize = 1;
1039 0 : val.cv = new std::vector<std::complex<double> >(1,stringtocomplex( *tmp ));
1040 0 : delete tmp;
1041 0 : break;
1042 : }
1043 0 : case STRINGVEC:
1044 : {
1045 0 : std::vector<std::string> *tmp = val.sv;
1046 0 : ssize_t current_size = (*tmp).size();
1047 0 : newsize = size > current_size ? size : current_size;
1048 0 : val.cv = new std::vector<std::complex<double> >(newsize);
1049 0 : std::vector<std::string>::const_iterator from = (*tmp).begin();
1050 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
1051 0 : (*val.cv)[i] = stringtocomplex(*from);
1052 0 : delete tmp;
1053 0 : break;
1054 : }
1055 0 : case RECORD:
1056 0 : delete val.recordv;
1057 : default:
1058 0 : newsize = 0;
1059 0 : val.cv = new std::vector<std::complex<double> >(0);
1060 0 : break;
1061 : }
1062 :
1063 0 : typev = COMPLEXVEC;
1064 0 : if ( shape_.size() == 1 )
1065 0 : shape_[0] = newsize;
1066 0 : else if ( shape_size() != newsize )
1067 0 : shape_ = std::vector<ssize_t>(1,newsize);
1068 :
1069 0 : } else if ( size > 0 && (size_t) size > (*val.cv).size() ) {
1070 :
1071 0 : resize(size);
1072 0 : if ( shape_.size() == 1 )
1073 0 : shape_[0] = size;
1074 0 : else if ( shape_size() != size )
1075 0 : shape_ = std::vector<ssize_t>(1,size);
1076 :
1077 : }
1078 :
1079 0 : return *val.cv;
1080 : }
1081 :
1082 0 : std::vector<bool> &variant::asBoolVec( ssize_t size ) {
1083 0 : ssize_t newsize = -1;
1084 0 : if ( typev != BOOLVEC ) {
1085 0 : switch( typev ) {
1086 0 : case BOOL:
1087 0 : newsize = size > 1 ? size : 1;
1088 0 : val.bv = new std::vector<bool>(newsize);
1089 0 : break;
1090 0 : case INT:
1091 0 : newsize = size > 1 ? size : 1;
1092 0 : val.bv = new std::vector<bool>(newsize, val.i != 0 ? true : false);
1093 0 : break;
1094 0 : case UINT:
1095 0 : newsize = size > 1 ? size : 1;
1096 0 : val.bv = new std::vector<bool>(newsize, val.ui != 0 ? true : false);
1097 0 : break;
1098 0 : case DOUBLE:
1099 0 : newsize = size > 1 ? size : 1;
1100 0 : val.bv = new std::vector<bool>(newsize, val.d != 0.0 ? true : false);
1101 0 : break;
1102 0 : case COMPLEX:
1103 : {
1104 0 : std::complex<double> *tmp = val.c;
1105 0 : newsize = size > 1 ? size : 1;
1106 0 : val.bv = new std::vector<bool>(newsize, ((*tmp).real() != 0.0 || (*tmp).imag() != 0.0) ? true : false);
1107 0 : delete tmp;
1108 0 : break;
1109 : }
1110 0 : case BOOLVEC:
1111 0 : break;
1112 0 : case INTVEC:
1113 : {
1114 0 : std::vector<long> *tmp = val.iv;
1115 0 : int current_size = (*tmp).size();
1116 0 : newsize = size > current_size ? size : current_size;
1117 0 : val.bv = new std::vector<bool>(newsize);
1118 0 : std::vector<long>::const_iterator from = (*tmp).begin();
1119 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
1120 0 : (*val.bv)[i] = *from != 0 ? true : false;
1121 0 : delete tmp;
1122 0 : break;
1123 : }
1124 0 : case UINTVEC:
1125 : {
1126 0 : std::vector<unsigned long> *tmp = val.uiv;
1127 0 : int current_size = (*tmp).size();
1128 0 : newsize = size > current_size ? size : current_size;
1129 0 : val.bv = new std::vector<bool>(newsize);
1130 0 : std::vector<unsigned long>::const_iterator from = (*tmp).begin();
1131 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
1132 0 : (*val.bv)[i] = *from != 0 ? true : false;
1133 0 : delete tmp;
1134 0 : break;
1135 : }
1136 0 : case DOUBLEVEC:
1137 : {
1138 0 : std::vector<double> *tmp = val.dv;
1139 0 : ssize_t current_size = (*tmp).size();
1140 0 : newsize = size > current_size ? size : current_size;
1141 0 : val.bv = new std::vector<bool>(newsize);
1142 0 : std::vector<double>::const_iterator from = (*tmp).begin();
1143 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
1144 0 : (*val.bv)[i] = *from != 0.0 ? true : false;
1145 0 : delete tmp;
1146 0 : break;
1147 : }
1148 0 : case COMPLEXVEC:
1149 : {
1150 0 : std::vector<std::complex<double> > *tmp = val.cv;
1151 0 : ssize_t current_size = (*tmp).size();
1152 0 : newsize = size > current_size ? size : current_size;
1153 0 : val.bv = new std::vector<bool>(newsize);
1154 0 : std::vector<std::complex<double> >::const_iterator from = (*tmp).begin();
1155 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from) {
1156 0 : const std::complex<double> &cpx = *from;
1157 0 : (*val.bv)[i] = (cpx.real() != 0.0 || cpx.imag() != 0.0) ? true : false;
1158 : }
1159 0 : delete tmp;
1160 0 : break;
1161 : }
1162 0 : case STRING:
1163 0 : newsize = 1;
1164 0 : val.bv = new std::vector<bool>(1,stringtobool( *val.s ));
1165 0 : break;
1166 0 : case STRINGVEC:
1167 : {
1168 0 : std::vector<std::string> *tmp = val.sv;
1169 0 : ssize_t current_size = (*tmp).size();
1170 0 : newsize = size > current_size ? size : current_size;
1171 0 : val.bv = new std::vector<bool>(newsize);
1172 0 : std::vector<std::string>::const_iterator from = (*tmp).begin();
1173 0 : for (unsigned int i=0; from != (*tmp).end(); ++i, ++from)
1174 0 : (*val.bv)[i] = stringtobool(*from);
1175 0 : delete tmp;
1176 0 : break;
1177 : }
1178 0 : case RECORD:
1179 0 : delete val.recordv;
1180 : default:
1181 0 : newsize = 0;
1182 0 : val.bv = new std::vector<bool>(0);
1183 0 : break;
1184 : }
1185 :
1186 0 : typev = BOOLVEC;
1187 0 : if ( shape_.size() == 1 )
1188 0 : shape_[0] = newsize;
1189 0 : else if ( shape_size() != newsize )
1190 0 : shape_ = std::vector<ssize_t>(1,newsize);
1191 :
1192 0 : } else if ( size > 0 && (size_t) size > (*val.bv).size() ) {
1193 0 : resize(size);
1194 0 : if ( shape_.size() == 1 )
1195 0 : shape_[0] = size;
1196 0 : else if ( shape_size() != size )
1197 0 : shape_ = std::vector<ssize_t>(1,size);
1198 : }
1199 :
1200 0 : return *val.bv;
1201 : }
1202 :
1203 0 : bool &variant::asBool( ) {
1204 0 : if (typev != BOOL) {
1205 0 : switch( typev ) {
1206 0 : case BOOL:
1207 0 : break;
1208 0 : case BOOLVEC:
1209 : {
1210 0 : std::vector<bool> *tmp = val.bv;
1211 0 : val.b = (*val.bv).size() > 0 ? (*val.bv)[0] : false;
1212 0 : delete tmp;
1213 0 : break;
1214 : }
1215 0 : case INT:
1216 0 : val.b = val.i ? true : false;
1217 0 : break;
1218 0 : case UINT:
1219 0 : val.b = val.ui ? true : false;
1220 0 : break;
1221 0 : case INTVEC:
1222 : {
1223 0 : std::vector<long> *tmp = val.iv;
1224 0 : val.b = (*tmp).size() > 0 ? ((*tmp)[0] ? true : false) : false;
1225 0 : delete tmp;
1226 0 : break;
1227 : }
1228 0 : case UINTVEC:
1229 : {
1230 0 : std::vector<unsigned long> *tmp = val.uiv;
1231 0 : val.b = (*tmp).size() > 0 ? ((*tmp)[0] ? true : false) : false;
1232 0 : delete tmp;
1233 0 : break;
1234 : }
1235 0 : case DOUBLE:
1236 0 : val.b = val.d != 0.0 ? true : false;
1237 0 : break;
1238 0 : case DOUBLEVEC:
1239 : {
1240 0 : std::vector<double> *tmp = val.dv;
1241 0 : val.b = (*tmp).size() > 0 ? ((*tmp)[0] != 0.0 ? true : false) : false;
1242 0 : delete tmp;
1243 0 : break;
1244 : }
1245 0 : case COMPLEX:
1246 : {
1247 0 : std::complex<double> *tmp = val.c;
1248 0 : val.b = ((*tmp).real() != 0.0 || (*tmp).imag() != 0.0) ? true : false;
1249 0 : delete tmp;
1250 0 : break;
1251 : }
1252 0 : case COMPLEXVEC:
1253 : {
1254 0 : std::vector<std::complex<double> > *tmp = val.cv;
1255 0 : val.b = (*tmp).size() > 0 ? (((*tmp)[0].real() != 0.0 || (*tmp)[0].imag() != 0.0) ? true : false) : false;
1256 0 : delete tmp;
1257 0 : break;
1258 : }
1259 0 : case STRING:
1260 : {
1261 0 : std::string *tmp = val.s;
1262 0 : val.b = stringtobool( *val.s );
1263 0 : delete tmp;
1264 0 : break;
1265 : }
1266 0 : case STRINGVEC:
1267 : {
1268 0 : std::vector<std::string> *tmp = val.sv;
1269 0 : val.b = (*tmp).size() > 0 ? stringtobool((*tmp)[0]) : false;
1270 0 : delete tmp;
1271 0 : break;
1272 : }
1273 0 : case RECORD:
1274 0 : delete val.recordv;
1275 : default:
1276 0 : val.b = false;
1277 0 : break;
1278 : }
1279 0 : typev = BOOL;
1280 : }
1281 :
1282 0 : if ( shape_.size() == 1 )
1283 0 : shape_[0] = 1;
1284 : else
1285 0 : shape_ = std::vector<ssize_t>(1,1);
1286 :
1287 0 : return val.b;
1288 : }
1289 :
1290 0 : std::string &variant::asString( ) {
1291 0 : if ( typev != STRING ) {
1292 0 : switch( typev ) {
1293 0 : case BOOL:
1294 0 : val.s = booltostringptr(val.b);
1295 0 : break;
1296 0 : case INT:
1297 0 : val.s = inttostringptr(val.i);
1298 0 : break;
1299 0 : case UINT:
1300 0 : val.s =inttostringptr(val.ui);
1301 0 : break;
1302 0 : case DOUBLE:
1303 0 : val.s = doubletostringptr(val.d);
1304 0 : break;
1305 0 : case COMPLEX:
1306 : {
1307 0 : std::complex<double> *tmp = val.c;
1308 0 : val.s = complextostringptr(*tmp);
1309 0 : delete tmp;
1310 0 : break;
1311 : }
1312 0 : case BOOLVEC:
1313 0 : VECASSTRING(bool,bool,bv,,"[","]",",","[]")
1314 0 : case INTVEC:
1315 0 : VECASSTRING(long,int,iv,,"[","]",",","[]")
1316 0 : case UINTVEC:
1317 0 : VECASSTRING(unsigned long,int,uiv,,"[","]",",","[]")
1318 0 : case DOUBLEVEC:
1319 0 : VECASSTRING(double,double,dv,,"[","]",",","[]")
1320 0 : case COMPLEXVEC:
1321 0 : VECASSTRING(std::complex<double>,complex,cv,,"[","]",",","[]")
1322 0 : case STRING:
1323 0 : break;
1324 0 : case STRINGVEC:
1325 0 : VECASSTRING(std_string,std_string,sv,,"[\"","\"]","\",\"","[]")
1326 0 : case RECORD:
1327 0 : delete val.recordv;
1328 0 : val.s = new std::string("{...}");
1329 0 : break;
1330 0 : default:
1331 0 : val.s = new std::string("");
1332 0 : break;
1333 : }
1334 0 : typev = STRING;
1335 : }
1336 :
1337 0 : if ( shape_.size() == 1 )
1338 0 : shape_[0] = 1;
1339 : else
1340 0 : shape_ = std::vector<ssize_t>(1,1);
1341 :
1342 0 : return *val.s;
1343 : }
1344 :
1345 0 : std::vector<std::string> &variant::asStringVec( ssize_t size ) {
1346 0 : ssize_t newsize = -1;
1347 0 : if ( typev != STRINGVEC ) {
1348 0 : switch( typev ) {
1349 0 : case BOOL:
1350 0 : newsize = size > 1 ? size : 1;
1351 0 : val.sv = new std::vector<std::string>(newsize,booltostring(val.b));
1352 0 : break;
1353 0 : case INT:
1354 0 : newsize = size > 1 ? size : 1;
1355 0 : val.sv = new std::vector<std::string>(newsize,inttostring(val.i));
1356 0 : break;
1357 0 : case UINT:
1358 0 : newsize = size > 1 ? size : 1;
1359 0 : val.sv = new std::vector<std::string>(newsize,inttostring(val.ui));
1360 0 : break;
1361 0 : case DOUBLE:
1362 0 : newsize = size > 1 ? size : 1;
1363 0 : val.sv = new std::vector<std::string>(newsize,doubletostring(val.d));
1364 0 : break;
1365 0 : case COMPLEX:
1366 : {
1367 0 : std::complex<double> *tmp = val.c;
1368 0 : newsize = size > 1 ? size : 1;
1369 0 : val.sv = new std::vector<std::string>(newsize,complextostring(*tmp));
1370 0 : delete tmp;
1371 0 : break;
1372 : }
1373 0 : case BOOLVEC:
1374 0 : VECASSTRINGVEC(bool,bool,bv,,,)
1375 0 : case INTVEC:
1376 0 : VECASSTRINGVEC(long,int,iv,,,)
1377 0 : case UINTVEC:
1378 0 : VECASSTRINGVEC(unsigned long,int,uiv,,,)
1379 0 : case DOUBLEVEC:
1380 0 : VECASSTRINGVEC(double,double,dv,,,)
1381 0 : case COMPLEXVEC:
1382 0 : VECASSTRINGVEC(std::complex<double>,complex,cv,,,)
1383 0 : case STRING:
1384 : {
1385 0 : newsize = 1;
1386 0 : std::string *tmp = val.s;
1387 0 : val.sv = new std::vector<std::string>(1,*tmp);
1388 0 : delete tmp;
1389 0 : break;
1390 : }
1391 0 : case STRINGVEC:
1392 0 : break;
1393 0 : case RECORD:
1394 0 : newsize = 1;
1395 0 : delete val.recordv;
1396 0 : val.sv = new std::vector<std::string>(1,"{...}");
1397 0 : break;
1398 0 : default:
1399 0 : newsize = 0;
1400 0 : val.sv = new std::vector<std::string>(0);
1401 0 : break;
1402 : }
1403 :
1404 0 : typev = STRINGVEC;
1405 0 : if ( shape_.size() == 1 )
1406 0 : shape_[0] = newsize;
1407 0 : else if ( shape_size() != newsize )
1408 0 : shape_ = std::vector<ssize_t>(1,newsize);
1409 :
1410 0 : } else if ( size > 0 && (unsigned int) size > (*val.sv).size() ) {
1411 0 : resize(size);
1412 0 : if ( shape_.size() == 1 )
1413 0 : shape_[0] = size;
1414 0 : else if ( shape_size() != size )
1415 0 : shape_ = std::vector<ssize_t>(1,size);
1416 : }
1417 :
1418 0 : return *val.sv;
1419 : }
1420 :
1421 59 : record &variant::asRecord( ) {
1422 59 : switch( typev ) {
1423 30 : case RECORD:
1424 30 : return *val.recordv;
1425 0 : case INT:
1426 : case UINT:
1427 : case BOOL:
1428 : case DOUBLE:
1429 0 : break;
1430 29 : case BOOLVEC:
1431 29 : delete val.bv;
1432 29 : break;
1433 0 : case INTVEC:
1434 0 : delete val.iv;
1435 0 : break;
1436 0 : case UINTVEC:
1437 0 : delete val.uiv;
1438 0 : break;
1439 0 : case DOUBLEVEC:
1440 0 : delete val.dv;
1441 0 : break;
1442 0 : case COMPLEX:
1443 0 : delete val.c;
1444 0 : break;
1445 0 : case COMPLEXVEC:
1446 0 : delete val.cv;
1447 0 : break;
1448 0 : case STRING:
1449 0 : delete val.s;
1450 0 : break;
1451 0 : case STRINGVEC:
1452 0 : delete val.sv;
1453 0 : break;
1454 : }
1455 :
1456 29 : typev = RECORD;
1457 29 : val.recordv = new record();
1458 29 : if ( shape_.size() == 1 )
1459 29 : shape_[0] = 0;
1460 : else
1461 0 : shape_ = std::vector<ssize_t>(1,0);
1462 :
1463 29 : return *val.recordv;
1464 : }
1465 :
1466 0 : void variant::as( TYPE t, ssize_t size ) {
1467 :
1468 0 : if (typev == t) return;
1469 :
1470 0 : switch ( t ) {
1471 0 : case BOOL:
1472 0 : asBool();
1473 0 : break;
1474 0 : case INT:
1475 0 : asInt();
1476 0 : break;
1477 0 : case UINT:
1478 0 : asuInt();
1479 0 : break;
1480 0 : case DOUBLE:
1481 0 : asDouble();
1482 0 : break;
1483 0 : case COMPLEX:
1484 0 : asComplex();
1485 0 : break;
1486 0 : case STRING:
1487 0 : asString();
1488 0 : break;
1489 0 : case BOOLVEC:
1490 0 : asBoolVec(size);
1491 0 : break;
1492 0 : case INTVEC:
1493 0 : asIntVec(size);
1494 0 : break;
1495 0 : case UINTVEC:
1496 0 : asuIntVec(size);
1497 0 : break;
1498 0 : case DOUBLEVEC:
1499 0 : asDoubleVec(size);
1500 0 : break;
1501 0 : case STRINGVEC:
1502 0 : asStringVec(size);
1503 0 : break;
1504 0 : case COMPLEXVEC:
1505 0 : asComplexVec(size);
1506 0 : break;
1507 0 : case RECORD:
1508 0 : asRecord( );
1509 0 : break;
1510 : }
1511 : }
1512 :
1513 : #define GETIT(CONST,CONST2,RET_TYPE,NAME,TYPE,VAL,DEREF) \
1514 : CONST RET_TYPE variant::NAME( ) CONST2 { \
1515 : if ( typev != TYPE ) \
1516 : ThrowCc( create_message( #NAME " called for type") ); \
1517 : return DEREF val.VAL; \
1518 : }
1519 :
1520 0 : GETIT(, const, long,getInt,INT,i,)
1521 0 : GETIT(, const, unsigned long,getuInt,UINT,ui,)
1522 0 : GETIT(, const, bool,getBool,BOOL,b,)
1523 2 : GETIT(, const, double,getDouble,DOUBLE,d,)
1524 0 : GETIT(const, const, std::complex<double>&,getComplex,COMPLEX,c,*)
1525 2 : GETIT(const, const, std::string&,getString,STRING,s,*)
1526 0 : GETIT(const, const, std::vector<long>&,getIntVec,INTVEC,iv,*)
1527 0 : GETIT(const, const, std::vector<unsigned long>&,getuIntVec,UINTVEC,uiv,*)
1528 0 : GETIT(const, const, std::vector<bool>&,getBoolVec,BOOLVEC,bv,*)
1529 0 : GETIT(const, const, std::vector<double>&,getDoubleVec,DOUBLEVEC,dv,*)
1530 0 : GETIT(const, const, std::vector<std::complex<double> >&,getComplexVec,COMPLEXVEC,cv,*)
1531 0 : GETIT(const, const, std::vector<std::string>&,getStringVec,STRINGVEC,sv,*)
1532 0 : GETIT(const, const, record&,getRecord,RECORD,recordv,*)
1533 :
1534 0 : GETIT(,,long&,getIntMod,INT,i,)
1535 0 : GETIT(,,unsigned long&,getuIntMod,UINT,ui,)
1536 0 : GETIT(,,bool&,getBoolMod,BOOL,b,)
1537 0 : GETIT(,,double&,getDoubleMod,DOUBLE,d,)
1538 0 : GETIT(,,std::complex<double>&,getComplexMod,COMPLEX,c,*)
1539 0 : GETIT(,,std::string&,getStringMod,STRING,s,*)
1540 0 : GETIT(,,std::vector<long>&,getIntVecMod,INTVEC,iv,*)
1541 0 : GETIT(,,std::vector<unsigned long>&,getuIntVecMod,UINTVEC,uiv,*)
1542 0 : GETIT(,,std::vector<bool>&,getBoolVecMod,BOOLVEC,bv,*)
1543 0 : GETIT(,,std::vector<double>&,getDoubleVecMod,DOUBLEVEC,dv,*)
1544 0 : GETIT(,,std::vector<std::complex<double> >&,getComplexVecMod,COMPLEXVEC,cv,*)
1545 0 : GETIT(,,std::vector<std::string>&,getStringVecMod,STRINGVEC,sv,*)
1546 0 : GETIT(,,record&,getRecordMod,RECORD,recordv,*)
1547 :
1548 : #define PUSHIMPL(TYPEX,TYPETAG,TYPETOSTRING,NUMTWEAK,BOOLTWEAK,BOOLCPX,STRBOOL, STRINT,STRLONG,STRDBL,STRCPX) \
1549 : void variant::push(TYPEX v, bool conform ) { \
1550 : \
1551 : if ( conform == true ) { \
1552 : TYPE new_type = variant::compatible_type(TYPETAG,typev); \
1553 : if (new_type != typev) as(new_type); \
1554 : } \
1555 : \
1556 : switch (typev) { \
1557 : case BOOL: \
1558 : asBoolVec().push_back((bool) STRBOOL(v NUMTWEAK)); \
1559 : break; \
1560 : case INT: \
1561 : asIntVec().push_back((long) STRINT(v BOOLTWEAK)); \
1562 : break; \
1563 : case UINT: \
1564 : asuIntVec().push_back((unsigned long) STRINT(v BOOLTWEAK)); \
1565 : break; \
1566 : case DOUBLE: \
1567 : asDoubleVec().push_back((double) STRDBL(v BOOLTWEAK)); \
1568 : break; \
1569 : case COMPLEX: \
1570 : asComplexVec().push_back((std::complex<double>) STRCPX(v BOOLCPX)); \
1571 : break; \
1572 : case STRING: \
1573 : asStringVec().push_back( TYPETOSTRING(v)); \
1574 : break; \
1575 : case BOOLVEC: \
1576 : (*val.bv).push_back((bool) STRBOOL(v NUMTWEAK)); \
1577 : break; \
1578 : case INTVEC: \
1579 : (*val.iv).push_back((long) STRINT(v BOOLTWEAK)); \
1580 : break; \
1581 : case UINTVEC: \
1582 : (*val.uiv).push_back((unsigned long) STRINT(v BOOLTWEAK)); \
1583 : break; \
1584 : case DOUBLEVEC: \
1585 : (*val.dv).push_back((double) STRDBL(v BOOLTWEAK)); \
1586 : break; \
1587 : case COMPLEXVEC: \
1588 : (*val.cv).push_back((std::complex<double>) STRCPX(v BOOLCPX)); \
1589 : break; \
1590 : case STRINGVEC: \
1591 : (*val.sv).push_back( TYPETOSTRING(v)); \
1592 : break; \
1593 : case RECORD: \
1594 : { \
1595 : char buf[512]; \
1596 : sprintf(buf,"key*%010u",++record_id_count); \
1597 : while ( (*val.recordv).find(buf) != (*val.recordv).end() ) \
1598 : sprintf(buf,"key*%010u",++record_id_count); \
1599 : (*val.recordv).insert(buf,variant(v)); \
1600 : } \
1601 : break; \
1602 : } \
1603 : \
1604 : if ( shape_.size() == 1 ) \
1605 : shape_[0] += 1; \
1606 : else if ( shape_size() != size() ) \
1607 : shape_ = std::vector<ssize_t>(1,size()); \
1608 : }
1609 :
1610 0 : PUSHIMPL(bool ,BOOL ,tostring , ,== true ? 1 : 0 ,== true ? 1 : 0, , , , , )
1611 0 : PUSHIMPL(std::complex<double>,COMPLEX ,tostring ,.real() == 0 && v.imag() == 0 ? false : true ,.real() , , , , , , )
1612 0 : PUSHIMPL(long ,INT ,tostring ,== 0 ? false : true , , , , , , , )
1613 0 : PUSHIMPL(unsigned long ,UINT ,tostring ,== 0 ? false : true , , , , , , , )
1614 0 : PUSHIMPL(double ,DOUBLE ,tostring ,== 0 ? false : true , , , , , , , )
1615 0 : PUSHIMPL(const std::string& ,STRING , , , , ,stringtobool ,stringtoint,stringtolong, stringtodouble ,stringtocomplex )
1616 0 : PUSHIMPL(const char* ,STRING , , , , ,stringtobool ,stringtoint,stringtolong, stringtodouble ,stringtocomplex )
1617 :
1618 : #define PLACEIMPL(TYPEX,TYPETAG,TYPETOSTRING,NUMTWEAK,BOOLTWEAK,BOOLCPX,STRBOOL, STRINT, STRLONG ,STRDBL,STRCPX) \
1619 : void variant::place(TYPEX v, unsigned int index, bool conform ) { \
1620 : \
1621 : if ( conform == true ) { \
1622 : TYPE new_type = variant::compatible_type(TYPETAG,typev); \
1623 : if (new_type != typev) as(new_type); \
1624 : } \
1625 : \
1626 : switch (typev) { \
1627 : case BOOL: \
1628 : if ( index > 0 ) \
1629 : asBoolVec(index+1)[index] = (bool) (STRBOOL(v NUMTWEAK)); \
1630 : else \
1631 : val.b = (bool) (STRBOOL(v NUMTWEAK)); \
1632 : break; \
1633 : case INT: \
1634 : if ( index > 0 ) \
1635 : asIntVec(index+1)[index] = (long) (STRINT(v BOOLTWEAK)); \
1636 : else \
1637 : val.i = (long) (STRINT(v BOOLTWEAK)); \
1638 : case UINT: \
1639 : if ( index > 0 ) \
1640 : asuIntVec(index+1)[index] = (unsigned long) (STRINT(v BOOLTWEAK)); \
1641 : else \
1642 : val.ui = (unsigned long) (STRINT(v BOOLTWEAK)); \
1643 : break; \
1644 : case DOUBLE: \
1645 : if ( index > 0 ) \
1646 : asDoubleVec(index+1).push_back((double) STRDBL(v BOOLTWEAK)); \
1647 : break; \
1648 : case COMPLEX: \
1649 : asComplexVec(index+1).push_back((std::complex<double>) STRCPX(v BOOLCPX)); \
1650 : break; \
1651 : case STRING: \
1652 : asStringVec(index+1).push_back( TYPETOSTRING(v)); \
1653 : break; \
1654 : case BOOLVEC: \
1655 : if ( index+1 > (*val.bv).size() ) \
1656 : (*val.bv).resize(index+1); \
1657 : (*val.bv)[index] = (bool) (STRBOOL(v NUMTWEAK)); \
1658 : break; \
1659 : case INTVEC: \
1660 : if ( index+1 > (*val.iv).size() ) \
1661 : (*val.iv).resize(index+1); \
1662 : (*val.iv)[index] = (long) (STRINT(v BOOLTWEAK)); \
1663 : break; \
1664 : case UINTVEC: \
1665 : if ( index+1 > (*val.uiv).size() ) \
1666 : (*val.uiv).resize(index+1); \
1667 : (*val.uiv)[index] = (unsigned long) (STRINT(v BOOLTWEAK)); \
1668 : break; \
1669 : case DOUBLEVEC: \
1670 : if ( index+1 > (*val.dv).size() ) \
1671 : (*val.dv).resize(index+1); \
1672 : (*val.dv)[index] = (double) (STRDBL(v BOOLTWEAK)); \
1673 : break; \
1674 : case COMPLEXVEC: \
1675 : if ( index+1 > (*val.cv).size() ) \
1676 : (*val.cv).resize(index+1); \
1677 : (*val.cv)[index] = (std::complex<double>) (STRCPX(v BOOLCPX)); \
1678 : break; \
1679 : case STRINGVEC: \
1680 : if ( index+1 > (*val.sv).size() ) \
1681 : (*val.sv).resize(index+1); \
1682 : (*val.sv)[index] = (TYPETOSTRING(v)); \
1683 : break; \
1684 : case RECORD: \
1685 : { \
1686 : char buf[512]; \
1687 : sprintf(buf,"idx*%010u",index); \
1688 : if ((*val.recordv).find(buf) == (*val.recordv).end()) \
1689 : (*val.recordv).insert(buf,casac::variant(v)); \
1690 : else { \
1691 : sprintf(buf,"key*%010u",++record_id_count); \
1692 : while ( (*val.recordv).find(buf) != (*val.recordv).end() ) \
1693 : sprintf(buf,"key*%010u",++record_id_count); \
1694 : (*val.recordv).insert(buf,casac::variant(v)); \
1695 : } \
1696 : } \
1697 : break; \
1698 : } \
1699 : }
1700 :
1701 0 : PLACEIMPL(bool ,BOOL ,tostring , ,== true ? 1 : 0 ,== true ? 1 : 0, , , , , )
1702 0 : PLACEIMPL(std::complex<double>,COMPLEX ,tostring ,.real() == 0.0 && v.imag() == 0.0 ? false : true ,.real() , , , , , , )
1703 0 : PLACEIMPL(long ,INT ,tostring ,== 0 ? false : true , , , , , , , )
1704 0 : PLACEIMPL(unsigned long ,UINT ,tostring ,== 0 ? false : true , , , , , , , )
1705 0 : PLACEIMPL(double ,DOUBLE ,tostring ,== 0 ? false : true , , , , , , , )
1706 0 : PLACEIMPL(const std::string& ,STRING , , , , ,stringtobool ,stringtoint, stringtolong, stringtodouble ,stringtocomplex )
1707 0 : PLACEIMPL(const char* ,STRING , , , , ,stringtobool ,stringtoint, stringtolong, stringtodouble ,stringtocomplex )
1708 :
1709 0 : std::string variant::create_message( const std::string s ) const {
1710 0 : std::string type = (typev == BOOL ? "bool" :
1711 0 : typev == INT ? "int" :
1712 0 : typev == UINT ? "uint" :
1713 0 : typev == DOUBLE ? "double" :
1714 0 : typev == STRING ? "string" :
1715 0 : typev == BOOLVEC ? "boolvec" :
1716 0 : typev == INTVEC ? "intvec" :
1717 0 : typev == UINTVEC ? "uintvec" :
1718 0 : typev == DOUBLEVEC ? "doublevec" :
1719 0 : typev == STRINGVEC ? "stringvec" : "ErRoR");
1720 0 : return s + " " + type + " variant";
1721 0 : }
1722 :
1723 0 : ssize_t variant::shape_size( ) const {
1724 0 : ssize_t result = 1;
1725 0 : for ( std::vector<ssize_t>::const_iterator iter = shape_.begin( );
1726 0 : iter != shape_.end( ); ++iter ) result *= *iter;
1727 0 : return result;
1728 : }
1729 :
1730 0 : ssize_t variant::vec_size( ) const {
1731 0 : switch (typev) {
1732 0 : case BOOLVEC: return (*val.bv).size();
1733 0 : case INTVEC: return (*val.iv).size();
1734 0 : case UINTVEC: return (*val.uiv).size();
1735 0 : case DOUBLEVEC: return (*val.dv).size();
1736 0 : case COMPLEXVEC: return (*val.cv).size();
1737 0 : case STRINGVEC: return (*val.sv).size();
1738 0 : default: return 1;
1739 : }
1740 : }
1741 :
1742 0 : void variant::resize( ssize_t size ) {
1743 :
1744 0 : if ( size < 0 ) return;
1745 :
1746 0 : if ( size > 1 ) {
1747 0 : switch (typev) {
1748 0 : case BOOL:
1749 0 : asBoolVec(size);
1750 0 : break;
1751 0 : case INT:
1752 0 : asIntVec(size);
1753 0 : break;
1754 0 : case UINT:
1755 0 : asuIntVec(size);
1756 0 : break;
1757 0 : case DOUBLE:
1758 0 : asDoubleVec(size);
1759 0 : break;
1760 0 : case COMPLEX:
1761 0 : asComplexVec(size);
1762 0 : break;
1763 0 : case STRING:
1764 0 : asStringVec(size);
1765 0 : break;
1766 0 : case BOOLVEC:
1767 0 : (*val.bv).resize(size);
1768 0 : break;
1769 0 : case INTVEC:
1770 0 : (*val.iv).resize(size);
1771 0 : break;
1772 0 : case UINTVEC:
1773 0 : (*val.uiv).resize(size);
1774 0 : break;
1775 0 : case DOUBLEVEC:
1776 0 : (*val.dv).resize(size);
1777 0 : break;
1778 0 : case COMPLEXVEC:
1779 0 : (*val.cv).resize(size);
1780 0 : break;
1781 0 : case STRINGVEC:
1782 0 : (*val.sv).resize(size);
1783 0 : break;
1784 0 : case RECORD:
1785 0 : break;
1786 : }
1787 : } else {
1788 0 : switch (typev) {
1789 0 : case BOOL:
1790 : case INT:
1791 : case UINT:
1792 : case DOUBLE:
1793 : case COMPLEX:
1794 : case STRING:
1795 0 : break;
1796 0 : case BOOLVEC:
1797 0 : (*val.bv).resize(size);
1798 0 : break;
1799 0 : case INTVEC:
1800 0 : (*val.iv).resize(size);
1801 0 : break;
1802 0 : case UINTVEC:
1803 0 : (*val.uiv).resize(size);
1804 0 : break;
1805 0 : case DOUBLEVEC:
1806 0 : (*val.dv).resize(size);
1807 0 : break;
1808 0 : case COMPLEXVEC:
1809 0 : (*val.cv).resize(size);
1810 0 : break;
1811 0 : case STRINGVEC:
1812 0 : (*val.sv).resize(size);
1813 0 : break;
1814 0 : case RECORD:
1815 0 : break;
1816 : }
1817 : }
1818 : }
1819 :
1820 0 : variant initialize_variant( const std::string & ) {
1821 0 : return variant();
1822 : }
1823 :
1824 0 : bool variant::empty() const {
1825 0 : switch (typev) {
1826 0 : case BOOL:
1827 : case INT:
1828 : case UINT:
1829 : case DOUBLE:
1830 : case COMPLEX:
1831 0 : return false;
1832 0 : case STRING:
1833 0 : return val.s->empty();
1834 0 : case BOOLVEC:
1835 : case INTVEC:
1836 : case UINTVEC:
1837 : case DOUBLEVEC:
1838 : case COMPLEXVEC:
1839 : case STRINGVEC:
1840 0 : return size() == 0;
1841 0 : case RECORD:
1842 0 : return val.recordv->empty();
1843 : }
1844 :
1845 0 : return false; // Looks right for unhandled case???
1846 : }
1847 :
1848 : } // casac namespace
1849 :
|