ug4
registry_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3  * Authors: Andreas Vogel, Sebastian Reiter
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__UG_BRIDGE__REGISTRY_IMPL__
34 #define __H__UG_BRIDGE__REGISTRY_IMPL__
35 
36 #include "registry_util.h"
37 #include "common/util/typename.h"
38 
39 namespace ug{
40 namespace bridge
41 {
42 
44 // global functions
46 // template<typename TClass>
47 // struct AddTypeName
48 // {
49 // static void add(std::string &s)
50 // {
51 // #ifdef UG_POSIX
52 // if(s.length() != 0)
53 // s += std::string(", ");
54 // s += std::string("C++ Name: ") + TypeName<TClass>();
55 // #endif
56 // }
57 // };
58 
59 template<class TFunc>
61 add_function(std::string funcName, TFunc func, std::string group,
62  std::string retValInfos, std::string paramInfos,
63  std::string tooltip, std::string help)
64 {
65  add_and_get_function(funcName, func, group, retValInfos, paramInfos,
66  tooltip, help);
67  return *this;
68 }
69 
70 template<class TFunc>
72 add_and_get_function(std::string funcName, TFunc func, std::string group,
73  std::string retValInfos, std::string paramInfos,
74  std::string tooltip, std::string help)
75 {
76 // At this point the method name contains parameters (name|param1=...).
77 //todo: they should be removed and specified with an extra parameter.
78 
79  std::string strippedMethodName = funcName;
80  std::string methodOptions;
81  std::string::size_type pos = strippedMethodName.find("|");
82  if(pos != std::string::npos){
83  methodOptions = strippedMethodName.substr(pos + 1, strippedMethodName.length() - pos);
84  strippedMethodName = strippedMethodName.substr(0, pos);
85  }
86 
87 // trim whitespaces
88  strippedMethodName = TrimString(strippedMethodName);
89  methodOptions = TrimString(methodOptions);
90 
91 // check that name is not empty
92  if(strippedMethodName.empty())
93  {
94  UG_THROW_REGISTRY_ERROR(strippedMethodName,
95  "Trying to register empty function name.");
96  }
97 
98  // check that name does not contain illegal characters
99  if (!IsValidRegistryIdentifier(strippedMethodName)) {
100  UG_THROW_REGISTRY_ERROR(strippedMethodName,
101  "Trying to register function '" << strippedMethodName << "' that"
102  << " contains illegal characters. " << GetRegistryIdentifierMessage());
103  }
104 
105 // if the function is already in use, we have to add an overload
106  ExportedFunctionGroup* funcGrp = get_exported_function_group(strippedMethodName);
107  if(!funcGrp)
108  {
109  // we have to create a new function group
110  funcGrp = new ExportedFunctionGroup(strippedMethodName);
111  m_vFunction.push_back(funcGrp);
112  }
113 
114 // add an overload to the function group
116  methodOptions, group,
117  retValInfos, paramInfos,
118  tooltip, help);
119 
120  if(!ef){
121  UG_THROW_REGISTRY_ERROR(strippedMethodName,
122  "Trying to register function name '"<<funcName
123  << "', that is already used by another function in this registry.");
124  }
125 
126  return ef;
127 }
128 
129 
131 // classes
133 
134 template <typename TClass, typename TBaseClass>
136 check_base_class(const std::string& className)
137 {
138 // check that className is not already used
139  if(classname_registered(className))
140  {
141  UG_THROW_REGISTRY_ERROR(className,
142  "Trying to register class name '"<<className
143  << "', that is already used by another class in this registry.");
144  }
145 // check that name is not empty
146  if(className.empty())
147  {
148  UG_THROW_REGISTRY_ERROR(className,
149  "Trying to register empty class name.");
150  }
151 
152 // check that base class is not same type as class
153  if(typeid(TClass) == typeid(TBaseClass))
154  {
155  UG_THROW_REGISTRY_ERROR(className,
156  "Trying to register class '"<< className
157  << "' that derives from itself.");
158  }
159 
160 // check that class derives from base class
161  if(boost::is_base_of<TBaseClass, TClass>::value == false)
162  {
163  UG_THROW_REGISTRY_ERROR(className,
164  "Trying to register class "<<className
165  << "with base class that is no base class.");
166  }
167 }
168 
169 template <typename TClass>
171 add_class_(std::string className, std::string group, std::string tooltip)
172 {
173 // check that className is not already used
174  if(classname_registered(className))
175  {
176  UG_THROW_REGISTRY_ERROR(className,
177  "Trying to register class name '"<<className
178  << "', that is already used by another class in this registry.");
179  }
180 // check that className is not already used as a group name
181  if(groupname_registered(className))
182  {
183  UG_THROW_REGISTRY_ERROR(className,
184  "Trying to register class name '"<<className
185  << "', that is already used by another group in this registry.");
186  }
187 // check that name is not empty
188  if(className.empty())
189  {
190  UG_THROW_REGISTRY_ERROR(className,
191  "Trying to register empty class name.");
192  }
193 
194  // check that name does not contain illegal characters
195  if (!IsValidRegistryIdentifier(className)) {
196  UG_THROW_REGISTRY_ERROR(className,
197  "Trying to register class '" << className << "' that"
198  << " contains illegal characters. "<< GetRegistryIdentifierMessage());
199  }
200 
201 // new class pointer
202  ExportedClass<TClass>* newClass = NULL;
203 
204  // AddTypeName<TClass>::add(tooltip);
205  newClass = new ExportedClass<TClass>(className, group, tooltip);
206 
207 // add new class to list of classes
208  m_vClass.push_back(newClass);
209 
210  return *newClass;
211 }
212 
213 template <typename TClass, typename TBaseClass>
215 add_class_(std::string className, std::string group, std::string tooltip)
216 {
217 // check that className is not already used
218  if(classname_registered(className))
219  {
220  UG_THROW_REGISTRY_ERROR(className,
221  "Trying to register class name '"<<className
222  << "', that is already used by another class in this registry.");
223  }
224 // check that className is not already used as a group name
225  if(groupname_registered(className))
226  {
227  UG_THROW_REGISTRY_ERROR(className,
228  "Trying to register class name '"<<className
229  << "', that is already used by another group in this registry.");
230  }
231 // check that name is not empty
232  if(className.empty())
233  {
234  UG_THROW_REGISTRY_ERROR(className,
235  "Trying to register empty class name.");
236  }
237 
238  // check that name does not contain illegal characters
239  if (!IsValidRegistryIdentifier(className)) {
240  UG_THROW_REGISTRY_ERROR(className,
241  "Trying to register class '" << className << "' that"
242  << " contains illegal characters. "<< GetRegistryIdentifierMessage());
243  }
244 
245 // check
246  check_base_class<TClass, TBaseClass>(className);
247 
248 // new class pointer
249  ExportedClass<TClass>* newClass = NULL;
250 
251  // AddTypeName<TClass>::add(tooltip);
252 
253 // try creation of new class
254  newClass = new ExportedClass<TClass>(className, group, tooltip);
255 
256 // set base class names
257  ClassNameProvider<TClass>::template set_name<TBaseClass>(className, group);
258 
259 // add cast function
260  ClassCastProvider::add_cast_func<TBaseClass, TClass>();
261 
262 // add new class to list of classes
263  m_vClass.push_back(newClass);
264  return *newClass;
265 }
266 
267 template <typename TClass, typename TBaseClass1, typename TBaseClass2>
269 add_class_(std::string className, std::string group, std::string tooltip)
270 {
271 // check that className is not already used
272  if(classname_registered(className))
273  {
274  UG_THROW_REGISTRY_ERROR(className,
275  "Trying to register class name '"<<className
276  << "', that is already used by another class in this registry.");
277  }
278 // check that className is not already used as a group name
279  if(groupname_registered(className))
280  {
281  UG_THROW_REGISTRY_ERROR(className,
282  "Trying to register class name '"<<className
283  << "', that is already used by another group in this registry.");
284  }
285 // check that name is not empty
286  if(className.empty())
287  {
288  UG_THROW_REGISTRY_ERROR(className,
289  "Trying to register empty class name.");
290  }
291 
292  // check that name does not contain illegal characters
293  if (!IsValidRegistryIdentifier(className)) {
294  UG_THROW_REGISTRY_ERROR(className,
295  "Trying to register class '" << className << "' that"
296  << " contains illegal characters. " << GetRegistryIdentifierMessage());
297  }
298 
299 // check
300  check_base_class<TClass, TBaseClass1>(className);
301  check_base_class<TClass, TBaseClass2>(className);
302 
303 // new class pointer
304  ExportedClass<TClass>* newClass = NULL;
305 
306  // AddTypeName<TClass>::add(tooltip);
307 
308 // try creation of new class
309  newClass = new ExportedClass<TClass>(className, group, tooltip);
310 
311 // set base class names
312  ClassNameProvider<TClass>::template set_name<TBaseClass1, TBaseClass2>(className, group);
313 
314 // add cast function
315  ClassCastProvider::add_cast_func<TBaseClass1, TClass>();
316  ClassCastProvider::add_cast_func<TBaseClass2, TClass>();
317 
318 // add new class to list of classes
319  m_vClass.push_back(newClass);
320  return *newClass;
321 }
322 
323 template <typename TClass>
325 get_class_()
326 {
327 // get class names
328  const std::string& name = ClassNameProvider<TClass>::name();
329 
330 // look for class in this registry
331  for(size_t i = 0; i < m_vClass.size(); ++i)
332  if(name == m_vClass[i]->name())
333  return *dynamic_cast<ExportedClass<TClass>* >(m_vClass[i]);
334 
335 // not found
337  "Trying to get class with name '" << name
338  << "', that has not yet been registered to this Registry.");
339 }
340 
341 }// end of namespace
342 }// end of namespace
343 
344 #endif
location name
Definition: checkpoint_util.lua:128
provides the name for a class
Definition: class_name_provider.h:102
static const std::string & name()
name of this class
Definition: class_name_provider_impl.h:152
This template class represents real c++ classes in the registry.
Definition: class.h:699
Groups of Functions - useful to realize overloaded functions.
Definition: global_function.h:243
ExportedFunction * add_overload(TFunc f, ExportedFunction::ProxyFunc pf, const std::string &funcOptions, const std::string &group, const std::string &retValInfos, const std::string &paramInfos, const std::string &tooltip, const std::string &help)
adds an overload. Returns false if the overload already existed.
Definition: global_function.h:261
This class describes a wrapper for a c++ - function, that is exported by ug.
Definition: global_function.h:186
Registry for functions and classes that are exported to scripts and visualizations.
Definition: registry.h:138
bool groupname_registered(const std::string &name)
returns true if groupname is already used by a class in this registry
Definition: registry.cpp:411
ExportedFunction * add_and_get_function(std::string funcName, TFunc func, std::string group="", std::string retValInfos="", std::string paramInfos="", std::string tooltip="", std::string help="")
Similar to add_function but returns the added function instead of the registry.
Definition: registry_impl.h:72
bool classname_registered(const std::string &name)
returns true if classname is already used by a class in this registry
Definition: registry.cpp:406
Registry & add_function(std::string funcName, TFunc func, std::string group="", std::string retValInfos="", std::string paramInfos="", std::string tooltip="", std::string help="")
adds a function to the registry
Definition: registry_impl.h:61
std::vector< ExportedFunctionGroup * > m_vFunction
registered functions
Definition: registry.h:315
ExportedFunctionGroup * get_exported_function_group(const std::string &name)
returns an exported function group by name
Definition: registry.cpp:431
std::vector< IExportedClass * > m_vClass
registered classes
Definition: registry.h:318
ExportedClass< TClass > & add_class_(std::string className, std::string group="", std::string tooltip="")
Register a class at this registry.
Definition: registry_impl.h:171
ExportedClass< TClass > & get_class_()
Get Reference to already registered class.
Definition: registry_impl.h:325
void check_base_class(const std::string &className)
performs some checks, throws error if something wrong
Definition: registry_impl.h:136
bool IsValidRegistryIdentifier(const std::string &name)
Definition: registry_util.cpp:54
std::string GetRegistryIdentifierMessage()
Definition: registry_util.cpp:62
the ug namespace
string TrimString(const string &str)
Definition: string_util.cpp:104
function func(x, y, z, t, si)
#define UG_THROW_REGISTRY_ERROR(cls, msg)
Definition: error.h:76
Definition: global_function.h:341