Line data Source code
1 : /*
2 : * Copyright (c) 2010-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 :
34 : #ifndef __H__UG_BRIDGE__CLASS_NAME_PROVIDER__
35 : #define __H__UG_BRIDGE__CLASS_NAME_PROVIDER__
36 :
37 : #include "common/assert.h"
38 : #include <vector>
39 : #include <cstring>
40 : #include <string>
41 : #include <algorithm>
42 : #include <iostream>
43 : #include <typeinfo>
44 : #include <map>
45 : #include "common/common.h"
46 : #include "common/util/smart_pointer.h"
47 : #include "common/ug_config.h"
48 : #include "error.h"
49 :
50 : namespace ug
51 : {
52 : namespace bridge
53 : {
54 :
55 : /// \addtogroup registry
56 : /// \{
57 :
58 : /// node for class names
59 : /**
60 : * A ClassNameNode stores the name of a registered class and pointers to
61 : * the ClassNameNodes of the direct base classes of this class. By traversing
62 : * the tree of ClassNameNodes all parent classes of a class can be found.
63 : */
64 : class UG_API ClassNameNode
65 : {
66 : public:
67 : /// constructor
68 : ClassNameNode();
69 :
70 : /// set name
71 : void set_name(const std::string& name);
72 :
73 : /// add a base class
74 : void add_base_class(const ClassNameNode& node);
75 :
76 : /// returns own name
77 0 : const std::string& name() const {return m_name;}
78 :
79 : /// returns if a name has been set
80 : bool empty() const {return m_name.empty();}
81 :
82 : /// returns if a name has been set by the user
83 : bool named() const;
84 :
85 : /// returns number of parents
86 : size_t num_base_classes() const {return m_vBaseClass.size();}
87 :
88 : /// return a base class
89 0 : const ClassNameNode& base_class(size_t i) const {return *m_vBaseClass.at(i);}
90 :
91 : protected:
92 : /// own name
93 : std::string m_name;
94 :
95 : /// base classes
96 : std::vector<const ClassNameNode*> m_vBaseClass;
97 : };
98 :
99 : /// provides the name for a class
100 : template <typename TClass>
101 : class UG_API ClassNameProvider
102 : {
103 : public:
104 : /// set name of class and copy parent names
105 : static void set_name(const std::string& nameIn, const std::string& group,
106 : bool newName = false);
107 :
108 : /// set name of class and copy parent names
109 : template <typename TParent1>
110 : static void set_name(const std::string& nameIn, const std::string& group,
111 : bool newName = false);
112 :
113 : /// set name of class and copy parent names
114 : template <typename TParent1, typename TParent2>
115 : static void set_name(const std::string& nameIn, const std::string& group,
116 : bool newName = false);
117 :
118 : /** check if a given class name is equal
119 : * This function checks if a given class name is equal to this class name.
120 : * If the flag 'strict' is set to true, the class name must match exactly.
121 : * If it is set to false, also parent names (of the class hierarchy) are checked
122 : * and if this class inherits from the parent class true is returned.
123 : */
124 : static bool is_a(const std::string& parent, bool strict = false);
125 :
126 : /// name of this class
127 : static const std::string& name();
128 :
129 : /// groups
130 : static const std::string& group(){return m_group;}
131 :
132 : /// returns vector of all names including parent class names
133 : static const std::vector<const char*>& names();
134 :
135 : /// return the class name node in the class hierarchy
136 : static const ClassNameNode& class_name_node() {return m_ClassNameNode;}
137 :
138 : /// returns if class name is forward declared
139 : static bool forward_declared() {return m_bForwardDeclared;}
140 :
141 : /// returns if the class has been named by user
142 : static bool named() {return !m_bForwardDeclared && !m_ClassNameNode.empty();}
143 :
144 : protected:
145 : /// sets a temporary name to the class
146 : static void set_foreward_declared();
147 :
148 : private:
149 : /// vector of parent class names (depreciated)
150 : static std::vector<const char*> m_names;
151 :
152 : /// Name of group, we're this class is sorted
153 : static std::string m_group;
154 :
155 : /// set to true if class has not been named by user, but a default name given
156 : static bool m_bForwardDeclared;
157 :
158 : /// class name node holding own name and pointers to base class name nodes
159 : static ClassNameNode m_ClassNameNode;
160 : };
161 :
162 : template <typename TClass>
163 : const char* GetClassName(){
164 : return ClassNameProvider<TClass>::name().c_str();
165 : }
166 :
167 : /// static cast function for two classes
168 : template <typename TBase, typename TDerived>
169 : void* StaticVoidCast(void* DerivVoidPtr);
170 :
171 :
172 : struct UGError_ClassCastFailed : public UGError{
173 0 : UGError_ClassCastFailed(const std::string& from, const std::string& to) :
174 0 : UGError("Class cast failed"), m_from(from), m_to(to) {}
175 :
176 : std::string m_from;
177 : std::string m_to;
178 : };
179 :
180 : /// provides castings from derived classes to base classes
181 : class ClassCastProvider
182 : {
183 : public:
184 : /// add a cast function to the registry: Casts: Derived -> Base
185 : template <typename TBase, typename TDerived>
186 : static void add_cast_func();
187 :
188 : /// cast a pointer to the desired base class
189 : /**
190 : * This method casts a void pointer to a given derived class to the void
191 : * pointer of a base class. If conversion fails, an exception of type
192 : * UGError_ClassCastFailed is thrown.
193 : *
194 : * \param[in] pDerivVoid void pointer to Derived object
195 : * \param[in,out] node on entry: class name node corresponding to pDerivVoid
196 : * on exit: class name node corresponding to baseName
197 : * \param[in] baseName name of base class the pointer should be casted to
198 : * \returns void* to base class
199 : */
200 : /// \{
201 : static void* cast_to_base_class(void* pDerivVoid,
202 : const ClassNameNode*& node,
203 : const std::string& baseName);
204 : static const void* cast_to_base_class(const void* pDerivVoid,
205 : const ClassNameNode*& node,
206 : const std::string& baseName);
207 : //// \}
208 :
209 : /// casts a void pointer to a concrete class
210 : /**
211 : * This method casts a void pointer to a given derived classed and returns it
212 : * as a reinterpreted cast to the type specified by the template argument.
213 : * If conversion fails, an exception of type UGError_ClassCastFailed is thrown.
214 : *
215 : * \param[in] pDerivVoid void pointer to Derived object
216 : * \param[in,out] node on entry: class name node corresponding to pDerivVoid
217 : * on exit: class name node corresponding to baseName
218 : * \returns void* to base class
219 : */
220 : /// \{
221 : template <typename T>
222 : static T* cast_to(void* pDerivVoid, const ClassNameNode*& node);
223 : template <typename T>
224 : static const T* cast_to(const void* pDerivVoid, const ClassNameNode*& node);
225 : template <typename T>
226 : static SmartPtr<T> cast_to(SmartPtr<void> pDerivVoid, const ClassNameNode*& node);
227 : template <typename T>
228 : static ConstSmartPtr<T> cast_to(ConstSmartPtr<void> pDerivVoid, const ClassNameNode*& node);
229 : /// \}
230 :
231 : protected:
232 : // type of cast pointer
233 : typedef void* (*CastFunc)(void*);
234 :
235 : // cast map
236 : static std::map<std::pair<const ClassNameNode*, const ClassNameNode*>, CastFunc> m_mmCast;
237 : };
238 :
239 :
240 : /// returns the vector containing all names in the name tree for node and its base classes
241 : void ExtractClassNameVec(std::vector<const char*>& names,
242 : const ClassNameNode& node,
243 : bool clearVec = true);
244 :
245 : /// returns if a name is contained in the name vector
246 : bool ClassNameVecContains(const std::vector<const char*>& names, const std::string& name);
247 :
248 : /// returns if a name is contained in the name tree at node or in base classes
249 : bool ClassNameTreeContains(const ClassNameNode& node, const std::string& name);
250 :
251 : /// returns an std::vector that contains in reverse order the base class that
252 : /// must be used in the Class Hierarchy to get to the base class
253 : bool ClassNameTreeWay(std::vector<size_t>& vWay, const ClassNameNode& node, const std::string& name);
254 :
255 : // end group registry
256 : /// \}
257 :
258 : } // end namespace
259 : } // end namespace
260 :
261 : // include implementation
262 : #include "class_name_provider_impl.h"
263 :
264 : #endif /* __H__UG_BRIDGE__CLASS_NAME_PROVIDER__ */
|