LCOV - code coverage report
Current view: top level - ugbase/common/util - variant.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 237 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 34 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2012-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include "common/error.h"
      34              : #include "variant.h"
      35              : 
      36              : #include <iostream>
      37              : #define untested() ( std::cerr <<  "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \
      38              :           <<":" << __func__ << "\n" )
      39              : 
      40              : using namespace std;
      41              : 
      42              : namespace ug{
      43              : 
      44            0 : Variant::Variant() :
      45            0 :         m_type(VT_INVALID)
      46            0 : {}
      47              : 
      48            0 : Variant::Variant(bool val) :
      49            0 :         m_bool(val),
      50            0 :         m_type(VT_BOOL)
      51            0 : {}
      52              : 
      53            0 : Variant::Variant(int val) :
      54            0 :         m_int(val),
      55            0 :         m_type(VT_INT)
      56            0 : {}
      57              : 
      58            0 : Variant::Variant(size_t val) :
      59            0 :         m_size_t(val),
      60            0 :         m_type(VT_SIZE_T)
      61            0 : {}
      62              : 
      63            0 : Variant::Variant(float val) :
      64            0 :         m_float(val),
      65            0 :         m_type(VT_FLOAT)
      66            0 : {}
      67              : 
      68            0 : Variant::Variant(double val) :
      69            0 :         m_double(val),
      70            0 :         m_type(VT_DOUBLE)
      71            0 : {}
      72              : 
      73            0 : Variant::Variant(const char* val) :
      74            0 :         m_cstring(val),
      75            0 :         m_type(VT_CSTRING)
      76            0 : {}
      77              : 
      78            0 : Variant::Variant(const std::string& val) :
      79            0 :         m_stdstring(new string(val)),
      80            0 :         m_type(VT_STDSTRING)
      81            0 : {}
      82              : 
      83            0 : Variant::Variant(void* val) :
      84            0 :         m_pointer(val),
      85            0 :         m_type(VT_POINTER)
      86            0 : {}
      87              : 
      88            0 : Variant::Variant(const void* val) :
      89            0 :         m_constptr(val),
      90            0 :         m_type(VT_CONST_POINTER)
      91            0 : {}
      92              : 
      93            0 : Variant::Variant(const SmartPtr<void>& val) :
      94            0 :         m_smartptr(new SmartPtr<void>(val)),
      95            0 :         m_type(VT_SMART_POINTER)
      96            0 : {}
      97              : 
      98            0 : Variant::Variant(const ConstSmartPtr<void>& val) :
      99            0 :         m_constsmartptr(new ConstSmartPtr<void>(val)),
     100            0 :         m_type(VT_CONST_SMART_POINTER)
     101            0 : {}
     102              : 
     103              : #ifdef UG_FOR_LUA
     104            0 : Variant::Variant(LuaFunctionHandle val) :
     105            0 :         m_luafcthandle(val),
     106            0 :         m_type(VT_LUA_FUNCTION_HANDLE)
     107            0 : {}
     108            0 : Variant::Variant(LuaTableHandle val) :
     109            0 :         m_luatblhandle(val),
     110            0 :         m_type(VT_LUA_TABLE_HANDLE)
     111            0 : {}
     112              : #endif
     113              : 
     114            0 : Variant::Variant(const Variant& v) : m_type(VT_INVALID)
     115              : {
     116            0 :         assign_variant(v);
     117            0 : }
     118              : 
     119            0 : Variant::~Variant()
     120              : {
     121            0 :         if(m_type == VT_STDSTRING)
     122            0 :                 delete m_stdstring;
     123              : 
     124            0 :         if(m_type == VT_SMART_POINTER)
     125            0 :                 delete m_smartptr;
     126            0 :         if(m_type == VT_CONST_SMART_POINTER)
     127            0 :                 delete m_constsmartptr;
     128            0 : }
     129              : 
     130            0 : const Variant& Variant::operator=(const Variant& v)
     131              : {
     132              : //      if the variant encapsulates an std::string or a smartptr,
     133              : //      we first have to delete the     old instance
     134            0 :         if(m_type == VT_STDSTRING)
     135            0 :                 delete m_stdstring;
     136            0 :         if(m_type == VT_SMART_POINTER)
     137            0 :                 delete m_smartptr;
     138            0 :         if(m_type == VT_CONST_SMART_POINTER)
     139            0 :                 delete m_constsmartptr;
     140              : 
     141              : //      now assign the new value
     142            0 :         assign_variant(v);
     143              : 
     144              : //      done. return reference to this
     145            0 :         return *this;
     146              : }
     147              : 
     148            0 : void Variant::assign_variant(const Variant& v)
     149              : {
     150              : #ifdef UG_FOR_LUA
     151              :         // need std::variant behaviour in order to be able to
     152              :         // work with objects.
     153            0 :         if(m_type == VT_LUA_TABLE_HANDLE && v.m_type != m_type){ untested();
     154            0 :                 m_luatblhandle.~LuaTableHandle();
     155            0 :         }else if(m_type == VT_LUA_TABLE_HANDLE && v.m_type == m_type){ untested();
     156              :                 // assign.
     157            0 :                 m_luatblhandle = v.m_luatblhandle;
     158            0 :         }else if(v.m_type == VT_LUA_TABLE_HANDLE && v.m_type != m_type){
     159              :                 // create in place, reuse memory.
     160            0 :                 new (&m_luatblhandle) LuaTableHandle(v.m_luatblhandle);
     161              :         }else{
     162              :         }
     163              : #endif
     164            0 :         switch(v.m_type){
     165            0 :                 case VT_BOOL:
     166            0 :                         m_bool = v.m_bool;
     167            0 :                         break;
     168            0 :                 case VT_INT:
     169            0 :                         m_int = v.m_int;
     170            0 :                         break;
     171            0 :                 case VT_SIZE_T:
     172            0 :                         m_size_t = v.m_size_t;
     173            0 :                         break;
     174            0 :                 case VT_FLOAT:
     175            0 :                         m_float = v.m_float;
     176            0 :                         break;
     177            0 :                 case VT_DOUBLE:
     178            0 :                         m_double = v.m_double;
     179            0 :                         break;
     180            0 :                 case VT_CSTRING:
     181            0 :                         m_cstring = v.m_cstring;
     182            0 :                         break;
     183            0 :                 case VT_STDSTRING:
     184            0 :                         m_stdstring = new string;
     185            0 :                         *m_stdstring = *v.m_stdstring;
     186              :                         break;
     187            0 :                 case VT_POINTER:
     188            0 :                         m_pointer = v.m_pointer;
     189            0 :                         break;
     190            0 :                 case VT_CONST_POINTER:
     191            0 :                         m_constptr = v.m_constptr;
     192            0 :                         break;
     193            0 :                 case VT_SMART_POINTER:
     194            0 :                         m_smartptr = new SmartPtr<void>(*v.m_smartptr);
     195            0 :                         break;
     196            0 :                 case VT_CONST_SMART_POINTER:
     197            0 :                         m_constsmartptr = new ConstSmartPtr<void>(*v.m_constsmartptr);
     198            0 :                         break;
     199              : #ifdef UG_FOR_LUA
     200            0 :                 case VT_LUA_FUNCTION_HANDLE:
     201            0 :                         m_luafcthandle = v.m_luafcthandle;
     202            0 :                         break;
     203              :                 case VT_LUA_TABLE_HANDLE:
     204              :                         break;
     205              : #endif
     206              :                 default:
     207              :                         break;
     208              :         }
     209              : 
     210            0 :         m_type = v.m_type;
     211            0 : }
     212              : 
     213            0 : bool Variant::to_bool() const
     214              : {
     215            0 :         switch(m_type){
     216            0 :                 case VT_BOOL:   return m_bool;
     217            0 :                 case VT_INT:    return m_int != 0;
     218            0 :                 case VT_SIZE_T: return m_size_t != 0;
     219            0 :                 case VT_FLOAT:  return m_float != 0;
     220            0 :                 case VT_DOUBLE: return m_double != 0;
     221              :                 default: break;
     222              :         }
     223              : 
     224            0 :         UG_THROW("Variant: can't convert " << type_name() << " to bool.");
     225              : //      this should never be reached
     226              :         return false;
     227              : }
     228              : 
     229            0 : int Variant::to_int() const
     230              : {
     231            0 :         switch(m_type){
     232            0 :                 case VT_BOOL:   return (int)m_bool;
     233            0 :                 case VT_INT:    return m_int;
     234            0 :                 case VT_SIZE_T: return (int)m_size_t;
     235            0 :                 case VT_FLOAT:  return (int)m_float;
     236            0 :                 case VT_DOUBLE: return (int)m_double;
     237              :                 default: break;
     238              :         }
     239              : 
     240            0 :         UG_THROW("Variant: can't convert " << type_name() << " to int.");
     241              : //      this should never be reached
     242              :         return 0;
     243              : }
     244              : 
     245            0 : size_t Variant::to_size_t() const
     246              : {
     247              :         // note: we only allow save casts, i.e. not int->size_t
     248            0 :         switch(m_type){
     249            0 :                 case VT_BOOL:   return (size_t)m_bool;
     250            0 :                 case VT_SIZE_T: return m_size_t;
     251              :                 default: break;
     252              :         }
     253              : 
     254            0 :         UG_THROW("Variant: can't convert " << type_name() << " to int.");
     255              : //      this should never be reached
     256              :         return 0;
     257              : }
     258              : 
     259            0 : float Variant::to_float() const
     260              : {
     261            0 :         switch(m_type){
     262            0 :                 case VT_BOOL:   return (float)m_bool;
     263            0 :                 case VT_INT:    return (float)m_int;
     264            0 :                 case VT_SIZE_T: return (float)m_size_t;
     265            0 :                 case VT_FLOAT:  return m_float;
     266            0 :                 case VT_DOUBLE: return (float)m_double;
     267              :                 default: break;
     268              :         }
     269              : 
     270            0 :         UG_THROW("Variant: can't convert " << type_name() << " to float.");
     271              : //      this should never be reached
     272              :         return 0;
     273              : }
     274              : 
     275            0 : number Variant::to_number() const
     276              : {
     277            0 :         switch(m_type){
     278            0 :                 case VT_BOOL:   return (number)m_bool;
     279            0 :                 case VT_INT:    return (number)m_int;
     280            0 :                 case VT_SIZE_T: return (number)m_size_t;
     281            0 :                 case VT_FLOAT:  return (number)m_float;
     282            0 :                 case VT_DOUBLE: return (number)m_double;
     283              :                 default: break;
     284              :         }
     285              : 
     286            0 :         UG_THROW("Variant: can't convert " << type_name() << " to number.");
     287              : //      this should never be reached
     288              :         return 0;
     289              : }
     290              : 
     291            0 : double Variant::to_double() const
     292              : {
     293            0 :         switch(m_type){
     294            0 :                 case VT_BOOL:   return (double)m_bool;
     295            0 :                 case VT_INT:    return (double)m_int;
     296            0 :                 case VT_SIZE_T: return (double)m_size_t;
     297            0 :                 case VT_FLOAT:  return (double)m_float;
     298            0 :                 case VT_DOUBLE: return m_double;
     299              :                 default: break;
     300              :         }
     301              : 
     302            0 :         UG_THROW("Variant: can't convert " << type_name() << " to double.");
     303              : //      this should never be reached
     304              :         return 0;
     305              : }
     306              : 
     307            0 : const char* Variant::to_c_string() const
     308              : {
     309            0 :         if(m_type == VT_CSTRING)
     310            0 :                 return m_cstring;
     311              : 
     312            0 :         if(m_type == VT_STDSTRING)
     313            0 :                 return m_stdstring->c_str();
     314              : 
     315            0 :         UG_THROW("Variant: can't convert " << type_name() << " to cstring.");
     316              : //      this should never be reached
     317              :         return 0;
     318              : }
     319              : 
     320            0 : const std::string& Variant::to_std_string() const
     321              : {
     322            0 :         if(m_type == VT_STDSTRING)
     323            0 :                 return *m_stdstring;
     324              : 
     325            0 :         UG_THROW("Variant: can't convert " << type_name() << " to stdstring.");
     326              : //      this should never be reached
     327              :         return *m_stdstring;
     328              : }
     329              : 
     330            0 : void* Variant::to_pointer() const
     331              : {
     332            0 :         if(m_type == VT_POINTER)
     333            0 :                 return m_pointer;
     334              : 
     335            0 :         UG_THROW("Variant: can't convert " << type_name() << " to pointer.");
     336              : }
     337              : 
     338            0 : const void* Variant::to_const_pointer() const
     339              : {
     340            0 :         if(m_type == VT_CONST_POINTER)
     341            0 :                 return m_constptr;
     342              : 
     343            0 :         if(m_type == VT_POINTER)
     344            0 :                 return const_cast<const void*>(m_pointer);
     345              : 
     346            0 :         UG_THROW("Variant: can't convert " << type_name() << " to const pointer.");
     347              : }
     348              : 
     349            0 : SmartPtr<void> Variant::to_smart_pointer() const
     350              : {
     351            0 :         if(m_type == VT_SMART_POINTER)
     352            0 :                 return *m_smartptr;
     353              : 
     354            0 :         UG_THROW("Variant: can't convert " << type_name() << " to smart pointer.");
     355              : }
     356              : 
     357            0 : ConstSmartPtr<void> Variant::to_const_smart_pointer() const
     358              : {
     359            0 :         if(m_type == VT_CONST_SMART_POINTER)
     360            0 :                 return *m_constsmartptr;
     361              : 
     362            0 :         if(m_type == VT_SMART_POINTER)
     363            0 :                 return *m_smartptr;
     364              : 
     365            0 :         UG_THROW("Variant: can't convert " << type_name() << " to const smart pointer.");
     366              : }
     367              : 
     368              : #ifdef UG_FOR_LUA
     369            0 : LuaFunctionHandle Variant::to_lua_function_handle() const
     370              : {
     371            0 :         return m_luafcthandle;
     372              : }
     373            0 : LuaTableHandle Variant::to_lua_table_handle() const
     374              : {
     375            0 :         return m_luatblhandle;
     376              : }
     377              : #endif
     378              : 
     379            0 : const char* Variant::type_name() const
     380              : {
     381            0 :         switch(m_type){
     382              :                 case VT_INVALID:        return "invalid_type";
     383            0 :                 case VT_BOOL:           return "bool";
     384            0 :                 case VT_SIZE_T:         return "size_t";
     385            0 :                 case VT_INT:            return "int";
     386            0 :                 case VT_FLOAT:          return "float";
     387            0 :                 case VT_DOUBLE:         return "double";
     388            0 :                 case VT_CSTRING:        return "cstring";
     389            0 :                 case VT_STDSTRING:      return "stdstring";
     390            0 :                 case VT_POINTER:        return "pointer";
     391            0 :                 case VT_CONST_POINTER:  return "constpointer";
     392            0 :                 case VT_SMART_POINTER:  return "smartpointer";
     393            0 :                 case VT_CONST_SMART_POINTER:    return "constsmartpointer";
     394              : 
     395            0 :                 default: return "unknown_type";
     396              :         }
     397              : }
     398              : 
     399              : }//     end of namespace
     400              : 
     401            0 : std::ostream& operator<< (std::ostream& outStream, const ug::Variant& v)
     402              : {
     403              :         using namespace ug;
     404              :         // TODO?: hide enum
     405            0 :         switch(v.type()){
     406            0 :                 case Variant::VT_BOOL:
     407            0 :                         if(v.to_bool())
     408            0 :                                 outStream << "true";
     409              :                         else
     410            0 :                                 outStream << "false";
     411              :                         break;
     412            0 :                 case Variant::VT_INT:
     413            0 :                         outStream << v.to_int();
     414            0 :                         break;
     415            0 :                 case Variant::VT_SIZE_T:
     416            0 :                         outStream << v.to_size_t();
     417              :                         break;
     418            0 :                 case Variant::VT_FLOAT:
     419            0 :                         outStream << v.to_float();
     420              :                         break;
     421            0 :                 case Variant::VT_DOUBLE:
     422            0 :                         outStream << v.to_double();
     423              :                         break;
     424            0 :                 case Variant::VT_CSTRING:
     425            0 :                         outStream << v.to_c_string();
     426            0 :                         break;
     427            0 :                 case Variant::VT_STDSTRING:
     428            0 :                         outStream << v.to_std_string();
     429              :                         break;
     430            0 :                 default:
     431            0 :                         outStream << "?";
     432              :         }
     433            0 :         return outStream;
     434              : }
        

Generated by: LCOV version 2.0-1