LCOV - code coverage report
Current view: top level - include/crpropa - Variant.h (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 50.0 % 36 18
Test Date: 2026-06-18 09:49:19 Functions: 37.5 % 16 6

            Line data    Source code
       1              : //-------------------------------------------------------------
       2              : // Based on Variant.hh of the Physics eXtension Library (PXL) -
       3              : // http://vispa.physik.rwth-aachen.de/                        -
       4              : // Licensed under a LGPL-2 or later license                   -
       5              : //-------------------------------------------------------------
       6              : 
       7              : #ifndef CRPROPA_VARIANT_H
       8              : #define CRPROPA_VARIANT_H
       9              : 
      10              : #include <complex>
      11              : #include <cstdint>
      12              : #include <cstdlib>
      13              : #include <cstring>
      14              : #include <iostream>
      15              : #include <limits>
      16              : #include <string>
      17              : #include <sstream>
      18              : #include <stdexcept>
      19              : #include <typeinfo>
      20              : 
      21              : #include "crpropa/Vector3.h"
      22              : 
      23              : 
      24              : 
      25              : // defines copy constructor X(const X&), isX(), asX(), fromX(), toX(), op(), op=, op==, op!=
      26              : #define VARIANT_ADD_TYPE_DECL_POD(NAME, TYPE, VALUE, FIELD) \
      27              :         Variant(const VALUE& v) { \
      28              :                 data._t_##FIELD = v; \
      29              :                 type = TYPE;  \
      30              :         } \
      31              :         bool is##NAME() const { \
      32              :                 return type == TYPE; \
      33              :         } \
      34              :         VALUE& as##NAME() { \
      35              :                 check(TYPE); \
      36              :                 return data._t_##FIELD; \
      37              :         } \
      38              :         const VALUE& as##NAME() const { \
      39              :                 check(TYPE); \
      40              :                 return data._t_##FIELD; \
      41              :         } \
      42              :         static Variant from##NAME(const VALUE& v) { \
      43              :                 return Variant(v); \
      44              :         } \
      45              :         VALUE to##NAME() const; \
      46              :         operator VALUE() const { \
      47              :                 return to##NAME(); \
      48              :         } \
      49              :         Variant& operator=(const VALUE& v) { \
      50              :                 clear(); \
      51              :                 type = TYPE; \
      52              :                 data._t_##FIELD = v; \
      53              :                 return *this; \
      54              :         } \
      55              :         bool operator==(const VALUE& v) const { \
      56              :                 check(TYPE); \
      57              :                 return data._t_##FIELD == v; \
      58              :         } \
      59              :         bool operator!=(const VALUE& v) const { \
      60              :                 check(TYPE); \
      61              :                 return data._t_##FIELD != v; \
      62              :         } \
      63              : 
      64              : // defines isX(), asX(), fromX()
      65              : #define VARIANT_ADD_TYPE_DECL_PTR_BASE(NAME, TYPE, VALUE, FIELD) \
      66              :         bool is##NAME() const { \
      67              :                 return type == TYPE; \
      68              :         } \
      69              :         VALUE& as##NAME() { \
      70              :                 check(TYPE); \
      71              :                 return *data._t_##FIELD; \
      72              :         } \
      73              :         const VALUE& as##NAME() const { \
      74              :                 check(TYPE); \
      75              :                 return *data._t_##FIELD; \
      76              :         } \
      77              :         static Variant from##NAME(const VALUE& v) { \
      78              :                 return Variant(v); \
      79              :         } \
      80              : 
      81              : // defines isX(), asX(), fromX(), and copy constructor X(const X&), op=, op==, op!=
      82              : #define VARIANT_ADD_TYPE_DECL_PTR(NAME, TYPE, VALUE, FIELD) \
      83              :         VARIANT_ADD_TYPE_DECL_PTR_BASE(NAME, TYPE, VALUE, FIELD) \
      84              :         Variant(const VALUE& v) { \
      85              :                 data._t_##FIELD = new VALUE(v); \
      86              :                 type = TYPE; \
      87              :         } \
      88              :         Variant& operator=(const VALUE& v) { \
      89              :                 if (type != TYPE) { \
      90              :                         clear(); \
      91              :                         data._t_##FIELD = new VALUE();\
      92              :                 } \
      93              :                 type = TYPE; \
      94              :                 (*data._t_##FIELD) = v; \
      95              :                 return *this; \
      96              :         } \
      97              :         bool operator==(const VALUE& v) const { \
      98              :                 check(TYPE); \
      99              :                 return *data._t_##FIELD == v; \
     100              :         } \
     101              :         bool operator!=(const VALUE& v) const { \
     102              :                 return !(*this == v); \
     103              :         } \
     104              : 
     105              : #define VARIANT_ADD_ITER_DECL_PTR(NAME, TYPE, FIELD) \
     106              :         typedef FIELD##_t::iterator FIELD##_iterator; \
     107              :         typedef FIELD##_t::const_iterator FIELD##_const_iterator; \
     108              :         inline FIELD##_iterator begin##NAME() { \
     109              :                 check(TYPE); \
     110              :                 return data._t_##FIELD->begin(); \
     111              :         } \
     112              :         inline FIELD##_iterator end##NAME() { \
     113              :                 check(TYPE); \
     114              :                 return data._t_##FIELD->end(); \
     115              :         } \
     116              :         inline FIELD##_const_iterator begin##NAME() const { \
     117              :                 check(TYPE); \
     118              :                 return data._t_##FIELD->begin(); \
     119              :         } \
     120              :         inline FIELD##_const_iterator end##NAME() const { \
     121              :                 check(TYPE); \
     122              :                 return data._t_##FIELD->end(); \
     123              :         }                                                                                
     124              : 
     125              : 
     126              : 
     127              : namespace crpropa {
     128              : 
     129              : /**
     130              :  @class Variant
     131              :  @brief storage container for data types as e.g. int, float, string, etc.
     132              : 
     133              :  Allows storage of multiple data types in one base class. Used to construct a map of `arbitrary' data types.
     134              :  Note that most default C++ types allow default conversions from `Variant` to the corresponding type.
     135              :  Types that require an explicit call via `toTargetType()` are: complex (float and double), Vector3, and vector<Variant>.
     136              :  */
     137              : class Variant {
     138              : public:
     139              :         enum Type {
     140              :                 TYPE_NONE = 0,
     141              :                 TYPE_BOOL,
     142              :                 TYPE_CHAR,
     143              :                 TYPE_UCHAR,
     144              :                 TYPE_INT16,
     145              :                 TYPE_UINT16,
     146              :                 TYPE_INT32,
     147              :                 TYPE_UINT32,
     148              :                 TYPE_INT64,
     149              :                 TYPE_UINT64,
     150              :                 TYPE_FLOAT,
     151              :                 TYPE_DOUBLE,
     152              :                 TYPE_LONGDOUBLE,
     153              :                 TYPE_COMPLEXF,
     154              :                 TYPE_COMPLEXD,
     155              :                 TYPE_STRING,
     156              :                 TYPE_VECTOR3F,
     157              :                 TYPE_VECTOR3D,
     158              :                 TYPE_VECTOR3C,
     159              :                 TYPE_VECTOR
     160              :         };
     161              : 
     162              :         class bad_conversion: public std::exception {
     163              :                 protected:
     164              :                         std::string msg;
     165              :                 public:
     166            0 :                         const char* what() const throw () {
     167            0 :                                 return msg.c_str();
     168              :                         }
     169              : 
     170            0 :                         bad_conversion(Type f, Type t) {
     171            0 :                                 msg = "Variant: bad conversion from '";
     172            0 :                                 msg += Variant::getTypeName(f);
     173              :                                 msg += "' to '";
     174            0 :                                 msg += Variant::getTypeName(t);
     175              :                                 msg += "'";
     176            0 :                         }
     177              : 
     178            0 :                         ~bad_conversion() throw () {
     179            0 :                         }
     180              :         };
     181              : 
     182              :         typedef std::complex<float> complex_f;
     183              :         typedef std::complex<double> complex_d;
     184              :         typedef Vector3<std::complex<double>> Vector3c;
     185              :         typedef std::vector<Variant> vector_t;
     186              : 
     187              : protected:
     188              :         Type type;
     189              : 
     190              :         union {
     191              :                 bool _t_bool;
     192              :                 char _t_char;
     193              :                 unsigned char _t_uchar;
     194              :                 int16_t _t_int16;
     195              :                 uint16_t _t_uint16;
     196              :                 int32_t _t_int32;
     197              :                 uint32_t _t_uint32;
     198              :                 int64_t _t_int64;
     199              :                 uint64_t _t_uint64;
     200              :                 float _t_float;
     201              :                 double _t_double;
     202              :                 long double _t_ldouble;
     203              :                 complex_f* _t_complex_f;
     204              :                 complex_d* _t_complex_d;
     205              :                 std::string* _t_string;
     206              :                 Vector3f* _t_vector3f;
     207              :                 Vector3d* _t_vector3d;
     208              :                 Vector3c* _t_vector3c;
     209              :                 vector_t* _t_vector;
     210              :         } data;
     211              : 
     212              : 
     213              : public:
     214              :         Variant();
     215              :         Variant(Type t);
     216              :         Variant(const Variant& v);
     217              :         Variant(const char* s);
     218              :         ~Variant();
     219              :         inline Type getType() const {
     220            2 :                 return type;
     221              :         }
     222              :         const char* getTypeName() const;
     223              :         static const char* getTypeName(Type t);
     224              :         const std::type_info& getTypeInfo() const;
     225              :         static Type toType(const std::string& name);                
     226              :         std::string toString(const std::string& delimiter = "\t") const;
     227              :         std::complex<float> toComplexFloat() const;
     228              :         std::complex<double> toComplexDouble() const;
     229              :         Vector3f toVector3f() const;
     230              :         Vector3d toVector3d() const;
     231              :         Vector3c toVector3c() const;
     232              :         vector_t toVector() const;
     233              :         static Variant fromString(const std::string& str, Type type);
     234              :         void clear(Type t = TYPE_NONE);
     235              :         bool isValid() const;
     236              :         size_t size() const;
     237              :         size_t getSizeOf() const;
     238              :         size_t getSize() const;
     239              :         void resize(size_t i);
     240              :         size_t copyToBuffer(void* buffer);
     241            1 :         operator std::string() const {
     242            2 :                 return toString();
     243              :         }
     244              :         Variant& operator=(const Variant& v);
     245              :         bool operator==(const Variant& v) const;
     246              :         bool operator!=(const Variant& v) const;
     247              :         bool operator!=(const char* a) const;
     248              :         Variant& operator[](size_t i);
     249              :         inline Variant& operator[](int i) {
     250              :                 return operator[]((size_t) i);
     251              :         }
     252              :         const Variant& operator[](size_t i) const;
     253              :         const Variant& operator[](int i) const {
     254              :                 return operator[]((size_t) i);
     255              :         }
     256              :         operator vector_t&();
     257              :         operator const vector_t&() const;
     258              : 
     259              : 
     260              :         template<class T>
     261              :         T to() const {
     262              :                 throw bad_conversion(type, TYPE_NONE);
     263              :         }
     264              : 
     265              :         // automatically-generated functions    
     266            6 :         VARIANT_ADD_TYPE_DECL_POD(Bool, TYPE_BOOL, bool, bool)
     267            0 :         VARIANT_ADD_TYPE_DECL_POD(Char, TYPE_CHAR, char, char)
     268            0 :         VARIANT_ADD_TYPE_DECL_POD(UChar, TYPE_UCHAR, unsigned char, uchar)
     269            0 :         VARIANT_ADD_TYPE_DECL_POD(Int16, TYPE_INT16, int16_t, int16)
     270            0 :         VARIANT_ADD_TYPE_DECL_POD(UInt16, TYPE_UINT16, uint16_t, uint16)
     271           12 :         VARIANT_ADD_TYPE_DECL_POD(Int32, TYPE_INT32, int32_t, int32)
     272            0 :         VARIANT_ADD_TYPE_DECL_POD(UInt32, TYPE_UINT32, uint32_t, uint32)
     273            6 :         VARIANT_ADD_TYPE_DECL_POD(Int64, TYPE_INT64, int64_t, int64)
     274           17 :         VARIANT_ADD_TYPE_DECL_POD(UInt64, TYPE_UINT64, uint64_t, uint64)
     275            0 :         VARIANT_ADD_TYPE_DECL_POD(Float, TYPE_FLOAT, float, float)
     276           34 :         VARIANT_ADD_TYPE_DECL_POD(Double, TYPE_DOUBLE, double, double)
     277            0 :         VARIANT_ADD_TYPE_DECL_POD(LongDouble, TYPE_LONGDOUBLE, long double, ldouble)
     278            0 :         VARIANT_ADD_TYPE_DECL_PTR(ComplexFloat, TYPE_COMPLEXF, std::complex<float>, complex_f)
     279            1 :         VARIANT_ADD_TYPE_DECL_PTR(ComplexDouble, TYPE_COMPLEXD, std::complex<double>, complex_d)
     280         3399 :         VARIANT_ADD_TYPE_DECL_PTR(String, TYPE_STRING, std::string, string)
     281            0 :         VARIANT_ADD_TYPE_DECL_PTR(Vector3f, TYPE_VECTOR3F, Vector3f, vector3f)
     282            1 :         VARIANT_ADD_TYPE_DECL_PTR(Vector3d, TYPE_VECTOR3D, Vector3d, vector3d)
     283            1 :         VARIANT_ADD_TYPE_DECL_PTR(Vector3c, TYPE_VECTOR3C, Vector3c, vector3c)
     284            2 :         VARIANT_ADD_TYPE_DECL_PTR(Vector, TYPE_VECTOR, vector_t, vector)
     285              :         VARIANT_ADD_ITER_DECL_PTR(Vector, TYPE_VECTOR, vector)
     286              :                 
     287              : private:
     288              :         void copy(const Variant& v);
     289              :         void check(const Type t) const;
     290              :         void check(const Type t);
     291              : };
     292              : 
     293              : #define VARIANT_TO_DECL(NAME, VALUE) \
     294              :         template<> inline VALUE Variant::to<VALUE>() const { \
     295              :                 return to##NAME(); \
     296              :         } \
     297              : 
     298              : // declare type conversion functions
     299              : // not implemented for Vector3 and complex_*
     300              : VARIANT_TO_DECL(Bool, bool)
     301              : VARIANT_TO_DECL(Char, char)
     302              : VARIANT_TO_DECL(UChar, unsigned char)
     303              : VARIANT_TO_DECL(Int16, int16_t)
     304              : VARIANT_TO_DECL(UInt16, uint16_t)
     305              : VARIANT_TO_DECL(Int32, int32_t)
     306              : VARIANT_TO_DECL(UInt32, uint32_t)
     307              : VARIANT_TO_DECL(Int64, int64_t)
     308              : VARIANT_TO_DECL(UInt64, uint64_t)
     309              : VARIANT_TO_DECL(Float, float)
     310              : VARIANT_TO_DECL(Double, double)
     311              : VARIANT_TO_DECL(LongDouble, long double)
     312              : VARIANT_TO_DECL(String, std::string)
     313              : VARIANT_TO_DECL(Vector, Variant::vector_t)
     314              : 
     315              : std::ostream& operator <<(std::ostream& os, const Variant &v);
     316              : 
     317              : 
     318              : /**
     319              :  Taken from PXL
     320              :  https://git.rwth-aachen.de/3pia/pxl/pxl/-/blob/master/core/include/pxl/core/Functions.hh
     321              :  */
     322              : template <class T> 
     323         2264 : inline void safeDelete(T*& p) {
     324         2267 :         if (p) {
     325         2267 :                 delete p;
     326         2267 :                 p = 0;
     327              :         }
     328         2264 : }
     329              : 
     330              : 
     331              : 
     332              : } // namespace crpropa 
     333              : 
     334              : #endif // CRPROPA_VARIANT
        

Generated by: LCOV version 2.0-1