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