DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
Plugins.h
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
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 // Framework include files
17 #include <DD4hep/config.h>
18 
19 // ROOT include files
20 #ifndef __CINT__
21 #include <string>
22 #include <vector>
23 #include <typeinfo>
24 
25 #if __cplusplus >= 201703
26 #include <any>
27 inline bool any_has_value(std::any a){ return a.has_value(); }
28 #else
29 # include <boost/any.hpp>
30 namespace std {
31  using boost::any;
32  using boost::any_cast;
33  using boost::bad_any_cast;
34  inline bool any_has_value(std::any a){ return !a.empty(); }
35 } // namespace std
36 #endif
37 
38 #ifndef DD4HEP_PARSERS_NO_ROOT
39 #include <RVersion.h>
40 #endif
41 
43 namespace dd4hep {
44 
45  class Detector;
46  class NamedObject;
47  template <typename T> class Handle;
48 
51  typedef std::string str_t;
52 
53  template <typename T> static T* ptr(const T* _p) { return (T*)_p; }
54  template <typename T> static T& ref(const T* _p) { return *(T*)_p; }
55  template <typename T> static T val(const T* _p) { return T(*_p); }
56  template <typename T> static T value(const void* _p) { return (T)_p; }
57  static const char* value(const void* _p) { return (const char*)(_p); }
58  };
59  template <> inline int PluginFactoryBase::value<int>(const void* _p) { return *(int*)(_p); }
60  template <> inline long PluginFactoryBase::value<long>(const void* _p) { return *(long*)(_p); }
61  template <> inline std::string PluginFactoryBase::value<std::string>(const void* _p) { return *(std::string*)(_p); }
62  template <> inline const std::string& PluginFactoryBase::value<const std::string&>(const void* _p) { return *(std::string*)(_p); }
63 
65 
74  struct PluginDebug {
75  int m_debug;
77  PluginDebug(int dbg = 2) noexcept(false);
79  ~PluginDebug() noexcept(false);
81  std::string missingFactory(const std::string& name) const;
82  };
83 
85  class PluginService {
86  private:
87  public:
88  typedef std::any stub_t;
89  template <typename R, typename... Args> static R Create(const std::string& id, Args... args) {
90  typedef R(*func)(Args...);
91  std::any f;
92  try {
93 #if DD4HEP_PLUGINSVC_VERSION==1
94  union { void* ptr; func fcn; } fptr;
95  f = getCreator(id,typeid(R(Args...)));
96  fptr.ptr = std::any_cast<void*>(f);
97  if ( fptr.ptr )
98  return (*fptr.fcn)(std::forward<Args>(args)...);
99 #elif DD4HEP_PLUGINSVC_VERSION==2
100  f = getCreator(id,typeid(R(Args...)));
101  if ( std::any_cast<func>(f) )
102  return std::any_cast<func>(f)(std::forward<Args>(args)...);
103 #endif
104  }
105  catch(const std::bad_any_cast& e) {
106  print_bad_cast(id, f, typeid(R(Args...)), e.what());
107  }
108  return 0;
109  }
110  template <typename FUNCTION> static std::any function(FUNCTION func) {
111 #if DD4HEP_PLUGINSVC_VERSION==1
112  union { void* ptr; FUNCTION fcn; } fptr;
113  fptr.fcn = func;
114  return std::any(fptr.ptr);
115 #elif DD4HEP_PLUGINSVC_VERSION==2
116  return std::any(func);
117 #endif
118  }
119  static bool debug();
120  static bool setDebug(bool new_value);
121  static stub_t getCreator(const std::string& id, const std::type_info& info);
122  static void addFactory(const std::string& id,
123  stub_t&& func,
124  const std::type_info& signature_type,
125  const std::type_info& return_type);
126  static void print_bad_cast(const std::string& id, const stub_t& stub, const std::type_info& signature, const char* msg);
127  };
128 
130  template <typename DD4HEP_SIGNATURE> class PluginRegistry {
131  public:
133  typedef DD4HEP_SIGNATURE signature_t;
134  template <typename R, typename... Args> static void add(const std::string& id, R(*func)(Args...)) {
135  svc_t::addFactory(id,svc_t::function(func),typeid(R(Args...)),typeid(R));
136  }
137  };
138 } /* End namespace dd4hep */
139 
140 namespace {
142  template <typename P, typename S> class Factory {};
143 }
144 
145 #define DD4HEP_FACTORY_CALL(type,name,signature) dd4hep::PluginRegistry<signature>::add(name,Factory<type,signature>::call)
146 #define DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(X,Y)
147 
148 #define DD4HEP_OPEN_PLUGIN(ns,name) namespace ns { namespace { struct name {}; } } namespace dd4hep
149 #define DD4HEP_PLUGINSVC_CNAME(name, serial) name##_dict_##serial
150 #define DD4HEP_PLUGINSVC_FACTORY(type,name,signature,serial) \
151  namespace { \
152  struct DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial) { \
153  DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial)() { \
154  DD4HEP_FACTORY_CALL(type,#name,signature); }}; \
155  static const DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial) \
156  DD4HEP_PLUGINSVC_CNAME(s____typeFactory__,serial); \
157  }
158 
159 
160 #define DD4HEP_PLUGIN_FACTORY_ARGS_0(R) \
161  template <typename P> class Factory<P, R()> \
162  : public dd4hep::PluginFactoryBase { \
163  public: \
164  static R call(); \
165  }; \
166  template <typename P> inline R Factory<P,R()>::call()
167 
168 #define DD4HEP_PLUGIN_FACTORY_ARGS_1(R,A0) \
169  template <typename P> class Factory<P, R(A0)> \
170  : public dd4hep::PluginFactoryBase { \
171  public: \
172  static R call(A0 a0); \
173  }; \
174  template <typename P> inline R Factory<P,R(A0)>::call(A0 a0)
175 
176 #define DD4HEP_PLUGIN_FACTORY_ARGS_2(R,A0,A1) \
177  template <typename P> class Factory<P, R(A0,A1)> \
178  : public dd4hep::PluginFactoryBase { \
179  public: \
180  static R call(A0 a0,A1 a1); \
181  }; \
182  template <typename P> inline R Factory<P,R(A0,A1)>::call(A0 a0, A1 a1)
183 
184 #define DD4HEP_PLUGIN_FACTORY_ARGS_3(R,A0,A1,A2) \
185  template <typename P> class Factory<P, R(A0,A1,A2)> \
186  : public dd4hep::PluginFactoryBase { \
187  public: \
188  static R call(A0 a0,A1 a1,A2 a2); \
189  }; \
190  template <typename P> inline R Factory<P,R(A0,A1,A2)>::call(A0 a0, A1 a1, A2 a2)
191 
192 #define DD4HEP_PLUGIN_FACTORY_ARGS_4(R,A0,A1,A2,A3) \
193  template <typename P> class Factory<P, R(A0,A1,A2,A3)> \
194  : public dd4hep::PluginFactoryBase { \
195  public: \
196  static R call(A0 a0,A1 a1,A2 a2, A3 a3); \
197  }; \
198  template <typename P> inline R Factory<P,R(A0,A1,A2,A3)>::call(A0 a0, A1 a1, A2 a2, A3 a3)
199 
200 #define DD4HEP_PLUGIN_FACTORY_ARGS_5(R,A0,A1,A2,A3,A4) \
201  template <typename P> class Factory<P, R(A0,A1,A2,A3,A4)> \
202  : public dd4hep::PluginFactoryBase { \
203  public: \
204  static R call(A0 a0,A1 a1,A2 a2, A3 a3, A4 a4); \
205  }; \
206  template <typename P> inline R Factory<P,R(A0,A1,A2,A3,A4)>::call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
207 
208 #endif /* __CINT__ */
209 #endif // DD4HEP_PLUGINS_H
std::any_has_value
bool any_has_value(std::any a)
Definition: Plugins.h:34
dd4hep::PluginRegistry::signature_t
DD4HEP_SIGNATURE signature_t
Definition: Plugins.h:133
config.h
dd4hep::PluginService::stub_t
std::any stub_t
Definition: Plugins.h:88
dd4hep::PluginRegistry
Factory template for the plugin mechanism.
Definition: Plugins.h:130
dd4hep::info
std::size_t info(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:65
dd4hep::PluginDebug::PluginDebug
PluginDebug(int dbg=2) noexcept(false)
Default constructor.
Definition: Plugins.cpp:137
dd4hep::debug
std::size_t debug(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:64
dd4hep::PluginRegistry::svc_t
PluginService svc_t
Definition: Plugins.h:132
dd4hep::PluginService
Factory template for the plugin mechanism.
Definition: Plugins.h:85
dd4hep::PluginFactoryBase::str_t
std::string str_t
Definition: Plugins.h:51
dd4hep::PluginFactoryBase::ptr
static T * ptr(const T *_p)
Definition: Plugins.h:53
dd4hep::PluginFactoryBase
Factory base class implementing some utilities.
Definition: Plugins.h:50
dd4hep::PluginDebug
Helper to debug plugin manager calls.
Definition: Plugins.h:74
Gaudi::PluginService::v1::Details::getCreator
GAUDIPS_API void * getCreator(const std::string &id, const std::string &type)
Definition: PluginServiceV1.cpp:116
dd4hep::PluginRegistry::add
static void add(const std::string &id, R(*func)(Args...))
Definition: Plugins.h:134
dd4hep::PluginFactoryBase::value
static const char * value(const void *_p)
Definition: Plugins.h:57
dd4hep::PluginDebug::missingFactory
std::string missingFactory(const std::string &name) const
Helper to check factory existence.
Definition: Plugins.cpp:147
std
Definition: Plugins.h:30
dd4hep::PluginService::Create
static R Create(const std::string &id, Args... args)
Definition: Plugins.h:89
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::PluginFactoryBase::val
static T val(const T *_p)
Definition: Plugins.h:55
_p
#define _p(x)
Definition: IoStreams.cpp:94
dd4hep::PluginDebug::m_debug
int m_debug
Definition: Plugins.h:75
dd4hep::PluginFactoryBase::value
static T value(const void *_p)
Definition: Plugins.h:56
dd4hep::PluginFactoryBase::ref
static T & ref(const T *_p)
Definition: Plugins.h:54