DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Plugins.h
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation for LCD
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 #ifndef DD4HEP_PLUGINS_H
14 #define DD4HEP_PLUGINS_H
15 
16 // ROOT include files
17 #ifndef __CINT__
18 #include <string>
19 #include <vector>
20 #include <typeinfo>
21 
22 #ifndef DD4HEP_PARSERS_NO_ROOT
23 #include "RVersion.h"
24 #if ROOT_VERSION_CODE < ROOT_VERSION(6,0,0)
25 #define DD4HEP_ROOT_VERSION_5 1
26 #endif
27 #endif
28 
30 namespace DD4hep {
31 
32  class NamedObject;
33  template <typename T> class Handle;
34 
36  namespace Geometry {
37  class LCDD;
38  }
40  namespace XML {
41  class Handle_t;
42  class Collection_t;
43  class Document;
44  class Element;
45  }
46 
53  typedef std::string str_t;
54 
55  template <typename T> static T* ptr(const T* p) { return (T*)p; }
56  template <typename T> static T& ref(const T* p) { return *(T*)p; }
57  template <typename T> static T val(const T* p) { return T(*p); }
58  template <typename T> static T value(const void* p) { return (T)p; }
59  static const char* value(const void* p) { return (const char*)(p); }
60  template <typename T> static T make_return(const T& p) { return p; }
61  };
62  template <> inline int PluginFactoryBase::value<int>(const void* p) { return *(int*)(p); }
63  template <> inline long PluginFactoryBase::value<long>(const void* p) { return *(long*)(p); }
64  template <> inline std::string PluginFactoryBase::value<std::string>(const void* p) { return *(std::string*)(p); }
65  template <> inline const std::string& PluginFactoryBase::value<const std::string&>(const void* p) { return *(std::string*)(p); }
66 
68 
77  struct PluginDebug {
78  int m_debug;
80  PluginDebug(int dbg = 2);
82  ~PluginDebug();
84  std::string missingFactory(const std::string& name) const;
85  };
86 
88  class PluginService {
89  private:
90  public:
91  typedef void* stub_t;
92 
93  template <typename FUNCTION> struct FuncPointer {
94  union { void* ptr; FUNCTION fcn; } fptr;
95  FuncPointer() { fptr.ptr = 0; }
96  FuncPointer(const FuncPointer& c) { fptr.ptr = c.fptr.ptr; }
97  FuncPointer(FUNCTION func) { fptr.fcn = func; }
98  FuncPointer(void* p) { fptr.ptr = p; }
99  void* ptr() const { return fptr.ptr; }
100  FUNCTION function() const { return fptr.func; }
102  fptr.ptr = c.fptr.ptr; return *this;
103  }
104  };
105  template <typename FUNCTION> static FuncPointer<FUNCTION> function(FUNCTION func) {
106  return FuncPointer<FUNCTION>(func);
107  }
108 
109  static bool debug();
110  static bool setDebug(bool new_value);
111 
112  static void* getCreator(const std::string& id, const std::type_info& info);
113  static void addFactory(const std::string& id, stub_t func,
114  const std::type_info& signature_type,
115  const std::type_info& return_type);
116 
117 #if defined(DD4HEP_ROOT_VERSION_5)
118  template <typename R> static R Create(const std::string& name);
119 
120  template <typename R, typename A0>
121  static R Create(const std::string& name,A0 a0);
122 
123  template <typename R, typename A0, typename A1>
124  static R Create(const std::string& name, A0 a0, A1 a1);
125 
126  template <typename R, typename A0, typename A1, typename A2>
127  static R Create(const std::string& name, A0 a0, A1 a1, A2 a2);
128 
129  template <typename R, typename A0, typename A1, typename A2, typename A3>
130  static R Create(const std::string& name, A0 a0, A1 a1, A2 a2, A3 a3);
131 
132  template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
133  static R Create(const std::string& name, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4);
134 
135  template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
136  static R Create(const std::string& name, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
137 #else
138  template <typename R, typename... Args> static R Create(const std::string& id, Args... args) {
139  FuncPointer<R(*)(Args...)> f(getCreator(id,typeid(R(Args...))));
140  return f.fptr.ptr ? (*f.fptr.fcn)(std::forward<Args>(args)...) : 0;
141  }
142 #endif
143  };
144 
146  template <typename SIGNATURE> class PluginRegistry {
147  public:
149  typedef SIGNATURE signature_t;
150 #if defined(DD4HEP_ROOT_VERSION_5)
151  typedef void (*stub_t)(void *retaddr, void*, const std::vector<void*>& arg, void*);
152  static void add(const char* name, stub_t stub);
153 #else
154  template <typename R, typename... Args> static void add(const std::string& id, R(*func)(Args...)) {
155  svc_t::addFactory(id,svc_t::function(func).ptr(),typeid(R(Args...)),typeid(R));
156  }
157 #endif
158  };
159 } /* End namespace DD4hep */
160 
161 namespace {
163  template <typename P, typename S> class Factory {};
164 }
165 
166 #if defined(DD4HEP_ROOT_VERSION_5)
167 #define DD4HEP_FACTORY_CALL(type,name,signature) DD4hep::PluginRegistry<signature>::add(name,Factory<type,signature>::wrapper);
168 #else
169 namespace DD4hep {
170  template <> inline long PluginFactoryBase::make_return(const long& p) { static long s=p; return (long)&s; }
171 }
172 #define DD4HEP_FACTORY_CALL(type,name,signature) DD4hep::PluginRegistry<signature>::add(name,Factory<type,signature>::call)
173 #define DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(X,Y)
174 #endif
175 
176 #define DD4HEP_OPEN_PLUGIN(ns,name) namespace ns { namespace { struct name {}; } } namespace DD4hep
177 #define DD4HEP_PLUGINSVC_CNAME(name, serial) name##_dict_##serial
178 #define DD4HEP_PLUGINSVC_FACTORY(type,name,signature,serial) \
179  namespace { \
180  struct DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial) { \
181  DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial)() { DD4HEP_FACTORY_CALL(type,#name,signature); } \
182  } DD4HEP_PLUGINSVC_CNAME(s____typeFactory__,serial); \
183  }
184 
185 
186 #define DD4HEP_PLUGIN_FACTORY_ARGS_0(R) \
187  template <typename P> class Factory<P, R()> \
188  : public DD4hep::PluginFactoryBase { \
189  public: \
190  static void wrapper(void *ret,void*,const std::vector<void*>& ,void*) { \
191  *(void**)ret = (void*)call(); \
192  } \
193  static R call(); \
194  }; \
195  template <typename P> inline R Factory<P,R()>::call()
196 
197 #define DD4HEP_PLUGIN_FACTORY_ARGS_1(R,A0) \
198  template <typename P> class Factory<P, R(A0)> \
199  : public DD4hep::PluginFactoryBase { \
200  public: \
201  static void wrapper(void *ret,void*,const std::vector<void*>& a,void*) { \
202  *(void**)ret = (void*)call(value<A0>(a[0])); \
203  } \
204  static R call(A0 a0); \
205  }; \
206  template <typename P> inline R Factory<P,R(A0)>::call(A0 a0)
207 
208 #define DD4HEP_PLUGIN_FACTORY_ARGS_2(R,A0,A1) \
209  template <typename P> class Factory<P, R(A0,A1)> \
210  : public DD4hep::PluginFactoryBase { \
211  public: \
212  static void wrapper(void *ret,void*,const std::vector<void*>& a,void*) { \
213  *(void**)ret = (void*)call(value<A0>(a[0]),value<A1>(a[1])); \
214  } \
215  static R call(A0 a0,A1 a1); \
216  }; \
217  template <typename P> inline R Factory<P,R(A0,A1)>::call(A0 a0, A1 a1)
218 
219 #define DD4HEP_PLUGIN_FACTORY_ARGS_3(R,A0,A1,A2) \
220  template <typename P> class Factory<P, R(A0,A1,A2)> \
221  : public DD4hep::PluginFactoryBase { \
222  public: \
223  static void wrapper(void *ret,void*,const std::vector<void*>& a,void*) { \
224  *(void**)ret = (void*)call(value<A0>(a[0]),value<A1>(a[1]),value<A2>(a[2])); \
225  } \
226  static R call(A0 a0,A1 a1,A2 a2); \
227  }; \
228  template <typename P> inline R Factory<P,R(A0,A1,A2)>::call(A0 a0, A1 a1, A2 a2)
229 
230 #define DD4HEP_PLUGIN_FACTORY_ARGS_4(R,A0,A1,A2,A3) \
231  template <typename P> class Factory<P, R(A0,A1,A2,A3)> \
232  : public DD4hep::PluginFactoryBase { \
233  public: \
234  static void wrapper(void *ret,void*,const std::vector<void*>& a,void*) { \
235  *(void**)ret = (void*)call(value<A0>(a[0]),value<A1>(a[1]),value<A2>(a[2]),value<A3>(a[3])); \
236  } \
237  static R call(A0 a0,A1 a1,A2 a2, A3 a3); \
238  }; \
239  template <typename P> inline R Factory<P,R(A0,A1,A2,A3)>::call(A0 a0, A1 a1, A2 a2, A3 a3)
240 
241 #define DD4HEP_PLUGIN_FACTORY_ARGS_5(R,A0,A1,A2,A3,A4) \
242  template <typename P> class Factory<P, R(A0,A1,A2,A3,A4)> \
243  : public DD4hep::PluginFactoryBase { \
244  public: \
245  static void wrapper(void *ret,void*,const std::vector<void*>& a,void*) { \
246  *(void**)ret = (void*)call(value<A0>(a[0]),value<A1>(a[1]),value<A2>(a[2]),value<A3>(a[3]),value<A4>(a[4])); \
247  } \
248  static R call(A0 a0,A1 a1,A2 a2, A3 a3, A4 a4); \
249  }; \
250  template <typename P> inline R Factory<P,R(A0,A1,A2,A3,A4)>::call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
251 
252 
253 
254 
255 #endif /* __CINT__ */
256 #endif /* DD4HEP_PLUGINS_H */
XML::Handle_t xml_h
Definition: Plugins.h:51
XML::Element xml_e
Definition: Plugins.h:52
std::string missingFactory(const std::string &name) const
Helper to check factory existence.
Definition: Plugins.cpp:147
static FuncPointer< FUNCTION > function(FUNCTION func)
Definition: Plugins.h:105
static T & ref(const T *p)
Definition: Plugins.h:56
static T make_return(const T &p)
Definition: Plugins.h:60
Geometry::LCDD lcdd_t
Definition: Plugins.h:49
static bool debug()
Definition: Plugins.cpp:32
TGeoShape * s
Definition: Volumes.cpp:294
User abstraction class to manipulate XML elements within a document.
Definition: XMLElements.h:686
static bool setDebug(bool new_value)
Definition: Plugins.cpp:36
static T value(const void *p)
Definition: Plugins.h:58
FuncPointer(const FuncPointer &c)
Definition: Plugins.h:96
static void add(const std::string &id, R(*func)(Args...))
Definition: Plugins.h:154
Factory base class implementing some utilities.
Definition: Plugins.h:48
PluginService svc_t
Definition: Plugins.h:148
~PluginDebug()
Default destructor.
Definition: Plugins.cpp:142
union DD4hep::PluginService::FuncPointer::@5 fptr
static void * getCreator(const std::string &id, const std::type_info &info)
Definition: Plugins.cpp:154
static R Create(const std::string &id, Args...args)
Definition: Plugins.h:138
static void addFactory(const std::string &id, stub_t func, const std::type_info &signature_type, const std::type_info &return_type)
Definition: Plugins.cpp:158
Helper to debug plugin manager calls.
Definition: Plugins.h:77
Factory template for the plugin mechanism.
Definition: Plugins.h:88
PluginDebug(int dbg=2)
Default constructor.
Definition: Plugins.cpp:137
FuncPointer & operator=(const FuncPointer &c)
Definition: Plugins.h:101
static T * ptr(const T *p)
Definition: Plugins.h:55
SIGNATURE signature_t
Definition: Plugins.h:149
static const char * value(const void *p)
Definition: Plugins.h:59
Factory template for the plugin mechanism.
Definition: Plugins.h:146
The main interface to the DD4hep detector description package.
Definition: LCDD.h:82
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:361
static T val(const T *p)
Definition: Plugins.h:57
Handle< NamedObject > ref_t
Definition: Plugins.h:50