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