LCOV - code coverage report
Current view: top level - include/crpropa - Variant.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 13 35 37.1 %
Date: 2024-04-29 14:43:01 Functions: 4 16 25.0 %

          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             :                                 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          16 :         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        3396 :         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           0 : inline void safeDelete(T*& p) {
     324           0 :         if (p) {
     325           0 :                 delete p;
     326           0 :                 p = 0;
     327             :         }
     328           0 : }
     329             : 
     330             : 
     331             : 
     332             : } // namespace crpropa 
     333             : 
     334             : #endif // CRPROPA_VARIANT

Generated by: LCOV version 1.14