Line data Source code
1 : //-------------------------------------------------------------
2 : // Based on Variant.cc in the Physics eXtension Library (PXL) -
3 : // http://vispa.physik.rwth-aachen.de/ -
4 : // Licensed under a LGPL-2 or later license -
5 : //-------------------------------------------------------------
6 :
7 : #include "crpropa/Variant.h"
8 :
9 :
10 : namespace crpropa {
11 :
12 :
13 1149 : Variant::Variant() : type(TYPE_NONE) {
14 1149 : }
15 :
16 0 : Variant::Variant(Type t) : type(TYPE_NONE) {
17 0 : check(t);
18 0 : }
19 :
20 2304 : Variant::Variant(const Variant& v) : type(TYPE_NONE) {
21 2304 : copy(v);
22 2304 : }
23 :
24 3 : Variant::Variant(const char* s) {
25 3 : data._t_string = new std::string(s);
26 3 : type = TYPE_STRING;
27 3 : }
28 :
29 4616 : Variant::~Variant() {
30 4616 : clear(type);
31 6883 : delete data._t_string;
32 4616 : }
33 :
34 0 : const char* Variant::getTypeName() const {
35 0 : return getTypeName(type);
36 : }
37 :
38 0 : const char* Variant::getTypeName(Type t) {
39 : if (t == TYPE_NONE)
40 : return "none";
41 : else if (t == TYPE_BOOL)
42 0 : return "bool";
43 : else if (t == TYPE_CHAR)
44 0 : return "char";
45 : else if (t == TYPE_UCHAR)
46 0 : return "uchar";
47 : else if (t == TYPE_INT16)
48 0 : return "int16";
49 : else if (t == TYPE_UINT16)
50 0 : return "uint16";
51 : else if (t == TYPE_INT32)
52 0 : return "int32";
53 : else if (t == TYPE_UINT32)
54 0 : return "uint32";
55 : else if (t == TYPE_INT64)
56 0 : return "int64";
57 : else if (t == TYPE_UINT64)
58 0 : return "uint64";
59 : else if (t == TYPE_FLOAT)
60 0 : return "float";
61 : else if (t == TYPE_DOUBLE)
62 0 : return "double";
63 : else if (t == TYPE_LONGDOUBLE)
64 0 : return "ldouble";
65 : else if (t == TYPE_COMPLEXF)
66 0 : return "complex_f";
67 : else if (t == TYPE_COMPLEXD)
68 0 : return "complex_d";
69 : else if (t == TYPE_STRING)
70 0 : return "string";
71 : else if (t == TYPE_VECTOR3F)
72 0 : return "Vector3f";
73 : else if (t == TYPE_VECTOR3D)
74 0 : return "Vector3d";
75 : else if (t == TYPE_VECTOR3C)
76 0 : return "Vector3c";
77 : else if (t == TYPE_VECTOR)
78 0 : return "vector";
79 : else
80 0 : return "unknown";
81 : }
82 :
83 60 : const std::type_info& Variant::getTypeInfo() const {
84 60 : if (type == TYPE_BOOL) {
85 : const std::type_info& ti = typeid(data._t_bool);
86 : return ti;
87 : } else if (type == TYPE_CHAR) {
88 : const std::type_info& ti = typeid(data._t_char);
89 0 : return ti;
90 : } else if (type == TYPE_UCHAR) {
91 : const std::type_info& ti = typeid(data._t_uchar);
92 0 : return ti;
93 : } else if (type == TYPE_INT16) {
94 : const std::type_info& ti = typeid(data._t_int16);
95 0 : return ti;
96 : } else if (type == TYPE_UINT16) {
97 : const std::type_info& ti = typeid(data._t_uint16);
98 0 : return ti;
99 : } else if (type == TYPE_INT32) {
100 : const std::type_info& ti = typeid(data._t_int32);
101 12 : return ti;
102 : } else if (type == TYPE_UINT32) {
103 : const std::type_info& ti = typeid(data._t_uint32);
104 0 : return ti;
105 : } else if (type == TYPE_INT64) {
106 : const std::type_info& ti = typeid(data._t_int64);
107 0 : return ti;
108 : } else if (type == TYPE_UINT64) {
109 : const std::type_info& ti = typeid(data._t_uint64);
110 0 : return ti;
111 : } else if (type == TYPE_FLOAT) {
112 : const std::type_info& ti = typeid(data._t_float);
113 0 : return ti;
114 : } else if (type == TYPE_DOUBLE) {
115 : const std::type_info& ti = typeid(data._t_double);
116 22 : return ti;
117 : } else if (type == TYPE_LONGDOUBLE) {
118 : const std::type_info& ti = typeid(data._t_ldouble);
119 0 : return ti;
120 : } else if (type == TYPE_STRING) {
121 : const std::type_info& ti = typeid(*data._t_string);
122 24 : return ti;
123 : } else if (type == TYPE_COMPLEXF) { // pointer needed?
124 : const std::type_info& ti = typeid(*data._t_complex_f);
125 0 : return ti;
126 : } else if (type == TYPE_COMPLEXD) {
127 : const std::type_info& ti = typeid(*data._t_complex_d);
128 0 : return ti;
129 : } else if (type == TYPE_VECTOR3D) {
130 : const std::type_info& ti = typeid(data._t_vector3d);
131 0 : return ti;
132 : } else if (type == TYPE_VECTOR3F) {
133 : const std::type_info& ti = typeid(data._t_vector3f);
134 0 : return ti;
135 : } else if (type == TYPE_VECTOR) {
136 : const std::type_info& ti = typeid(*data._t_vector);
137 0 : return ti;
138 : } else {
139 : const std::type_info& ti = typeid(0);
140 0 : return ti;
141 : }
142 : }
143 :
144 0 : Variant::Type Variant::toType(const std::string& name) {
145 0 : if (name == "none")
146 : return TYPE_NONE;
147 0 : else if (name == "bool")
148 : return TYPE_BOOL;
149 0 : else if (name == "char")
150 : return TYPE_CHAR;
151 0 : else if (name == "uchar")
152 : return TYPE_UCHAR;
153 0 : else if (name == "int16")
154 : return TYPE_INT16;
155 0 : else if (name == "uint16")
156 : return TYPE_UINT16;
157 0 : else if (name == "int32")
158 : return TYPE_INT32;
159 0 : else if (name == "uint32")
160 : return TYPE_UINT32;
161 0 : else if (name == "int64")
162 : return TYPE_INT64;
163 0 : else if (name == "uint64")
164 : return TYPE_UINT64;
165 0 : else if (name == "float")
166 : return TYPE_FLOAT;
167 0 : else if (name == "double")
168 : return TYPE_DOUBLE;
169 0 : else if (name == "long double")
170 : return TYPE_LONGDOUBLE;
171 0 : else if (name == "complex_f")
172 : return TYPE_COMPLEXF;
173 0 : else if (name == "complex_d")
174 : return TYPE_COMPLEXD;
175 0 : else if (name == "string")
176 : return TYPE_STRING;
177 0 : else if (name == "Vector3f")
178 : return TYPE_VECTOR3F;
179 0 : else if (name == "Vector3d")
180 : return TYPE_VECTOR3D;
181 0 : else if (name == "Vector3c")
182 : return TYPE_VECTOR3C;
183 0 : else if (name == "vector")
184 : return TYPE_VECTOR;
185 : else
186 0 : return TYPE_NONE;
187 : }
188 :
189 2 : bool Variant::toBool() const {
190 2 : switch (type) {
191 2 : case TYPE_BOOL:
192 2 : return data._t_bool;
193 : break;
194 0 : case TYPE_CHAR:
195 0 : return data._t_char != 0;
196 : break;
197 0 : case TYPE_UCHAR:
198 0 : return data._t_uchar != 0;
199 : break;
200 0 : case TYPE_INT16:
201 0 : return data._t_int16 != 0;
202 : break;
203 0 : case TYPE_UINT16:
204 0 : return data._t_uint16 != 0;
205 : break;
206 0 : case TYPE_INT32:
207 0 : return data._t_int32 != 0;
208 : break;
209 0 : case TYPE_UINT32:
210 0 : return data._t_uint32 != 0;
211 : break;
212 0 : case TYPE_INT64:
213 0 : return data._t_int64 != 0;
214 : break;
215 0 : case TYPE_UINT64:
216 0 : return data._t_uint64 != 0;
217 : break;
218 0 : case TYPE_STRING: {
219 0 : std::string upperstr(*data._t_string);
220 : std::transform(upperstr.begin(), upperstr.end(), upperstr.begin(), (int(*) (int)) toupper);
221 0 : if (upperstr == "YES" || upperstr == "TRUE" || upperstr == "1")
222 : return true;
223 0 : else if (upperstr == "NO" || upperstr == "FALSE" || upperstr == "0")
224 : return false;
225 : else
226 0 : throw bad_conversion(type, TYPE_BOOL);
227 : }
228 : break;
229 0 : case TYPE_COMPLEXF: {
230 0 : if (data._t_complex_f->real() == 0 && data._t_complex_f->imag() == 0)
231 0 : return true;
232 : else
233 : return false;
234 : }
235 : break;
236 0 : case TYPE_COMPLEXD: {
237 0 : if (data._t_complex_d->real() == 0 && data._t_complex_d->imag() == 0)
238 0 : return true;
239 : else
240 : return false;
241 : }
242 : break;
243 0 : case TYPE_VECTOR:
244 0 : return data._t_vector->size() != 0;
245 : break;
246 0 : case TYPE_FLOAT:
247 : case TYPE_DOUBLE:
248 : case TYPE_LONGDOUBLE:
249 : default:
250 0 : throw bad_conversion(type, TYPE_BOOL);
251 : break;
252 : }
253 :
254 : return false;
255 : }
256 :
257 0 : float Variant::toFloat() const {
258 0 : switch (type) {
259 0 : case TYPE_BOOL:
260 0 : return data._t_bool ? (float) 1.0 : (float) 0.0;
261 : break;
262 0 : case TYPE_CHAR:
263 0 : return static_cast<float>(data._t_char);
264 : break;
265 0 : case TYPE_UCHAR:
266 0 : return static_cast<float>(data._t_uchar);
267 : break;
268 0 : case TYPE_INT16:
269 0 : return static_cast<float>(data._t_int16);
270 : break;
271 0 : case TYPE_INT32:
272 0 : return static_cast<float>(data._t_int32);
273 : break;
274 0 : case TYPE_INT64:
275 0 : return static_cast<float>(data._t_int64);
276 : break;
277 0 : case TYPE_UINT16:
278 0 : return static_cast<float>(data._t_uint16);
279 : break;
280 0 : case TYPE_UINT32:
281 0 : return static_cast<float>(data._t_uint32);
282 : break;
283 0 : case TYPE_UINT64:
284 0 : return static_cast<float>(data._t_uint64);
285 : break;
286 0 : case TYPE_FLOAT:
287 0 : return static_cast<float>(data._t_float);
288 : break;
289 0 : case TYPE_DOUBLE:
290 0 : return static_cast<float>(data._t_double);
291 : break;
292 0 : case TYPE_LONGDOUBLE:
293 0 : return static_cast<float>(data._t_ldouble);
294 : break;
295 0 : case TYPE_STRING:
296 0 : return static_cast<float>(std::atof(data._t_string->c_str()));
297 : break;
298 0 : case TYPE_COMPLEXF: {
299 0 : if (data._t_complex_f->imag() == 0)
300 0 : return static_cast<float>(data._t_complex_f->real());
301 : else
302 0 : throw bad_conversion(type, TYPE_COMPLEXF);
303 : }
304 : break;
305 0 : case TYPE_COMPLEXD: {
306 0 : if (data._t_complex_d->imag() == 0)
307 0 : return static_cast<float>(data._t_complex_d->real());
308 : else
309 0 : throw bad_conversion(type, TYPE_COMPLEXD);
310 : }
311 : break;
312 0 : default:
313 0 : throw bad_conversion(type, TYPE_FLOAT);
314 : break;
315 : }
316 :
317 : return 0.;
318 : }
319 :
320 6 : double Variant::toDouble() const {
321 6 : switch (type) {
322 0 : case TYPE_BOOL:
323 0 : return data._t_bool ? (double) 1.0 : (double) 0.0;
324 : break;
325 0 : case TYPE_CHAR:
326 0 : return static_cast<double>(data._t_char);
327 : break;
328 0 : case TYPE_UCHAR:
329 0 : return static_cast<double>(data._t_uchar);
330 : break;
331 0 : case TYPE_INT16:
332 0 : return static_cast<double>(data._t_int16);
333 : break;
334 0 : case TYPE_INT32:
335 0 : return static_cast<double>(data._t_int32);
336 : break;
337 0 : case TYPE_INT64:
338 0 : return static_cast<double>(data._t_int64);
339 : break;
340 0 : case TYPE_UINT16:
341 0 : return static_cast<double>(data._t_uint16);
342 : break;
343 0 : case TYPE_UINT32:
344 0 : return static_cast<double>(data._t_uint32);
345 : break;
346 0 : case TYPE_UINT64:
347 0 : return static_cast<double>(data._t_uint64);
348 : break;
349 0 : case TYPE_FLOAT:
350 0 : return static_cast<double>(data._t_float);
351 : break;
352 6 : case TYPE_DOUBLE:
353 6 : return static_cast<double>(data._t_double);
354 : break;
355 0 : case TYPE_LONGDOUBLE:
356 0 : return static_cast<double>(data._t_ldouble);
357 : break;
358 0 : case TYPE_COMPLEXF: {
359 0 : if (data._t_complex_f->imag() == 0)
360 0 : return static_cast<double>(data._t_complex_f->real());
361 : else
362 0 : throw bad_conversion(type, TYPE_COMPLEXF);
363 : }
364 : break;
365 0 : case TYPE_COMPLEXD: {
366 0 : if (data._t_complex_d->imag() == 0)
367 0 : return static_cast<double>(data._t_complex_d->real());
368 : else
369 0 : throw bad_conversion(type, TYPE_COMPLEXD);
370 : }
371 : break;
372 0 : case TYPE_STRING:
373 0 : return static_cast<double>(std::atof(data._t_string->c_str()));
374 : break;
375 0 : default:
376 0 : throw bad_conversion(type, TYPE_DOUBLE);
377 : break;
378 : }
379 :
380 : return 0.;
381 : }
382 :
383 0 : long double Variant::toLongDouble() const {
384 0 : switch (type) {
385 0 : case TYPE_BOOL:
386 0 : return data._t_bool ? (long double) 1.0 : (long double) 0.0;
387 : break;
388 0 : case TYPE_CHAR:
389 0 : return static_cast<long double>(data._t_char);
390 : break;
391 0 : case TYPE_UCHAR:
392 0 : return static_cast<long double>(data._t_uchar);
393 : break;
394 0 : case TYPE_INT16:
395 0 : return static_cast<long double>(data._t_int16);
396 : break;
397 0 : case TYPE_INT32:
398 0 : return static_cast<long double>(data._t_int32);
399 : break;
400 0 : case TYPE_INT64:
401 0 : return static_cast<long double>(data._t_int64);
402 : break;
403 0 : case TYPE_UINT16:
404 0 : return static_cast<long double>(data._t_uint16);
405 : break;
406 0 : case TYPE_UINT32:
407 0 : return static_cast<long double>(data._t_uint32);
408 : break;
409 0 : case TYPE_UINT64:
410 0 : return static_cast<long double>(data._t_uint64);
411 : break;
412 0 : case TYPE_FLOAT:
413 0 : return static_cast<long double>(data._t_float);
414 : break;
415 0 : case TYPE_DOUBLE:
416 0 : return static_cast<long double>(data._t_double);
417 : break;
418 0 : case TYPE_LONGDOUBLE:
419 0 : return static_cast<long double>(data._t_ldouble);
420 : break;
421 0 : case TYPE_COMPLEXF: {
422 0 : if (data._t_complex_f->imag() == 0)
423 0 : return static_cast<long double>(data._t_complex_f->real());
424 : else
425 0 : throw bad_conversion(type, TYPE_COMPLEXF);
426 : }
427 : break;
428 0 : case TYPE_COMPLEXD: {
429 0 : if (data._t_complex_d->imag() == 0)
430 0 : return static_cast<long double>(data._t_complex_d->real());
431 : else
432 0 : throw bad_conversion(type, TYPE_COMPLEXD);
433 : }
434 : break;
435 0 : case TYPE_STRING:
436 0 : return static_cast<double>(std::atof(data._t_string->c_str()));
437 : break;
438 0 : default:
439 0 : throw bad_conversion(type, TYPE_LONGDOUBLE);
440 : break;
441 : }
442 :
443 : return 0.;
444 : }
445 :
446 0 : std::complex<float> Variant::toComplexFloat() const {
447 0 : switch (type) {
448 0 : case TYPE_COMPLEXF:
449 0 : return static_cast<std::complex<float>>(*data._t_complex_f);
450 : break;
451 0 : case TYPE_COMPLEXD:
452 0 : return static_cast<std::complex<float>>(*data._t_complex_d);
453 : break;
454 0 : default:
455 0 : throw bad_conversion(type, TYPE_COMPLEXF);
456 : break;
457 : }
458 : }
459 :
460 0 : std::complex<double> Variant::toComplexDouble() const {
461 0 : switch (type) {
462 0 : case TYPE_COMPLEXF:
463 0 : return static_cast<std::complex<double>>(*data._t_complex_f);
464 : break;
465 0 : case TYPE_COMPLEXD:
466 0 : return static_cast<std::complex<double>>(*data._t_complex_d);
467 : break;
468 0 : default:
469 0 : throw bad_conversion(type, TYPE_COMPLEXD);
470 : break;
471 : }
472 : }
473 :
474 0 : Vector3f Variant::toVector3f() const {
475 0 : switch (type) {
476 0 : case TYPE_VECTOR3F:
477 0 : return static_cast<Vector3f>(*data._t_vector3f);
478 : break;
479 0 : case TYPE_VECTOR3D:
480 0 : return static_cast<Vector3f>(*data._t_vector3d);
481 : break;
482 0 : default:
483 0 : throw bad_conversion(type, TYPE_VECTOR3F);
484 : break;
485 : }
486 : }
487 :
488 0 : Vector3d Variant::toVector3d() const {
489 0 : switch (type) {
490 0 : case TYPE_VECTOR3F:
491 0 : return static_cast<Vector3d>(*data._t_vector3f);
492 : break;
493 0 : case TYPE_VECTOR3D:
494 0 : return static_cast<Vector3d>(*data._t_vector3d);
495 : break;
496 0 : default:
497 0 : throw bad_conversion(type, TYPE_VECTOR3D);
498 : break;
499 : }
500 : }
501 :
502 0 : Vector3<std::complex<double>> Variant::toVector3c() const {
503 0 : switch (type) {
504 0 : case TYPE_VECTOR3C:
505 0 : return static_cast<Vector3c>(*data._t_vector3c);
506 : break;
507 0 : default:
508 0 : throw bad_conversion(type, TYPE_VECTOR3C);
509 : break;
510 : }
511 : }
512 :
513 6 : std::string Variant::toString(const std::string& delimiter) const {
514 6 : if (type == TYPE_STRING)
515 3 : return *data._t_string;
516 :
517 3 : std::stringstream ss;
518 :
519 3 : if (type == TYPE_BOOL) {
520 0 : ss << data._t_bool;
521 : } else if (type == TYPE_CHAR) {
522 0 : ss << data._t_char;
523 : } else if (type == TYPE_UCHAR) {
524 0 : ss << data._t_uchar;
525 : } else if (type == TYPE_INT16) {
526 0 : ss << data._t_int16;
527 : } else if (type == TYPE_UINT16) {
528 0 : ss << data._t_uint16;
529 : } else if (type == TYPE_INT32) {
530 1 : ss << data._t_int32;
531 : } else if (type == TYPE_UINT32) {
532 0 : ss << data._t_uint32;
533 : } else if (type == TYPE_INT64) {
534 1 : ss << data._t_int64;
535 : } else if (type == TYPE_UINT64) {
536 0 : ss << data._t_uint64;
537 : } else if (type == TYPE_FLOAT) {
538 0 : ss << std::scientific << data._t_float;
539 : } else if (type == TYPE_DOUBLE) {
540 1 : ss << std::scientific << data._t_double;
541 : } else if (type == TYPE_LONGDOUBLE) {
542 0 : ss << std::scientific << data._t_ldouble;
543 : } else if (type == TYPE_COMPLEXF) {
544 0 : ss << std::scientific << data._t_complex_f->real() << delimiter;
545 0 : ss << std::scientific << data._t_complex_f->imag();
546 : } else if (type == TYPE_COMPLEXD) {
547 0 : ss << std::scientific << data._t_complex_d->real() << delimiter;
548 0 : ss << std::scientific << data._t_complex_d->imag();
549 : } else if (type == TYPE_VECTOR3F) {
550 0 : ss << *data._t_vector3f;
551 : } else if (type == TYPE_VECTOR3D) {
552 0 : ss << *data._t_vector3d;
553 : } else if (type == TYPE_VECTOR) {
554 0 : ss << *data._t_vector;
555 : }
556 :
557 : return ss.str();
558 3 : }
559 :
560 0 : Variant::vector_t Variant::toVector() const {
561 0 : if (type == TYPE_VECTOR)
562 0 : return *data._t_vector;
563 : else
564 0 : throw bad_conversion(type, TYPE_VECTOR);
565 : }
566 :
567 2 : Variant Variant::fromString(const std::string& s, Type t) {
568 2 : std::stringstream ss(s);
569 :
570 : if (t == TYPE_BOOL) {
571 : std::string upperstr(s);
572 : std::transform(upperstr.begin(), upperstr.end(), upperstr.begin(), (int (*)(int)) toupper);
573 0 : if (upperstr == "YES" || upperstr == "TRUE" || upperstr == "1")
574 : return Variant(true);
575 0 : else if (upperstr == "NO" || upperstr == "FALSE" || upperstr == "0")
576 : return Variant(false);
577 0 : throw bad_conversion(t, TYPE_BOOL);
578 : } else if (t == TYPE_CHAR) {
579 : char c;
580 0 : ss >> c;
581 : return Variant(c);
582 : } else if (t == TYPE_UCHAR) {
583 : unsigned char c;
584 : ss >> c;
585 : return Variant(c);
586 : } else if (t == TYPE_INT16) {
587 : int16_t c;
588 0 : ss >> c;
589 : return Variant(c);
590 : } else if (t == TYPE_INT32) {
591 : int32_t c;
592 1 : ss >> c;
593 : return Variant(c);
594 : } else if (t == TYPE_INT64) {
595 : int64_t c;
596 : ss >> c;
597 : return Variant(c);
598 : } else if (t == TYPE_UINT16) {
599 : uint16_t c;
600 : ss >> c;
601 : return Variant(c);
602 : } else if (t == TYPE_UINT32) {
603 : uint32_t c;
604 : ss >> c;
605 : return Variant(c);
606 : } else if (t == TYPE_UINT64) {
607 : uint64_t c;
608 : ss >> c;
609 : return Variant(c);
610 : } else if (t == TYPE_FLOAT) {
611 : float c;
612 : ss >> c;
613 : return Variant(c);
614 : } else if (t == TYPE_DOUBLE) {
615 : double c;
616 : ss >> c;
617 : return Variant(c);
618 : } else if (t == TYPE_LONGDOUBLE) {
619 : long double c;
620 : ss >> c;
621 : return Variant(c);
622 : } else if (t == TYPE_STRING) {
623 0 : return Variant(s);
624 : } else if (t == TYPE_COMPLEXF) {
625 : float _vr, _vi;
626 : ss >> _vr >> _vi;
627 0 : complex_f v(_vr, _vi);
628 : return Variant(v);
629 : } else if (t == TYPE_COMPLEXD) {
630 : double _vr, _vi;
631 : ss >> _vr >> _vi;
632 0 : complex_d v(_vr, _vi);
633 : return Variant(v);
634 : } else if (t == TYPE_VECTOR3F) {
635 : Vector3f v;
636 : float _val;
637 : ss >> _val;
638 0 : v.setX(_val);
639 : ss >> _val;
640 0 : v.setY(_val);
641 : ss >> _val;
642 0 : v.setZ(_val);
643 : return Variant(v);
644 : } else if (t == TYPE_VECTOR3D) {
645 : Vector3d v;
646 : double _val;
647 : ss >> _val;
648 0 : v.setX(_val);
649 : ss >> _val;
650 0 : v.setY(_val);
651 : ss >> _val;
652 0 : v.setZ(_val);
653 : return Variant(v);
654 : } else if (t == TYPE_VECTOR3C) {
655 : Vector3c v;
656 0 : std::complex<double> _val;
657 0 : ss >> _val;
658 : v.setX(_val);
659 0 : ss >> _val;
660 : v.setY(_val);
661 0 : ss >> _val;
662 : v.setZ(_val);
663 : return Variant(v);
664 : } else if (t == TYPE_VECTOR) {
665 : // std::regex useless("(|)|[|]| ");
666 : vector_t v;
667 0 : while (ss.good()) {
668 : std::string s;
669 0 : v.push_back(s);
670 : }
671 0 : return Variant(v);
672 0 : } else {
673 : std::string msg;
674 : msg += "fromString not implemented for type ";
675 0 : msg += getTypeName(t);
676 0 : throw std::runtime_error("Variant: " + msg);
677 : }
678 2 : }
679 :
680 5786 : void Variant::clear(Type t) {
681 : if (t == TYPE_STRING)
682 2263 : safeDelete(data._t_string);
683 : else if (t == TYPE_VECTOR3F)
684 : safeDelete(data._t_vector3f);
685 : else if (t == TYPE_VECTOR3D)
686 : safeDelete(data._t_vector3d);
687 : else if (t == TYPE_VECTOR3C)
688 : safeDelete(data._t_vector3c);
689 : else if (t == TYPE_COMPLEXF)
690 : safeDelete(data._t_complex_f);
691 : else if (t == TYPE_COMPLEXD)
692 : safeDelete(data._t_complex_d);
693 : else if (t == TYPE_VECTOR)
694 1 : safeDelete(data._t_vector);
695 :
696 : // set the type to TYPE_NONE which will be used for checks
697 5786 : type = TYPE_NONE;
698 5786 : check(t);
699 5786 : }
700 :
701 3455 : void Variant::copy(const Variant& v) {
702 3455 : Type t = v.type;
703 :
704 : if (t == TYPE_BOOL)
705 : operator = (v.data._t_bool);
706 : else if (t == TYPE_CHAR)
707 : operator = (v.data._t_char);
708 : else if (t == TYPE_UCHAR)
709 : operator = (v.data._t_uchar);
710 : else if (t == TYPE_INT16)
711 : operator = (v.data._t_int16);
712 : else if (t == TYPE_UINT16)
713 : operator = (v.data._t_uint16);
714 : else if (t == TYPE_INT32)
715 : operator = (v.data._t_int32);
716 : else if (t == TYPE_UINT32)
717 : operator = (v.data._t_uint32);
718 : else if (t == TYPE_INT64)
719 : operator = (v.data._t_int64);
720 : else if (t == TYPE_UINT64)
721 : operator = (v.data._t_uint64);
722 : else if (t == TYPE_FLOAT)
723 : operator = (v.data._t_float);
724 : else if (t == TYPE_DOUBLE)
725 : operator = (v.data._t_double);
726 : else if (t == TYPE_LONGDOUBLE)
727 : operator = (v.data._t_ldouble);
728 : else if (t == TYPE_STRING)
729 1137 : operator = (*v.data._t_string);
730 : else if (t == TYPE_COMPLEXF)
731 0 : operator = (*v.data._t_complex_f);
732 : else if (t == TYPE_COMPLEXD)
733 0 : operator = (*v.data._t_complex_d);
734 : else if (t == TYPE_VECTOR3F)
735 0 : operator = (*v.data._t_vector3f);
736 : else if (t == TYPE_VECTOR3D)
737 0 : operator = (*v.data._t_vector3d);
738 : else if (t == TYPE_VECTOR3C)
739 0 : operator = (*v.data._t_vector3c);
740 : else if (t == TYPE_VECTOR)
741 0 : operator = (*v.data._t_vector);
742 : else
743 2277 : type = TYPE_NONE;
744 3455 : }
745 :
746 5 : void Variant::check(const Type t) const {
747 5 : if (type != t) {
748 0 : throw bad_conversion(type, t);
749 : }
750 5 : }
751 :
752 5794 : void Variant::check(const Type t) {
753 5794 : if (type == TYPE_NONE) {
754 5786 : memset(&data, 0, sizeof(data));
755 : if (t == TYPE_VECTOR3F)
756 0 : data._t_vector3f = new Vector3f();
757 : else if (t == TYPE_VECTOR3D)
758 1 : data._t_vector3d = new Vector3d();
759 : else if (t == TYPE_VECTOR3C)
760 1 : data._t_vector3c = new Vector3c();
761 : else if (t == TYPE_COMPLEXF)
762 0 : data._t_complex_f = new complex_f();
763 : else if (t == TYPE_COMPLEXD)
764 1 : data._t_complex_d = new complex_d();
765 : else if (t == TYPE_STRING)
766 2263 : data._t_string = new std::string();
767 : else if (t == TYPE_VECTOR)
768 1 : data._t_vector = new vector_t();
769 : else
770 3519 : type = t;
771 8 : } else if (type != t) {
772 0 : throw bad_conversion(type, t);
773 : }
774 5794 : }
775 :
776 8 : bool Variant::isValid() const {
777 8 : return (type != TYPE_NONE);
778 : }
779 :
780 0 : size_t Variant::size() const {
781 0 : if (type == TYPE_VECTOR) {
782 0 : return data._t_vector->size();
783 : } else {
784 : std::string msg;
785 : msg += "size() not implemented for type ";
786 0 : msg += getTypeName(type);
787 0 : throw std::runtime_error("Variant: " + msg);
788 : }
789 : }
790 :
791 0 : size_t Variant::getSizeOf() const {
792 0 : switch (type) {
793 : case TYPE_BOOL:
794 : return sizeof(data._t_bool);
795 : break;
796 : case TYPE_CHAR:
797 : return sizeof(data._t_char);
798 : break;
799 : case TYPE_UCHAR:
800 : return sizeof(data._t_uchar);
801 : break;
802 : case TYPE_INT16:
803 : return sizeof(data._t_int16);
804 : break;
805 : case TYPE_UINT16:
806 : return sizeof(data._t_uint16);
807 : break;
808 : case TYPE_INT32:
809 : return sizeof(data._t_int32);
810 : break;
811 : case TYPE_UINT32:
812 : return sizeof(data._t_uint32);
813 : break;
814 : case TYPE_INT64:
815 : return sizeof(data._t_int64);
816 : break;
817 : case TYPE_UINT64:
818 : return sizeof(data._t_uint64);
819 : break;
820 : case TYPE_FLOAT:
821 : return sizeof(data._t_float);
822 : break;
823 : case TYPE_DOUBLE:
824 : return sizeof(data._t_double);
825 : break;
826 0 : case TYPE_LONGDOUBLE:
827 0 : return sizeof(data._t_ldouble);
828 : break;
829 : case TYPE_COMPLEXF:
830 : return sizeof(data._t_complex_f);
831 : break;
832 : case TYPE_COMPLEXD:
833 : return sizeof(data._t_complex_d);
834 : break;
835 : case TYPE_VECTOR3F:
836 : return sizeof(data._t_vector3f);
837 : break;
838 : case TYPE_VECTOR3D:
839 : return sizeof(data._t_vector3d);
840 : break;
841 : case TYPE_VECTOR3C:
842 : return sizeof(data._t_vector3c);
843 : break;
844 0 : case TYPE_STRING: {
845 0 : size_t len = strlen(data._t_string->c_str() + 1);
846 0 : return len;
847 : }
848 : break;
849 0 : case TYPE_NONE:
850 0 : return 0;
851 : break;
852 0 : default:
853 0 : throw std::runtime_error("Function getSize() cannot handle this type.");
854 : }
855 : }
856 :
857 0 : size_t Variant::getSize() const {
858 0 : return getSizeOf();
859 : }
860 :
861 0 : void Variant::resize(size_t i) {
862 0 : check(TYPE_VECTOR);
863 0 : return data._t_vector->resize(i);
864 : }
865 :
866 1 : size_t Variant::copyToBuffer(void* buffer) {
867 1 : if (type == TYPE_BOOL) {
868 0 : memcpy(buffer, &data._t_bool, sizeof(bool));
869 0 : return sizeof(data._t_bool);
870 : } else if (type == TYPE_CHAR) {
871 0 : memcpy(buffer, &data._t_char, sizeof(char));
872 0 : return sizeof(data._t_char);
873 : } else if (type == TYPE_UCHAR) {
874 0 : memcpy(buffer, &data._t_uchar, sizeof(unsigned char));
875 0 : return sizeof(data._t_uchar);
876 : } else if (type == TYPE_INT16) {
877 0 : memcpy(buffer, &data._t_int16, sizeof(int16_t));
878 0 : return sizeof(data._t_int16);
879 : } else if (type == TYPE_UINT16) {
880 0 : memcpy(buffer, &data._t_uint16, sizeof(uint16_t));
881 0 : return sizeof(data._t_uint16);
882 : } else if (type == TYPE_INT32) {
883 0 : memcpy(buffer, &data._t_int32, sizeof(int32_t));
884 0 : return sizeof(data._t_int32);
885 : } else if (type == TYPE_UINT32) {
886 0 : memcpy(buffer, &data._t_uint32, sizeof(uint32_t));
887 0 : return sizeof(data._t_uint32);
888 : } else if (type == TYPE_INT64) {
889 0 : memcpy(buffer, &data._t_int64, sizeof(int64_t));
890 0 : return sizeof(data._t_int64);
891 : } else if (type == TYPE_UINT64) {
892 0 : memcpy(buffer, &data._t_uint64, sizeof(uint64_t));
893 0 : return sizeof(data._t_uint64);
894 : } else if (type == TYPE_FLOAT) {
895 0 : memcpy(buffer, &data._t_float, sizeof(float));
896 0 : return sizeof(data._t_float);
897 : } else if (type == TYPE_DOUBLE) {
898 1 : memcpy(buffer, &data._t_double, sizeof(double));
899 1 : return sizeof(data._t_double);
900 : } else if (type == TYPE_LONGDOUBLE) {
901 0 : memcpy(buffer, &data._t_ldouble, sizeof(long double));
902 0 : return sizeof(data._t_ldouble);
903 : } else if (type == TYPE_STRING) {
904 0 : size_t len = data._t_string->size();
905 : memcpy(buffer, data._t_string->c_str(), len);
906 0 : return len;
907 : } else if (type == TYPE_NONE) {
908 : return 0;
909 : } else {
910 0 : throw std::runtime_error("This type cannot be handled by copyToBuffer().");
911 : }
912 : }
913 :
914 1151 : Variant& Variant::operator=(const Variant &v) {
915 1151 : copy(v);
916 1151 : return *this;
917 : }
918 :
919 4 : bool Variant::operator==(const Variant& v) const {
920 4 : if (type != v.type)
921 : return false;
922 :
923 : if (type == TYPE_BOOL) {
924 0 : return (data._t_bool == v.data._t_bool);
925 : } else if (type == TYPE_CHAR) {
926 0 : return (data._t_char == v.data._t_char);
927 : } else if (type == TYPE_UCHAR) {
928 0 : return (data._t_uchar == v.data._t_uchar);
929 : } else if (type == TYPE_INT16) {
930 0 : return (data._t_int16 == v.data._t_int16);
931 : } else if (type == TYPE_UINT16) {
932 0 : return (data._t_uint16 == v.data._t_uint16);
933 : } else if (type == TYPE_INT32) {
934 0 : return (data._t_int32 == v.data._t_int32);
935 : } else if (type == TYPE_UINT32) {
936 0 : return (data._t_uint32 == v.data._t_uint32);
937 : } else if (type == TYPE_INT64) {
938 0 : return (data._t_int64 == v.data._t_int64);
939 : } else if (type == TYPE_UINT64) {
940 0 : return (data._t_uint64 == v.data._t_uint64);
941 : } else if (type == TYPE_FLOAT) {
942 0 : return (data._t_float == v.data._t_float);
943 : } else if (type == TYPE_DOUBLE) {
944 4 : return (data._t_double == v.data._t_double);
945 : } else if (type == TYPE_LONGDOUBLE) {
946 0 : return (data._t_ldouble == v.data._t_ldouble);
947 : } else if (type == TYPE_STRING) {
948 0 : return (*data._t_string == *v.data._t_string);
949 : } else if (type == TYPE_COMPLEXF) {
950 0 : return (*data._t_complex_f == *v.data._t_complex_f);
951 : } else if (type == TYPE_COMPLEXD) {
952 0 : return (*data._t_complex_d == *v.data._t_complex_d);
953 : } else if (type == TYPE_VECTOR3F) {
954 0 : return (*data._t_vector3f == *v.data._t_vector3f);
955 : } else if (type == TYPE_VECTOR3D) {
956 0 : return (*data._t_vector3d == *v.data._t_vector3d);
957 : } else if (type == TYPE_VECTOR3C) {
958 0 : return (*data._t_vector3c == *v.data._t_vector3c);
959 : } else if (type == TYPE_VECTOR) {
960 0 : return (*data._t_vector == *v.data._t_vector);
961 : } else {
962 0 : throw std::runtime_error("compare operator not implemented");
963 : }
964 : }
965 :
966 0 : bool Variant::operator!=(const Variant& v) const {
967 0 : if (type != v.type)
968 : return true;
969 :
970 0 : if (*this == v)
971 : return false;
972 : else
973 : return true;
974 : }
975 :
976 0 : bool Variant::operator!=(const char* v) const {
977 0 : check(TYPE_STRING);
978 0 : return data._t_string->compare(v) != 0;
979 : }
980 :
981 0 : Variant& Variant::operator[](size_t i) {
982 0 : check(TYPE_VECTOR);
983 0 : return (*data._t_vector)[i];
984 : }
985 :
986 0 : const Variant& Variant::operator[](size_t i) const {
987 0 : check(TYPE_VECTOR);
988 0 : return (*data._t_vector)[i];
989 : }
990 :
991 0 : Variant::operator std::vector<Variant>&() {
992 0 : check(TYPE_VECTOR);
993 0 : return *data._t_vector;
994 : }
995 :
996 0 : Variant::operator const std::vector<Variant>&() const {
997 0 : check(TYPE_VECTOR);
998 0 : return *data._t_vector;
999 : }
1000 :
1001 :
1002 :
1003 : #define INT_CASE(from_var, from_type, to_type, to) \
1004 : case Variant::from_type: { \
1005 : if (data._t_##from_var <std::numeric_limits<to>::min() || data._t_##from_var> std::numeric_limits<to>::max()) \
1006 : throw bad_conversion(type, to_type); \
1007 : else \
1008 : return static_cast<to>(data._t_##from_var); \
1009 : } \
1010 : break; \
1011 :
1012 : #define INT_FUNCTION(to_type, fun, to) \
1013 : to Variant::fun() const { \
1014 : switch (to_type) { \
1015 : case Variant::TYPE_BOOL: \
1016 : return data._t_bool ? 1 : 0; \
1017 : break; \
1018 : INT_CASE(char, TYPE_CHAR, to_type, to) \
1019 : INT_CASE(uchar, TYPE_UCHAR, to_type, to) \
1020 : INT_CASE(int16, TYPE_INT16, to_type, to) \
1021 : INT_CASE(uint16, TYPE_UINT16, to_type, to) \
1022 : INT_CASE(int32, TYPE_INT32, to_type, to) \
1023 : INT_CASE(uint32, TYPE_UINT32, to_type, to) \
1024 : INT_CASE(int64, TYPE_INT64, to_type, to) \
1025 : INT_CASE(uint64, TYPE_UINT64, to_type, to) \
1026 : INT_CASE(float, TYPE_FLOAT, to_type, to) \
1027 : INT_CASE(double, TYPE_DOUBLE, to_type, to) \
1028 : INT_CASE(ldouble, TYPE_LONGDOUBLE, to_type, to) \
1029 : case Variant::TYPE_STRING: { \
1030 : long l = atol(data._t_string->c_str()); \
1031 : if (l <std::numeric_limits<to>::min() || l > std::numeric_limits<to>::max()) \
1032 : throw bad_conversion(type, to_type); \
1033 : else \
1034 : return l; \
1035 : } \
1036 : break; \
1037 : case Variant::TYPE_COMPLEXF: \
1038 : case Variant::TYPE_COMPLEXD: \
1039 : case Variant::TYPE_VECTOR3F: \
1040 : case Variant::TYPE_VECTOR3D: \
1041 : case Variant::TYPE_VECTOR3C: \
1042 : case Variant::TYPE_VECTOR: \
1043 : case Variant::TYPE_NONE: \
1044 : throw bad_conversion(type, to_type); \
1045 : break; \
1046 : } \
1047 : return 0; \
1048 : }
1049 :
1050 0 : INT_FUNCTION(TYPE_CHAR, toChar, char)
1051 0 : INT_FUNCTION(TYPE_UCHAR, toUChar, unsigned char)
1052 0 : INT_FUNCTION(TYPE_INT16, toInt16, int16_t)
1053 0 : INT_FUNCTION(TYPE_UINT16, toUInt16, uint16_t)
1054 0 : INT_FUNCTION(TYPE_INT32, toInt32, int32_t)
1055 0 : INT_FUNCTION(TYPE_UINT32, toUInt32, uint32_t)
1056 2 : INT_FUNCTION(TYPE_INT64, toInt64, int64_t)
1057 0 : INT_FUNCTION(TYPE_UINT64, toUInt64, uint64_t)
1058 :
1059 :
1060 :
1061 0 : std::ostream& operator <<(std::ostream& os, const Variant& v) {
1062 0 : switch (v.getType()) {
1063 : case Variant::TYPE_BOOL:
1064 0 : os << v.asBool();
1065 : break;
1066 : case Variant::TYPE_CHAR:
1067 0 : os << v.asChar();
1068 0 : break;
1069 : case Variant::TYPE_UCHAR:
1070 0 : os << v.asUChar();
1071 : break;
1072 : case Variant::TYPE_INT16:
1073 0 : os << v.asInt16();
1074 0 : break;
1075 : case Variant::TYPE_UINT16:
1076 0 : os << v.asUInt16();
1077 : break;
1078 : case Variant::TYPE_INT32:
1079 0 : os << v.asInt32();
1080 0 : break;
1081 : case Variant::TYPE_UINT32:
1082 0 : os << v.asUInt32();
1083 : break;
1084 : case Variant::TYPE_INT64:
1085 0 : os << v.asInt64();
1086 : break;
1087 : case Variant::TYPE_UINT64:
1088 0 : os << v.asUInt64();
1089 : break;
1090 : case Variant::TYPE_FLOAT:
1091 0 : os << v.asFloat();
1092 : break;
1093 : case Variant::TYPE_DOUBLE:
1094 0 : os << v.asDouble();
1095 : break;
1096 : case Variant::TYPE_LONGDOUBLE:
1097 0 : os << v.asLongDouble();
1098 : break;
1099 : case Variant::TYPE_COMPLEXF:
1100 0 : os << v.asComplexFloat();
1101 0 : break;
1102 : case Variant::TYPE_COMPLEXD:
1103 0 : os << v.asComplexDouble();
1104 0 : break;
1105 : case Variant::TYPE_STRING:
1106 : os << v.asString();
1107 : break;
1108 : case Variant::TYPE_VECTOR3F:
1109 0 : os << v.asVector3f();
1110 0 : break;
1111 : case Variant::TYPE_VECTOR3D:
1112 0 : os << v.asVector3d();
1113 0 : break;
1114 : case Variant::TYPE_VECTOR3C:
1115 0 : os << v.asVector3c();
1116 0 : break;
1117 : default:
1118 : break;
1119 : }
1120 :
1121 0 : return os;
1122 : }
1123 :
1124 :
1125 :
1126 : } // namespace crpropa
|