LCOV - code coverage report
Current view: top level - ugbase/registry - class.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 63.0 % 119 75
Test Date: 2026-06-01 23:54:59 Functions: 51.0 % 35226 17960

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       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              : 
      34              : #ifndef __H__UG_BRIDGE__CLASS__
      35              : #define __H__UG_BRIDGE__CLASS__
      36              : 
      37              : #include <cstdlib>
      38              : #include <cstring>
      39              : #include <string>
      40              : 
      41              : #include <type_traits> // for std::is_void
      42              : 
      43              : // std::optional is Cxx17 and not yet supported by all compilers, so we use boost::optional for now
      44              : #include <boost/optional.hpp> // for boost::optional
      45              : 
      46              : #include "parameter_stack.h"
      47              : #include "function_traits.h"
      48              : #include "global_function.h"
      49              : #include "common/common.h"
      50              : #include "error.h"
      51              : #include "registry_util.h"
      52              : 
      53              : #ifdef PROFILE_BRIDGE
      54              : #ifndef UG_PROFILER
      55              :         #error "You need to define UG_PROFILER to use PROFILE_BRIDGE"
      56              : #endif
      57              : #include "common/profiler/runtime_profile_info.h"
      58              : #else
      59              : #endif
      60              : 
      61              : 
      62              : namespace ug
      63              : {
      64              : namespace bridge
      65              : {
      66              : 
      67              : /// \addtogroup registry
      68              : /// \{
      69              : 
      70              : class MethodPtrWrapper
      71              : {
      72              :         public:
      73              :                 template <typename TMethod>
      74         4885 :                 MethodPtrWrapper(TMethod m)
      75              :                 {
      76         4885 :                         size = sizeof(TMethod);
      77         4885 :                         data = malloc(size);
      78              :                         memcpy(data, &m, size);
      79         4885 :                 }
      80              :                 
      81         4885 :                 MethodPtrWrapper(const MethodPtrWrapper& mpw)
      82         4885 :                 {
      83         4885 :                         size = mpw.size;
      84         4885 :                         data = malloc(size);
      85              :                         memcpy(data, mpw.get_raw_ptr(), size);
      86         4885 :                 }
      87              :                 
      88            0 :                 ~MethodPtrWrapper()     {free(data);}
      89              :                 
      90         4885 :                 void* get_raw_ptr() const {return data;}
      91              :                 
      92              :         protected:
      93              :                 void*   data;
      94              :                 int             size;
      95              : };
      96              : 
      97              : ///     Performs a reinterpret cast on the given pointer, then calls delete on it
      98            0 : template <class TClass> void CastAndDelete(const void* ptr)
      99              : {
     100            0 :         delete reinterpret_cast<const TClass*>(ptr);
     101            0 : }
     102              : 
     103            0 : template <> inline void CastAndDelete<void>(const void* ptr)
     104              : {
     105            0 :         UG_THROW("Can't delete instance of class 'void'");
     106              : }
     107              : 
     108              : 
     109              : /** function exported from ug
     110              :  * This class describes a wrapper for a c++ - function, that is exported by ug
     111              :  */
     112              : class ExportedMethod : public ExportedFunctionBase
     113              : {
     114              :         public:
     115              :         // all c++ functions are wrapped by a proxy function of the following type
     116              :                 typedef void (*ProxyFunc)(const MethodPtrWrapper& func, void* obj,
     117              :                                                                   const ParameterStack& in, ParameterStack& out);
     118              : 
     119              :         public:
     120         4885 :                 ExportedMethod( const MethodPtrWrapper& m, ProxyFunc pf,
     121              :                                                 const std::string& name, const std::string& className,
     122              :                                                 const std::string& methodOptions,
     123              :                                                 const std::string& retValInfos, const std::string& paramInfos,
     124              :                                                 const std::string& tooltip, const std::string& help)
     125         4885 :                 : ExportedFunctionBase(name, methodOptions, retValInfos, paramInfos, tooltip, help),
     126         4885 :                   m_ptrWrapper(m), m_proxy_func(pf), m_className(className)
     127              : #ifdef PROFILE_BRIDGE
     128              :                 ,m_dpi((m_className + ":" + name).c_str(), true, "registry", false)
     129              : #endif
     130              :                 {
     131         4885 :                 }
     132              : 
     133              :         /// executes the function
     134              :                 void execute(void* obj, const ParameterStack& paramsIn, ParameterStack& paramsOut) const
     135              :                 {
     136              : #ifdef PROFILE_BRIDGE
     137              :                         m_dpi.beginNode();
     138              : #endif
     139            0 :                         m_proxy_func(m_ptrWrapper, obj, paramsIn, paramsOut);
     140              : 
     141              : #ifdef PROFILE_BRIDGE
     142              :                         m_dpi.endNode();
     143              : #endif
     144            0 :                 }
     145              : 
     146              :         /// \todo: replace this method with a better integrated way.
     147              :                 template <typename TFunc>
     148              :                 void create_parameter_stack()
     149              :                 {
     150         4885 :                         ExportedFunctionBase::create_parameter_stack<TFunc>();
     151         4885 :                         m_customReturn = func_traits<TFunc>::custom_return;
     152              :                 }
     153              :                 
     154              :         ///     returns the class name this method belongs to
     155              :                 const std::string& class_name() const {return m_className;}
     156              : 
     157              :         /// returns true if this method handles its own return of values to lua
     158            0 :                 bool has_custom_return() const {return m_customReturn;}
     159              : 
     160              :         private:
     161              :         /// pointer to function (stored in a wrapper)
     162              :                 MethodPtrWrapper m_ptrWrapper;
     163              :         
     164              :         /// proxy function to call method
     165              :                 ProxyFunc m_proxy_func;
     166              : 
     167              :         /// name of class this method belongs to
     168              :                 std::string m_className;
     169              : 
     170              :                 bool m_customReturn;
     171              : 
     172              : #ifdef PROFILE_BRIDGE
     173              :                 mutable RuntimeProfileInfo m_dpi;
     174              : #endif
     175              : };
     176              : 
     177              : ////////////////////////////////////////////////////////////////////////////////
     178              : //      ExportedMethodGroup (sreiter)
     179              : ////////////////////////////////////////////////////////////////////////////////
     180              : 
     181              : ///     Groups of methods - useful to realize overloaded methods
     182              : class ExportedMethodGroup
     183              : {
     184              :         typedef ExportedMethod::ProxyFunc ProxyFunc;
     185              : 
     186              :         public:
     187         3981 :                 ExportedMethodGroup(const std::string& name) : m_name(name)
     188              :                 {}
     189              : 
     190         3981 :                 ~ExportedMethodGroup()
     191              :                 {
     192         8866 :                         for(size_t i = 0; i < m_overloads.size(); ++i)
     193         4885 :                                 delete m_overloads[i].m_func;
     194         3981 :                 }
     195              : 
     196              :         ///     name of function group
     197        18383 :                 const std::string& name() const {return m_name;}
     198              : 
     199              :         ///     adds an overload. Returns false if the overload already existed.
     200              :                 template <class TFunc>
     201         4885 :                 bool add_overload(      const TFunc& m, ProxyFunc pf,
     202              :                                         const std::string& className,
     203              :                                                         const std::string& methodOptions, const std::string& retValInfos,
     204              :                                                         const std::string& paramInfos, const std::string& tooltip,
     205              :                                                         const std::string& help)
     206              :                 {
     207         4885 :                         size_t typeID = GetUniqueTypeID<TFunc>();
     208              : 
     209              :                 //      make sure that the overload didn't exist
     210         4885 :                         if(get_overload_by_type_id(typeID))
     211              :                                 return false;
     212              : 
     213              :                 //      create a new overload
     214         9770 :                         ExportedMethod* func = new ExportedMethod(MethodPtrWrapper(m),
     215         4885 :                                                                                                 pf, m_name, className,
     216              :                                                                                                 methodOptions, retValInfos,
     217              :                                                                                                 paramInfos, tooltip, help);
     218              : 
     219         4885 :                         m_overloads.push_back(Overload(func, typeID));
     220              : 
     221              : 
     222              :                 //  create parameter in list
     223              :                         func->create_parameter_stack<TFunc>();
     224              : 
     225         4885 :                         return true;
     226              :                 }
     227              : 
     228              :                 size_t num_overloads() const {return m_overloads.size();}
     229              : 
     230            0 :                 ExportedMethod* get_overload(size_t index) {return m_overloads.at(index).m_func;}
     231              : 
     232            0 :                 const ExportedMethod* get_overload(size_t index) const {return m_overloads.at(index).m_func;}
     233              : 
     234              :                 template <class TType>
     235              :                 ExportedMethod* get_overload_by_type()
     236              :                 {
     237              :                         size_t typeID = GetUniqueTypeID<TType>();
     238              :                         return get_overload_by_type_id(typeID);
     239              :                 }
     240              : 
     241              :                 template <class TType>
     242              :                 const ExportedMethod* get_overload_by_type() const
     243              :                 {
     244              :                         size_t typeID = GetUniqueTypeID<TType>();
     245              :                         return get_overload_by_type_id(typeID);
     246              :                 }
     247              : 
     248              :                 ExportedMethod* get_overload_by_type_id(size_t typeID)
     249              :                 {
     250         7757 :                         for(size_t i = 0; i < m_overloads.size(); ++i){
     251         2872 :                                 if(m_overloads[i].m_typeID == typeID)
     252            0 :                                         return m_overloads[i].m_func;
     253              :                         }
     254              :                         return NULL;
     255              :                 }
     256              : 
     257              :                 const ExportedMethod* get_overload_by_type_id(size_t typeID) const
     258              :                 {
     259              :                         for(size_t i = 0; i < m_overloads.size(); ++i){
     260              :                                 if(m_overloads[i].m_typeID == typeID)
     261              :                                         return m_overloads[i].m_func;
     262              :                         }
     263              :                         return NULL;
     264              :                 }
     265              : 
     266              :                 size_t get_overload_type_id(size_t index) const {return m_overloads.at(index).m_typeID;}
     267              : 
     268              :         private:
     269              :                 struct Overload{
     270              :                         Overload()      {}
     271              :                         Overload(ExportedMethod* func, size_t typeID)
     272         4885 :                                 : m_func(func), m_typeID(typeID)
     273              :                         {}
     274              :                         ExportedMethod*         m_func;
     275              :                         size_t                          m_typeID;
     276              :                 };
     277              : 
     278              :                 std::string m_name;
     279              :                 std::vector<Overload>     m_overloads;
     280              : };
     281              : 
     282              : template <typename TClass, typename TMethod,
     283              :                   typename TRet = typename func_traits<TMethod>::return_type>
     284              : struct MethodProxy
     285              : {
     286            0 :         static void apply(const MethodPtrWrapper& method, void* obj,
     287              :                           const ParameterStack& in, ParameterStack& out)
     288              :         {
     289              :         //  cast to method pointer
     290            0 :                 TMethod mptr = *(TMethod*) method.get_raw_ptr();
     291              : 
     292              :         //  cast object to type
     293              :                 TClass* objPtr = (TClass*) (obj);
     294              : 
     295              :         //  get parameter
     296              :                 typedef typename func_traits<TMethod>::params_type params_type;
     297            0 :                 ParameterStackToTypeValueList<params_type> args(in);
     298              : 
     299              :         //  apply method
     300            0 :                 TRet res = func_traits<TMethod>::apply(mptr, objPtr, args);
     301              : 
     302              :         //  write return value
     303            0 :                 out.push<TRet>(res);
     304            0 :         }
     305              : };
     306              : 
     307              : template <typename TClass, typename TMethod>
     308              : struct MethodProxy<TClass, TMethod, void>
     309              : {
     310            0 :         static void apply(const MethodPtrWrapper& method, void* obj,
     311              :                           const ParameterStack& in, ParameterStack& out)
     312              :         {
     313              :         //  cast to method pointer
     314            0 :                 TMethod mptr = *(TMethod*) method.get_raw_ptr();
     315              : 
     316              :         //  cast object to type
     317              :                 TClass* objPtr = (TClass*) (obj);
     318              : 
     319              :         //  get parameter
     320              :                 typedef typename func_traits<TMethod>::params_type params_type;
     321            0 :                 ParameterStackToTypeValueList<params_type> args(in);
     322              : 
     323              :         //  apply method
     324            0 :                 func_traits<TMethod>::apply(mptr, objPtr, args);
     325            0 :         }
     326              : };
     327              : 
     328              : template <typename TClass, typename TMethod>
     329              : struct MethodProxy<TClass, TMethod, CustomReturn>
     330              : {
     331              :         static void apply(const MethodPtrWrapper& method, void* obj,
     332              :                           const ParameterStack& in, ParameterStack& out)
     333              :         {
     334              :         //  cast to method pointer
     335              :                 TMethod mptr = *(TMethod*) method.get_raw_ptr();
     336              : 
     337              :         //  cast object to type
     338              :                 TClass* objPtr = (TClass*) (obj);
     339              : 
     340              :         //  get parameter
     341              :                 typedef typename func_traits<TMethod>::params_type params_type;
     342              :                 ParameterStackToTypeValueList<params_type> args(in);
     343              : 
     344              :         //  apply method
     345              :                 func_traits<TMethod>::apply(mptr, objPtr, args);
     346              :         }
     347              : };
     348              : 
     349              : 
     350              : ////////////////////////////////////////////////////////////////////////////////
     351              : // Exported Constructor
     352              : ////////////////////////////////////////////////////////////////////////////////
     353              : 
     354              : /// describing information for constructor
     355              : class UG_API ExportedConstructor
     356              : {
     357              :         public:
     358              :         // all c++ functions are wrapped by a proxy function of the following type
     359              :                 typedef void* (*ProxyFunc)(const ParameterStack& in);
     360              : 
     361              :         public:
     362              :                 ExportedConstructor(ProxyFunc pf,
     363              :                                     const std::string& className, const std::string& options,
     364              :                                     const std::string& paramInfos,
     365              :                                     const std::string& tooltip, const std::string& help);
     366              : 
     367              :         /// executes the function
     368              :                 void* create(const ParameterStack& paramsIn) const
     369              :                 {
     370              : #ifdef PROFILE_BRIDGE
     371              :                         m_dpi.beginNode();
     372              : #endif
     373              : 
     374            0 :                         void *pRet = m_proxy_func(paramsIn);
     375              : 
     376              : #ifdef PROFILE_BRIDGE
     377              :                         m_dpi.endNode();
     378              : #endif
     379              :                         return pRet;
     380              :                 }
     381              : 
     382              :         ///     options
     383              :                 const std::string& options() const {return m_options;}
     384              : 
     385              :         /// number of parameters.
     386              :                 size_t num_parameter() const {return m_vvParamInfo.size();}
     387              : 
     388              :         ///     number of info strings for one parameter
     389              :                 size_t num_infos(size_t i) const {return m_vvParamInfo.at(i).size();}
     390              : 
     391              :         /// name of parameter i
     392            0 :                 const std::string& parameter_name(size_t i) const {return parameter_info(i, 0);}
     393              : 
     394              :         ///     type info of all parameters
     395            0 :                 const std::string& parameter_info(size_t i, size_t j) const {return m_vvParamInfo.at(i).at(j);}
     396              : 
     397              :         /// type info of i th parameters
     398              :                 const std::vector<std::string>& parameter_info_vec(size_t i) const {return m_vvParamInfo.at(i);}
     399              : 
     400              :         ///     whole string of all type infos for of all parameters
     401              :                 const std::string& parameter_info_string() const {return m_paramInfos;}
     402              : 
     403              :         /// gives some information to the exported functions
     404              :                 const std::string& tooltip() const {return m_tooltip;}
     405              : 
     406              :         /// help informations
     407              :                 const std::string& help() const {return m_help;}
     408              : 
     409              :         /// parameter list for input values
     410            0 :                 const ParameterInfo& params_in() const      {return m_paramsIn;}
     411              : 
     412              :         /// non-const export of param list
     413              :                 ParameterInfo& params_in() {return m_paramsIn;}
     414              : 
     415              :         /// returns true if all parameters of the function are correctly declared
     416              :                 bool check_consistency(std::string classname) const;
     417              : 
     418              :                 template <typename TFunc>
     419         1996 :                 void create_parameter_stack()
     420              :                 {
     421              :                         typedef typename func_traits<TFunc>::params_type params_type;
     422          332 :                         CreateParameterInfo<params_type>::create(m_paramsIn);
     423              : 
     424              :                 //      arbitrary choosen minimum number of infos exported
     425              :                 //      (If values non given we set them to an empty string)
     426              :                         const size_t MinNumInfos = 3; // for "name | style | options"
     427              : 
     428              :                 //      Fill missing Parameter
     429         1996 :                         m_vvParamInfo.resize(m_paramsIn.size());
     430              : 
     431              :                 //      resize missing infos for each parameter
     432         4667 :                         for(int i = 0; i < (int)m_vvParamInfo.size(); ++i)
     433         8980 :                                 for(size_t j = m_vvParamInfo.at(i).size(); j < MinNumInfos; ++j)
     434        12618 :                                         m_vvParamInfo.at(i).push_back(std::string(""));
     435         1996 :                 }
     436              : 
     437              :         protected:
     438              :         //      help function to tokenize the parameter string
     439              :                 void tokenize(const std::string& str, std::vector<std::string>& tokens,
     440              :                               const char delimiter);
     441              : 
     442              :         protected:
     443              :         private:
     444              :         /// proxy function to call method
     445              :                 ProxyFunc m_proxy_func;
     446              : 
     447              :         ///     name of class constructed
     448              :                 std::string m_className;
     449              : 
     450              :         ///     options
     451              :                 std::string m_options;
     452              : 
     453              :         /// string with Infos about parameter
     454              :                 std::string m_paramInfos;
     455              : 
     456              :         ///     tokenized strings for each Parameter and each Info (name | style | options | ...)
     457              :                 std::vector<std::vector<std::string> > m_vvParamInfo;
     458              : 
     459              :                 std::string m_tooltip;
     460              :                 std::string m_help;
     461              : 
     462              :                 ParameterInfo m_paramsIn;
     463              : 
     464              : #ifdef PROFILE_BRIDGE
     465              :                 mutable RuntimeProfileInfo m_dpi;
     466              : #endif
     467              : };
     468              : 
     469              : template <typename TClass, typename TMethod>
     470              : struct ConstructorProxy
     471              : {
     472            0 :         static void* create(const ParameterStack& in)
     473              :         {
     474              :         //  get parameter
     475              :                 typedef typename func_traits<TMethod>::params_type params_type;
     476            0 :                 ParameterStackToTypeValueList<params_type> args(in);
     477              : 
     478              :         //  apply method
     479            0 :                 TClass* newInst = constructor_traits<TClass, params_type>::apply(args);
     480              : 
     481              :         //  return new pointer
     482            0 :                 return (void*) newInst;
     483              :         }
     484              : };
     485              : 
     486              : template <typename TClass>
     487            0 : void DestructorProxy(void* obj)
     488              : {
     489              :         TClass* pObj = (TClass*)obj;
     490            0 :         delete pObj;
     491            0 : }
     492              : 
     493              : ////////////////////////////////////////////////////////////////////////////////
     494              : // Interface Exported Class
     495              : ////////////////////////////////////////////////////////////////////////////////
     496              : 
     497              : 
     498              : class JSONConstructible {};
     499              : 
     500              : /// Base class for exported Classes
     501              : class IExportedClass
     502              : {
     503              :         public:
     504              :                 typedef void (*DeleteFunction)(const void*);
     505              : 
     506              :         public:
     507              :         ///  name of class
     508              :                 virtual const std::string& name() const = 0;
     509              : 
     510              :         ///     get groups
     511              :                 virtual const std::string& group() const = 0;
     512              : 
     513              :         ///     name node of class
     514              :                 virtual const ClassNameNode& class_name_node() const = 0;
     515              : 
     516              :         /// get tooltip
     517              :                 virtual const std::string& tooltip() const = 0;
     518              : 
     519              :         ///     name-list of class hierarchy
     520              :                 virtual const std::vector<const char*>* class_names() const = 0;
     521              : 
     522              :         ///  number of method of the class
     523              :                 virtual size_t num_methods() const = 0;
     524              : 
     525              :         ///     number of registered const-methods
     526              :                 virtual size_t num_const_methods() const = 0;
     527              :                 
     528              :         ///  get exported method
     529              :                 virtual const ExportedMethod& get_method(size_t i) const = 0;
     530              : 
     531              :         /// get exported const-method
     532              :                 virtual const ExportedMethod& get_const_method(size_t i) const = 0;
     533              :                 
     534              :         ///     returns the number of overloads of a method
     535              :                 virtual size_t num_overloads(size_t funcInd) const = 0;
     536              : 
     537              :         ///     returns the number of overloads of a const method
     538              :                 virtual size_t num_const_overloads(size_t funcInd) const = 0;
     539              : 
     540              :         ///     returns the i-th overload of a method
     541              :                 virtual const ExportedMethod& get_overload(size_t funcInd, size_t oInd) const = 0;
     542              : 
     543              :         ///     returns the i-th overload of a const method
     544              :                 virtual const ExportedMethod& get_const_overload(size_t funcInd, size_t oInd) const = 0;
     545              : 
     546              :         ///     returns the i-th method group (all overloads of the i-th function)
     547              :                 virtual const ExportedMethodGroup& get_method_group(size_t ind) const = 0;
     548              : 
     549              :         ///     returns the i-th method group (all overloads of the i-th function)
     550              :                 virtual const ExportedMethodGroup& get_const_method_group(size_t ind) const = 0;
     551              : 
     552              :                 virtual const ExportedMethodGroup* get_exported_method_group(const std::string& name) const = 0;
     553              : 
     554              :                 virtual const ExportedMethodGroup* get_const_exported_method_group(const std::string& name) const = 0;
     555              : 
     556              :         /**  can we create instances of this class
     557              :          *      (i.e. the class does not contain pure virtual functions)*/
     558              :                 virtual bool is_instantiable() const = 0;
     559              : 
     560              :         ///     number of registered constructors
     561              :                 virtual size_t num_constructors() const = 0;
     562              : 
     563              :         ///     get exported constructor
     564              :                 virtual const ExportedConstructor& get_constructor(size_t i) const = 0;
     565              : 
     566              :         /// get constructor for construction from json
     567              :                 virtual const boost::optional<ExportedConstructor&> get_json_constructor() const = 0;
     568              : 
     569              :         /// get constructor for construction from json
     570              :                 virtual bool is_json_constructible() const = 0;
     571              : 
     572              :         ///     true if the class shall be wrapped in a SmartPtr on construction
     573              :                 virtual bool construct_as_smart_pointer() const = 0;
     574              : 
     575              :         ///     destructur for object
     576              :                 virtual void destroy(void* obj) const = 0;
     577              : 
     578              :         ///     returns a function which will call delete on the object
     579              :                 virtual DeleteFunction get_delete_function() const = 0;
     580              : 
     581              :         ///     returns false is consistency-check failed
     582              :                 virtual bool check_consistency() const;
     583              : 
     584              :         ///  virtual destructor
     585              :                 virtual ~IExportedClass() {};
     586              : };
     587              : 
     588              : ///     A base implementation with non-template methods.
     589              : /**     Speeds up compilation times.*/
     590              : class ExportedClassBaseImpl : public IExportedClass
     591              : {
     592              :         private:
     593              :         //  disallow
     594              :                 ExportedClassBaseImpl();
     595              :                 ExportedClassBaseImpl(const ExportedClassBaseImpl& other);
     596              : 
     597              :         public:
     598              :                 ExportedClassBaseImpl(const std::string& tooltip);
     599              : 
     600              :         /// destructor
     601              :                 virtual ~ExportedClassBaseImpl();
     602              : 
     603              :         /// tooltip
     604              :                 virtual const std::string& tooltip() const;
     605              : 
     606              :         /// number of registered methods (overloads are not counted)
     607              :                 virtual size_t num_methods() const;
     608              : 
     609              :         ///     number of registered const-methods (overloads are not counted)
     610              :                 virtual size_t num_const_methods() const;
     611              : 
     612              :         /// returns the first overload of an exported function
     613              :                 virtual const ExportedMethod& get_method(size_t i) const;
     614              : 
     615              :         /// returns the first overload of an exported const function
     616              :                 virtual const ExportedMethod& get_const_method(size_t i) const;
     617              : 
     618              :         ///     returns the number of overloads of a method
     619              :                 virtual size_t num_overloads(size_t funcInd) const;
     620              : 
     621              :         ///     returns the number of overloads of a const method
     622              :                 virtual size_t num_const_overloads(size_t funcInd) const;
     623              : 
     624              :         ///     returns the i-th overload of a method
     625              :                 virtual const ExportedMethod& get_overload(size_t funcInd, size_t oInd) const;
     626              : 
     627              :         ///     returns the i-th overload of a const method
     628              :                 virtual const ExportedMethod& get_const_overload(size_t funcInd, size_t oInd) const;
     629              : 
     630              :         ///     returns the i-th method group (all overloads of the i-th function)
     631              :                 virtual const ExportedMethodGroup& get_method_group(size_t ind) const;
     632              : 
     633              :         ///     returns the i-th method group (all overloads of the i-th function)
     634              :                 virtual const ExportedMethodGroup& get_const_method_group(size_t ind) const;
     635              : 
     636              :                 virtual const ExportedMethodGroup* get_exported_method_group(const std::string& name) const;
     637              : 
     638              :                 virtual const ExportedMethodGroup* get_const_exported_method_group(const std::string& name) const;
     639              : 
     640              :         ///     number of registered constructors
     641              :                 virtual size_t num_constructors() const;
     642              : 
     643              :         ///     get exported constructor
     644              :                 virtual const ExportedConstructor& get_constructor(size_t i) const;
     645              : 
     646              :         /// get constructor for construction from json
     647              :                 virtual const boost::optional<ExportedConstructor&> get_json_constructor() const;
     648              : 
     649              :         ///     returns whether the class shall be wrapped in a SmartPtr on construction
     650              :                 virtual bool construct_as_smart_pointer() const;
     651              : 
     652              :         ///     sets whether the class shall be wrapped in a SmartPtr
     653              :         /**     Returns a reference to this, so that it can be used in a chained call.*/
     654              :                 virtual void set_construct_as_smart_pointer(bool enable);
     655              : 
     656              :         /// is instantiable
     657              :                 virtual bool is_instantiable() const;
     658              : 
     659              :         ///     destructur for object
     660              :                 virtual void destroy(void* obj) const;
     661              : 
     662              :         protected:
     663              :         ///     returns if a constructor overload is registered
     664              :                 bool constructor_type_id_registered(size_t typeID);
     665              : 
     666              :         /// returns true if methodname is already used by a method in this class
     667              :                 bool constmethodname_registered(const std::string& name);
     668              : 
     669              :         /// returns true if methodname is already used by a method in this class
     670              :                 bool methodname_registered(const std::string& name);
     671              : 
     672              :                 ExportedMethodGroup* get_exported_method_group(const std::string& name);
     673              : 
     674              :                 ExportedMethodGroup* get_const_exported_method_group(const std::string& name);
     675              : 
     676              :         protected:
     677              :                 struct ConstructorOverload{
     678              :                         ConstructorOverload()   {}
     679              :                         ConstructorOverload(ExportedConstructor* func, size_t typeID)
     680         1996 :                                 : m_constructor(func), m_typeID(typeID)
     681              :                         {}
     682              :                         ExportedConstructor*    m_constructor;
     683              :                         size_t                                  m_typeID;
     684              :                 };
     685              : 
     686              :                 std::vector<ConstructorOverload> m_vConstructor;
     687              : 
     688              :                 typedef void (*DestructorFunc)(void*);
     689              :                 DestructorFunc m_destructor;
     690              : 
     691              :                 std::vector<ExportedMethodGroup*> m_vMethod;
     692              :                 std::vector<ExportedMethodGroup*> m_vConstMethod;
     693              :                 std::string m_tooltip;
     694              : 
     695              :                 bool    m_constructAsSmartPtr;
     696              : };
     697              : 
     698              : 
     699              : ///     This template class represents real c++ classes in the registry.
     700              : template <typename TClass>
     701              : class ExportedClass : public ExportedClassBaseImpl
     702              : {
     703              :         private:
     704              :         //  disallow
     705              :                 ExportedClass () {};
     706              :                 ExportedClass (const ExportedClass& other);
     707              : 
     708              :         public:
     709              :         //  contructor
     710         1562 :                 ExportedClass(const std::string& name, const std::string& group,
     711              :                                const std::string& tooltip)
     712         1562 :                                 : ExportedClassBaseImpl(tooltip)
     713              :                 {
     714         1562 :                         ClassNameProvider<TClass>::set_name(name, group, true);
     715         1562 :                         ClassNameProvider<const TClass>::set_name(name, group, true);
     716         1562 :                 }
     717              : 
     718              :         /// destructor
     719         1562 :                 virtual ~ExportedClass(){}
     720              : 
     721              :         /// name of class
     722      4716347 :                 virtual const std::string& name() const {return ClassNameProvider<TClass>::name();}
     723              : 
     724              :         ///     name node of class
     725            0 :                 virtual const ClassNameNode& class_name_node() const {return ClassNameProvider<TClass>::class_name_node();}
     726              : 
     727              :         ///     get groups
     728            0 :                 virtual const std::string& group() const {return ClassNameProvider<TClass>::group();}
     729              : 
     730              :         /// is json constructible
     731            0 :                 virtual bool is_json_constructible() const { return std::is_base_of<JSONConstructible, TClass>::value; }
     732              : 
     733              :         //\todo: remove this method, use class name nodes instead
     734              :         ///     class-hierarchy
     735            0 :                 virtual const std::vector<const char*>* class_names() const       {return &ClassNameProvider<TClass>::names();}
     736              : 
     737              :                 template<typename T>
     738              :                 ExportedClass<TClass>& add_(T t)
     739              :                 {
     740              :                         return t.add_to(*this);
     741              :                 }
     742              :         /// Method registration
     743              :         /**
     744              :          * @param methodName the name of the method to appear in the registry
     745              :          * @param func pointer to the member function (e.g. &MyClass::my_method)
     746              :          * @param retValInfos string documenting what the function returns (optional)
     747              :          * @param paramInfos string documenting the parameters of the function
     748              :          * seperate parameters with an # e.g. "x#y#z" (don't specify the type of the values)  (optional)
     749              :          * @param toolTip small documentation for the function (optional)
     750              :          * @param help help string for the function
     751              :          * @sa \ref pageUG4Registry
     752              :          * @sa \ref secSTHowToSpecifyParameterInformation
     753              :          */
     754              :                 template <typename TMethod>
     755         4885 :                 ExportedClass<TClass>& add_method (std::string methodName, TMethod func,
     756              :                                                     std::string retValInfos = "", std::string paramInfos = "",
     757              :                                                     std::string tooltip = "", std::string help = "")
     758              :                 {
     759              :                 //      At this point the method name contains parameters (name|param1=...).
     760              :                 //todo: they should be removed and specified with an extra parameter.
     761              : 
     762              :                         std::string strippedMethodName = methodName;
     763              :                         std::string methodOptions;
     764              :                         std::string::size_type pos = strippedMethodName.find("|");
     765         4885 :                         if(pos != std::string::npos){
     766           15 :                                 methodOptions = strippedMethodName.substr(pos + 1, strippedMethodName.length() - pos);
     767           30 :                                 strippedMethodName = strippedMethodName.substr(0, pos);
     768              :                         }
     769              : 
     770              :                 //      trim whitespaces
     771         4885 :                         strippedMethodName = TrimString(strippedMethodName);
     772         9770 :                         methodOptions = TrimString(methodOptions);
     773              : 
     774              :                 //      check that name is not empty
     775         4885 :                         if(strippedMethodName.empty())
     776              :                         {
     777            0 :                                 UG_THROW_REGISTRY_ERROR(strippedMethodName,
     778              :                                         "Trying to register empty method name.");
     779              :                         }
     780              :                         
     781              :                         // check that name does not contain illegal characters
     782         4885 :                         if (!IsValidRegistryIdentifier(strippedMethodName)) {
     783            0 :                                 UG_THROW_REGISTRY_ERROR(strippedMethodName,
     784              :                                 "Trying to register method '"<< strippedMethodName << "' that"
     785              :                                 << " contains illegal characters. "
     786              :                                 << GetRegistryIdentifierMessage());
     787              :                         }
     788              : 
     789              :                 //      if the method is already in use, we have to add an overload.
     790              :                 //      If not, we have to create a new method group
     791              :                         ExportedMethodGroup* methodGrp = NULL;
     792              :                         if(func_traits<TMethod>::const_method)
     793          668 :                                 methodGrp = get_const_exported_method_group(strippedMethodName);
     794              :                         else
     795         4217 :                                 methodGrp = get_exported_method_group(strippedMethodName);
     796              : 
     797         4885 :                         if(!methodGrp){
     798         3981 :                                 methodGrp = new ExportedMethodGroup(strippedMethodName);
     799              :                                 if(func_traits<TMethod>::const_method)
     800          643 :                                         m_vConstMethod.push_back(methodGrp);
     801              :                                 else
     802         3338 :                                         m_vMethod.push_back(methodGrp);
     803              :                         }
     804              : 
     805         4885 :                         bool success = methodGrp->add_overload(func, &MethodProxy<TClass, TMethod>::apply,
     806              :                                                                                                    ClassNameProvider<TClass>::name(),
     807              :                                                                                                    methodOptions, retValInfos, paramInfos,
     808              :                                                                                                    tooltip, help);
     809              : 
     810         4885 :                         if(!success)
     811              :                         {
     812            0 :                                 UG_THROW_REGISTRY_ERROR(name(),
     813              :                                 "Trying to register method name '" << strippedMethodName
     814              :                                 << "' to class '" << name() << "', but another method with this name "
     815              :                                 << " and the same function signature is already registered for this class.");
     816              :                         }
     817              : 
     818         4885 :                         return *this;
     819              :                 }
     820              : 
     821              :         /// Make default constructor accessible
     822          454 :                 ExportedClass<TClass>& add_constructor ()
     823              :                 {
     824              :                 //      add also in new style
     825          908 :                         add_constructor<void (*)()>();
     826              : 
     827              :                 //  remember constructor proxy
     828          454 :                         m_destructor = &DestructorProxy<TClass>;
     829              : 
     830          454 :                         return *this;
     831              :                 }
     832              : 
     833              :         /// constructor registration
     834              :         /**
     835              :          * @param paramInfos string documenting the parameters of the function
     836              :          * seperate parameters with an # e.g. "x#y#z" (don't specify the type of the values)  (optional)
     837              :          * @param toolTip small documentation for the function (optional)
     838              :          * @param help help string for the function
     839              :          * @param options style option of the constructor itself (for visualisation)
     840              :          * @sa \ref pageUG4Registry
     841              :          */
     842              :                 template <typename TFunc>
     843         1996 :                 ExportedClass<TClass>& add_constructor(std::string paramInfos = "",
     844              :                                                        std::string tooltip = "", std::string help = "",
     845              :                                                        std::string options = "")
     846              :                 {
     847              :                 //      return-type must be void
     848              :                         if(!(std::is_void< typename func_traits<TFunc>::return_type >::value))
     849              :                         {
     850              :                                 UG_THROW_REGISTRY_ERROR(name(),
     851              :                                 "Trying to register constructor of class "
     852              :                                  <<name()<<"with non-void return value in signature function.");
     853              :                         }
     854              : 
     855              :                 //      type id of constructor
     856         1996 :                         size_t typeID = GetUniqueTypeID<TFunc>();
     857              : 
     858              :                 //      make sure that the overload didn't exist
     859         1996 :                         if(constructor_type_id_registered(typeID))
     860              :                         {
     861            0 :                                 UG_THROW_REGISTRY_ERROR(name(),
     862              :                                 "Trying to register constructor of class "
     863              :                                  <<name()<<" with same signature twice.");
     864              :                         }
     865              : 
     866              :                 //      create new exported constructor
     867              :                         ExportedConstructor* expConstr
     868         3992 :                                 = new ExportedConstructor(      &ConstructorProxy<TClass, TFunc>::create,
     869              :                                                                 ClassNameProvider<TClass>::name(),
     870              :                                                                                         options, paramInfos, tooltip, help);
     871              : 
     872              :                 //      create parameter stack
     873         1996 :                         expConstr->create_parameter_stack<TFunc>();
     874              : 
     875              :                 //      rememeber it
     876         1996 :                         m_vConstructor.push_back(ConstructorOverload(expConstr, typeID));
     877              : 
     878              :                 //      done
     879         1996 :                         return *this;
     880              :                 }
     881              : 
     882              :         ///     return pointer to the delete method
     883            0 :                 virtual DeleteFunction get_delete_function() const
     884              :                 {
     885            0 :                         return CastAndDelete<TClass>;
     886              :                 }
     887              : };
     888              : 
     889              : // end group registry
     890              : /// \}
     891              : 
     892              : } // end namespace bridge
     893              : } // end namespace ug
     894              : 
     895              : 
     896              : #endif /* __H__UG_BRIDGE__CLASS__ */
        

Generated by: LCOV version 2.0-1