Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
class_name_provider_impl.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3 * Authors: Sebastian Reiter, 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#ifndef __H__UG_BRIDGE__CLASS_NAME_PROVIDER_IMPL__
34#define __H__UG_BRIDGE__CLASS_NAME_PROVIDER_IMPL__
35
36#include <algorithm>
37#include <string>
38
39#include "class_name_provider.h"
41
42namespace ug{
43namespace bridge{
44
46// ClassNameProvider
48
49template <typename TClass>
51set_name(const std::string& nameIn, const std::string& group, bool newName)
52{
53// if class already named throw error
54 if(newName == true && m_bForwardDeclared==false && !m_ClassNameNode.empty())
55 {
56 if(nameIn != name())
58 "Trying to register class with name '"<<nameIn
59 << "', that has already been named. This is not allowed.");
60 }
61
62// check name
63 if(nameIn.empty())
64 UG_THROW_REGISTRY_MSG("Registered class name has length zero");
65
66 if(nameIn.c_str()[0] == '[')
67 UG_THROW_REGISTRY_ERROR(nameIn, "Registered class name must not begin with '['");
68
69// check for non-allowed character
70 size_t found = nameIn.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
71 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
72 "_"
73 "0123456789");
74 if (found!=std::string::npos)
75 {
76 UG_ERR_LOG("Non-allowed character '"<<nameIn[found]<<"' "<<
77 "contained at position "<<int(found)<<" in registered Class Name "
78 "'"<<nameIn<<"'.\nClass names must match the regular expression: "
79 "[a-zA-Z_][a-zA-Z_0-9]*, \ni.e. only alphabetic characters, numbers "
80 " and '_' are allowed; no numbers at the beginning.\n");
81 UG_THROW_REGISTRY_ERROR(nameIn, "Class Name must only contain [a-zA-Z_][a-zA-Z_0-9]*.");
82 }
83
84// check that no number at the beginning
85 found = nameIn.find_first_of("0123456789");
86 if (found!=std::string::npos && found == 0)
87 {
88 UG_ERR_LOG("Class Name "<<nameIn<<" starts with a number.\nThis is "
89 " not allowed. Please change naming.\n");
90 UG_THROW_REGISTRY_ERROR(nameIn,"Class Name must not start with number.");
91 }
92
93
94// copy name into static string
95 m_ClassNameNode.set_name(nameIn);
96
97// set forward declared to false, since now name set
98 m_bForwardDeclared = false;
99
100// remember groups
101 m_group = std::string(group);
102};
103
104template <typename TClass>
105template <typename TParent1>
107set_name(const std::string& name, const std::string& group, bool newName)
108{
109// set own name
110 set_name(name, group, newName);
111
112// add parent nodes
113 m_ClassNameNode.add_base_class(ClassNameProvider<TParent1>::class_name_node());
114}
115
116template <typename TClass>
117template <typename TParent1, typename TParent2>
119set_name(const std::string& name, const std::string& group,bool newName)
120{
121// set own name
122 set_name(name, group, newName);
123
124// add parent nodes
125 m_ClassNameNode.add_base_class(ClassNameProvider<TParent1>::class_name_node());
126 m_ClassNameNode.add_base_class(ClassNameProvider<TParent2>::class_name_node());
127}
128
129template <typename TClass>
130bool ClassNameProvider<TClass>::is_a(const std::string& parent, bool strict)
131{
132// check if class is forward declared
133 if(m_bForwardDeclared)
135 "Class '"<<parent<<"' must not be foreward declared to use is_a");
136
137// strict comparison: must match this class name, parents are not allowed
138 if(strict)
139 {
140 // compare strings
141 if(parent == name()) return true;
142
143 // names does not match
144 return false;
145 }
146
147// return if parent name is contained in tree of base classes
148 return ClassNameTreeContains(m_ClassNameNode, parent);
149}
150
151template <typename TClass>
153{
154// if name has not been set, set temporary forward declaration
155 if(m_ClassNameNode.empty()) set_foreward_declared();
156
157// return the name of this class as stored in ClassNameNode
158 return m_ClassNameNode.name();
159}
160
161template <typename TClass>
162const std::vector<const char*>& ClassNameProvider<TClass>::names()
163{
164// if name has not been set, set temporary forward declaration
165 if(m_ClassNameNode.empty()) set_foreward_declared();
166
167// create names list, including this class and all base classes
168// \todo: remove this, avoid names-vector
169 ExtractClassNameVec(m_names, m_ClassNameNode, true);
170
171// return the vector of base class names
172 return m_names;
173}
174
175template <typename TClass>
177{
178// build default name using typeinfo
179 std::string name("[[");
180 name.append( TypeName<TClass>() );
181 name.append(" (undeclared) ]]");
182
183// set this as current name, but remember pre-declaration
184 m_ClassNameNode.set_name(name);
185 m_bForwardDeclared = true;
186}
187
188template <typename TClass>
189std::vector<const char*> ClassNameProvider<TClass>::m_names = std::vector<const char*>();
190
191template <typename TClass>
192std::string ClassNameProvider<TClass>::m_group = std::string("");
193
194template <typename TClass>
196
197template <typename TClass>
199
201// ClassCastProvider
203
204template <typename TBase, typename TDerived>
205void* StaticVoidCast(void* DerivVoidPtr)
206{
207// cast to derived class; this assumes, that the void pointer points to the
208// beginning of the data field of the Derived object
209 TDerived* pDeriv = reinterpret_cast<TDerived*>(DerivVoidPtr);
210
211// static case to the Derid class
212 TBase* pBase = static_cast<TBase*>(pDeriv);
213
214// return cast to void
215 return reinterpret_cast<void*>(pBase);
216}
217
218template <typename TBase, typename TDerived>
220{
221 const ClassNameNode* pBaseNode =
223 const ClassNameNode* pDerivNode =
225
226 std::pair<const ClassNameNode*, const ClassNameNode*>
227 namePair(pBaseNode, pDerivNode);
228
229 m_mmCast[namePair] = &StaticVoidCast<TBase, TDerived>;
230}
231
232template <typename T>
234cast_to(void* ptr, const ClassNameNode*& node)
235{
236// get base name
237 const std::string& baseName = ClassNameProvider<T>::name();
238
239// cast the plain pointer
241
242// return it
243 return reinterpret_cast<T*>(ptr);
244}
245
246template <typename T>
248cast_to(const void* ptr, const ClassNameNode*& node)
249{
250// get base name
251 const std::string& baseName = ClassNameProvider<T>::name();
252
253// cast the plain pointer
255
256// return it
257 return reinterpret_cast<const T*>(ptr);
258}
259
260template <typename T>
262cast_to(SmartPtr<void> spDerivVoid, const ClassNameNode*& node)
263{
264// get base name
265 const std::string& baseName = ClassNameProvider<T>::name();
266
267// extract plain pointer
268 void* rawPtr = spDerivVoid.get();
269
270// cast the plain pointer
271 rawPtr = ClassCastProvider::cast_to_base_class(rawPtr, node, baseName);
272
273// sets as pointer to the smart ptr
274 spDerivVoid.set_impl<T, FreeDelete>(rawPtr);
275
276// return it
277 return spDerivVoid.cast_reinterpret<T, FreeDelete>();
278}
279
280template <typename T>
282cast_to(ConstSmartPtr<void> spDerivVoid, const ClassNameNode*& node)
283{
284// get base name
285 const std::string& baseName = ClassNameProvider<T>::name();
286
287// extract plain pointer
288 const void* rawPtr = spDerivVoid.get();
289
290// cast the plain pointer
291 rawPtr = ClassCastProvider::cast_to_base_class(rawPtr, node, baseName);
292
293// sets as pointer to the smart ptr
294 spDerivVoid.set_impl<T, FreeDelete>(rawPtr);
295
296// return it
297 return spDerivVoid.cast_reinterpret<T, FreeDelete>();
298}
299} // end namespace ug
300} // end namespace bridge
301
302#endif /* __H__UG_BRIDGE__CLASS_NAME_PROVIDER_IMPL__ */
location name
Definition checkpoint_util.lua:128
Definition smart_pointer.h:296
const T * get() const
Definition smart_pointer.h:409
ConstSmartPtr< TDest, FreePolicy > cast_reinterpret() const
performs a static cast
Definition smart_pointer.h:440
Definition smart_pointer.h:51
Definition smart_pointer.h:108
T * get()
returns encapsulated pointer
Definition smart_pointer.h:197
SmartPtr< TDest, FreePolicy > cast_reinterpret() const
performs a reinterpret cast
Definition smart_pointer.h:232
static void * cast_to_base_class(void *pDerivVoid, const ClassNameNode *&node, const std::string &baseName)
cast a pointer to the desired base class
Definition class_name_provider.cpp:139
static T * cast_to(void *pDerivVoid, const ClassNameNode *&node)
casts a void pointer to a concrete class
Definition class_name_provider_impl.h:234
static std::map< std::pair< const ClassNameNode *, const ClassNameNode * >, CastFunc > m_mmCast
Definition class_name_provider.h:236
static void add_cast_func()
add a cast function to the registry: Casts: Derived -> Base
Definition class_name_provider_impl.h:219
node for class names
Definition class_name_provider.h:65
provides the name for a class
Definition class_name_provider.h:102
static const ClassNameNode & class_name_node()
return the class name node in the class hierarchy
Definition class_name_provider.h:136
static void set_foreward_declared()
sets a temporary name to the class
Definition class_name_provider_impl.h:176
static void set_name(const std::string &nameIn, const std::string &group, bool newName=false)
set name of class and copy parent names
Definition class_name_provider_impl.h:107
static const std::string & name()
name of this class
Definition class_name_provider_impl.h:152
static bool is_a(const std::string &parent, bool strict=false)
Definition class_name_provider_impl.h:130
static void set_name(const std::string &nameIn, const std::string &group, bool newName=false)
set name of class and copy parent names
Definition class_name_provider_impl.h:51
static const std::vector< const char * > & names()
returns vector of all names including parent class names
Definition class_name_provider_impl.h:162
void * StaticVoidCast(void *DerivVoidPtr)
static cast function for two classes
Definition class_name_provider_impl.h:205
bool ClassNameTreeContains(const ClassNameNode &node, const std::string &name)
returns if a name is contained in the name tree at node or in base classes
Definition class_name_provider.cpp:104
void ExtractClassNameVec(std::vector< const char * > &names, const ClassNameNode &node, bool clearVec)
returns the vector containing all names in the name tree for node and its base classes
Definition class_name_provider.cpp:90
#define UG_ERR_LOG(msg)
Definition log.h:383
the ug namespace
void baseName(std::string &nameOut, const std::string &nameIn)
Definition vtkoutput.cpp:209
#define UG_THROW_REGISTRY_MSG(msg)
Definition error.h:81
#define UG_THROW_REGISTRY_ERROR(cls, msg)
Definition error.h:76