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: 2025-09-21 23:31:46 Functions: 50.9 % 30497 15518

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

Generated by: LCOV version 2.0-1