WARPXM v1.10.0
Loading...
Searching...
No Matches
wxcreator.h
Go to the documentation of this file.
1
26#ifndef wxcreator_h
27#define wxcreator_h
28
29// WarpX includes
30#include "wxexcept.h"
31#include "wmopaqueptr.h"
32
33// std includes
34#include <iostream>
35#include <unordered_map>
36#include <stdexcept>
37#include <string>
38#include <vector>
39#include <typeinfo>
40#include <memory>
41
46namespace wxm
47{
48namespace detail
49{
54{
55public:
56 std::string name_;
57 const std::type_info* type_;
58
59 creator_base(std::string name, const std::type_info* dtype)
60 : name_(std::move(name)), type_(dtype)
61 {
62 }
63
64 virtual ~creator_base() = default;
65};
66
67// TODO: do we actually need two different lists?
68extern std::unordered_map<std::string, std::unique_ptr<creator_base>>&
70
71extern std::unordered_map<std::string, std::unique_ptr<creator_base>>&
73
74} // namespace detail
75} // namespace wxm
76
77template<class B> class WxCreatorBase;
78template<class B> class WxCreatorForChildrenBase;
79
83template<class B> class WxCreatorMapBase
84{
85public:
93 static wxm::detail::creator_base& addCreator(const std::string& nm,
95 {
96 auto v = wxm::detail::creatorsForDefault().emplace(
97 nm, std::unique_ptr<wxm::detail::creator_base>(b));
98 if (!v.second)
99 {
100 WxExcept wxe;
101 wxe << "Duplicate Creator for class " << nm;
102 throw wxe;
103 }
104 return *v.first->second;
105 }
106
116 {
117 auto v = wxm::detail::creatorsForChildren().emplace(
118 nm, std::unique_ptr<wxm::detail::creator_base>(b));
119 if (!v.second)
120 {
121 WxExcept wxe;
122 wxe << "Duplicate Creator for class " << nm;
123 throw wxe;
124 }
125 return *v.first->second;
126 }
127
133 static void removeCreatorForDefault(const std::string& nm)
134 {
135 std::cout << "unregistering " << nm << std::endl;
137 }
138
144 static void removeCreatorForChild(const std::string& nm)
145 {
146 std::cout << "unregistering " << nm << std::endl;
148 }
149};
150
151template<class B> class WxCreatorMap : public WxCreatorMapBase<B>
152{
153public:
161 static B* getNew(const std::string& nm)
162 {
163 auto i = wxm::detail::creatorsForDefault().find(nm);
164 if (i != wxm::detail::creatorsForDefault().end())
165 {
166 return reinterpret_cast<WxCreatorBase<B>*>(i->second.get())->getNew();
167 }
168
169 WxExcept wxe;
170 wxe << "Creator for class " << nm << " not found";
171 throw wxe;
172 }
173
183 static B* getNew(const std::string& nm, const WmConstOpaquePtr& parentPointer)
184 {
185 auto i = wxm::detail::creatorsForChildren().find(nm);
186 if (i != wxm::detail::creatorsForChildren().end())
187 {
188 return reinterpret_cast<WxCreatorForChildrenBase<B>*>(i->second.get())
189 ->getNew(parentPointer);
190 }
191
192 WxExcept wxe;
193 wxe << "Creator for class " << nm << " not found";
194 throw wxe;
195 }
196
204 static const std::string getRegisteredName(const std::type_info& type)
205 {
206
207 // check default constructor creators first
208 for (auto& i : wxm::detail::creatorsForDefault())
209 {
210 if (*(i.second->type_) == type)
211 {
212 return i.first;
213 }
214 }
215
216 // not found, so check 'ForChildren' constructor creators second
217 for (auto& i : wxm::detail::creatorsForChildren())
218 {
219 if (*(i.second->type_) == type)
220 {
221 return i.first;
222 }
223 }
224
225 std::string nomatch;
226 return nomatch;
227 }
228};
229template<class B> class WxCreatorBase : public wxm::detail::creator_base
230{
231public:
232 WxCreatorBase(std::string nm, const std::type_info* dtype)
233 : wxm::detail::creator_base(std::move(nm), dtype)
234 {
235 }
236
240 virtual B* getNew() = 0;
241};
242
246template<class D, class B> class WxCreator : public WxCreatorBase<B>
247{
248public:
249 WxCreator(std::string name) : WxCreatorBase<B>(std::move(name), &typeid(D))
250 {
251 }
252
254 {
255 D* d = new D;
256 return static_cast<B*>(d);
257 }
258};
259
261{
262public:
263 WxCreatorForChildrenBase(std::string nm, const std::type_info* dtype)
264 : wxm::detail::creator_base(std::move(nm), dtype)
265 {
266 }
267
271 virtual B* getNew(const WmConstOpaquePtr& parentPointer) = 0;
272};
273
278template<class D, class B> class WxCreatorForChildren : public WxCreatorForChildrenBase<B>
279{
280public:
281 WxCreatorForChildren(std::string name)
282 : WxCreatorForChildrenBase<B>(std::move(name), &typeid(D))
283 {
284 }
285
286 B* getNew(const WmConstOpaquePtr& parentPointer)
287 {
288 D* d = new D(parentPointer);
289 return static_cast<B*>(d);
290 }
291};
292
295#if defined(__GNUC__)
296#define WXM_UNUSED __attribute__((unused))
297#elif defined(_MSC_VER) && !defined(__clang__)
298#define WXM_UNUSED
299#else
300#define WXM_UNUSED
301#endif
302
303// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
304// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
305// empty. If X is empty the expression becomes (+1 == +0).
306#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
307#define WXM_PRIVATE_UNIQUE_ID __COUNTER__
308#else
309#define WXM_PRIVATE_UNIQUE_ID __LINE__
310#endif
311
312// Helpers for generating unique variable names
313#define WXM_PRIVATE_NAME(n) WXM_PRIVATE_CONCAT(wxm_creator_, WXM_PRIVATE_UNIQUE_ID, n)
314#define WXM_PRIVATE_CONCAT(a, b, c) WXM_PRIVATE_CONCAT2(a, b, c)
315#define WXM_PRIVATE_CONCAT2(a, b, c) a##b##c##_
316
317#define REGISTER_CREATOR(name, specialization, base) \
318 namespace \
319 { \
320 static auto& WXM_PRIVATE_NAME(registered) WXM_UNUSED = \
321 (WxCreatorMapBase<base>::addCreator(name, \
322 new WxCreator<specialization, base>(name))); \
323 }
324
325#define REGISTER_CREATOR_FOR_CHILDREN(name, specialization, base) \
326 namespace \
327 { \
328 static auto& WXM_PRIVATE_NAME(registered) \
329 WXM_UNUSED = (WxCreatorMapBase<base>::addCreatorForChildren( \
330 name, \
331 new WxCreatorForChildren<specialization, base>(name))); \
332 }
333
334#endif // wxcreator_h
Opaque Pointer object that carries the referenced data type, but does not expose this payload type as...
Definition: wmopaqueptr.h:81
Definition: wxcreator.h:230
WxCreatorBase(std::string nm, const std::type_info *dtype)
Definition: wxcreator.h:232
virtual B * getNew()=0
calls constructors for derived class taking no arguments
Definition: wxcreator.h:261
WxCreatorForChildrenBase(std::string nm, const std::type_info *dtype)
Definition: wxcreator.h:263
virtual B * getNew(const WmConstOpaquePtr &parentPointer)=0
calls constructors for derived class taking the one parentPointer argument
This creator is meant to be used for classes that require a parent argument to their constructor.
Definition: wxcreator.h:279
B * getNew(const WmConstOpaquePtr &parentPointer)
calls constructors for derived class taking the one parentPointer argument
Definition: wxcreator.h:286
WxCreatorForChildren(std::string name)
Definition: wxcreator.h:281
This creator is meant to be used for classes with default constructor.
Definition: wxcreator.h:247
WxCreator(std::string name)
Definition: wxcreator.h:249
B * getNew()
calls constructors for derived class taking no arguments
Definition: wxcreator.h:253
Defines Common Interface for WxCreatorMap.
Definition: wxcreator.h:84
static wxm::detail::creator_base & addCreator(const std::string &nm, wxm::detail::creator_base *b)
Add a new creator object into the list of available creators for base classes that have default const...
Definition: wxcreator.h:93
static void removeCreatorForChild(const std::string &nm)
Remove a creator from the list of parent pointer constructor creators.
Definition: wxcreator.h:144
static wxm::detail::creator_base & addCreatorForChildren(const std::string &nm, wxm::detail::creator_base *b)
Add a new creator object into the list of available creators for base classes that have a parent poin...
Definition: wxcreator.h:114
static void removeCreatorForDefault(const std::string &nm)
Remove a creator from the list of default constructor creators.
Definition: wxcreator.h:133
Definition: wxcreator.h:152
static B * getNew(const std::string &nm)
Get a new object whose creator has the given name and base class has a default constructor.
Definition: wxcreator.h:161
static const std::string getRegisteredName(const std::type_info &type)
Returns the first registered name string associated with a particular derived type.
Definition: wxcreator.h:204
static B * getNew(const std::string &nm, const WmConstOpaquePtr &parentPointer)
Get a new object whose creator has the given name and base class has a constructor taking one WxAny a...
Definition: wxcreator.h:183
implementation detail so deletion happens correctly
Definition: wxcreator.h:54
creator_base(std::string name, const std::type_info *dtype)
Definition: wxcreator.h:59
const std::type_info * type_
Definition: wxcreator.h:57
std::string name_
Definition: wxcreator.h:56
virtual ~creator_base()=default
wxm::lib::Except is the class to use for creating and throwing exceptions.
Definition: wxexcept.h:31
std::unordered_map< std::string, std::unique_ptr< creator_base > > & creatorsForDefault()
std::unordered_map< std::string, std::unique_ptr< creator_base > > & creatorsForChildren()
Base namespace for everything not included in the global namespace.
Definition: field_source.h:8