File indexing completed on 2025-03-13 09:07:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DD4HEP_PLUGINS_H
0014 #define DD4HEP_PLUGINS_H
0015
0016
0017 #include <DD4hep/config.h>
0018
0019
0020 #ifndef __CINT__
0021 #include <string>
0022 #include <vector>
0023 #include <typeinfo>
0024
0025 #if __cplusplus >= 201703
0026 #include <any>
0027 inline bool any_has_value(std::any a){ return a.has_value(); }
0028 #else
0029 # include <boost/any.hpp>
0030 namespace std {
0031 using boost::any;
0032 using boost::any_cast;
0033 using boost::bad_any_cast;
0034 inline bool any_has_value(std::any a){ return !a.empty(); }
0035 }
0036 #endif
0037
0038 #ifndef DD4HEP_PARSERS_NO_ROOT
0039 #include <RVersion.h>
0040 #endif
0041
0042
0043 namespace dd4hep {
0044
0045 class Detector;
0046 class NamedObject;
0047 template <typename T> class Handle;
0048
0049
0050 struct PluginFactoryBase {
0051 typedef std::string str_t;
0052
0053 template <typename T> static T* ptr(const T* _p) { return (T*)_p; }
0054 template <typename T> static T& ref(const T* _p) { return *(T*)_p; }
0055 template <typename T> static T val(const T* _p) { return T(*_p); }
0056 template <typename T> static T value(const void* _p) { return (T)_p; }
0057 static const char* value(const void* _p) { return (const char*)(_p); }
0058 };
0059 template <> inline int PluginFactoryBase::value<int>(const void* _p) { return *(int*)(_p); }
0060 template <> inline long PluginFactoryBase::value<long>(const void* _p) { return *(long*)(_p); }
0061 template <> inline std::string PluginFactoryBase::value<std::string>(const void* _p) { return *(std::string*)(_p); }
0062 template <> inline const std::string& PluginFactoryBase::value<const std::string&>(const void* _p) { return *(std::string*)(_p); }
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 struct PluginDebug {
0075 int m_debug;
0076
0077 PluginDebug(int dbg = 2) noexcept(false);
0078
0079 ~PluginDebug() noexcept(false);
0080
0081 std::string missingFactory(const std::string& name) const;
0082 };
0083
0084
0085 class PluginService {
0086 private:
0087 public:
0088 typedef std::any stub_t;
0089 template <typename R, typename... Args> static R Create(const std::string& id, Args... args) {
0090 typedef R(*func)(Args...);
0091 std::any f;
0092 try {
0093 #if DD4HEP_PLUGINSVC_VERSION==1
0094 union { void* ptr; func fcn; } fptr;
0095 f = getCreator(id,typeid(R(Args...)));
0096 fptr.ptr = std::any_cast<void*>(f);
0097 if ( fptr.ptr )
0098 return (*fptr.fcn)(std::forward<Args>(args)...);
0099 #elif DD4HEP_PLUGINSVC_VERSION==2
0100 f = getCreator(id,typeid(R(Args...)));
0101 if ( std::any_cast<func>(f) )
0102 return std::any_cast<func>(f)(std::forward<Args>(args)...);
0103 #endif
0104 }
0105 catch(const std::bad_any_cast& e) {
0106 print_bad_cast(id, f, typeid(R(Args...)), e.what());
0107 }
0108 return 0;
0109 }
0110 template <typename FUNCTION> static std::any function(FUNCTION func) {
0111 #if DD4HEP_PLUGINSVC_VERSION==1
0112 union { void* ptr; FUNCTION fcn; } fptr;
0113 fptr.fcn = func;
0114 return std::any(fptr.ptr);
0115 #elif DD4HEP_PLUGINSVC_VERSION==2
0116 return std::any(func);
0117 #endif
0118 }
0119 static bool debug();
0120 static bool setDebug(bool new_value);
0121 static stub_t getCreator(const std::string& id, const std::type_info& info);
0122 static void addFactory(const std::string& id,
0123 stub_t&& func,
0124 const std::type_info& signature_type,
0125 const std::type_info& return_type);
0126 static void print_bad_cast(const std::string& id, const stub_t& stub, const std::type_info& signature, const char* msg);
0127 };
0128
0129
0130 template <typename DD4HEP_SIGNATURE> class PluginRegistry {
0131 public:
0132 typedef PluginService svc_t;
0133 typedef DD4HEP_SIGNATURE signature_t;
0134 template <typename R, typename... Args> static void add(const std::string& id, R(*func)(Args...)) {
0135 svc_t::addFactory(id,svc_t::function(func),typeid(R(Args...)),typeid(R));
0136 }
0137 };
0138 }
0139
0140 namespace {
0141
0142 template <typename P, typename S> class Factory {};
0143 }
0144
0145 #define DD4HEP_FACTORY_CALL(type,name,signature) dd4hep::PluginRegistry<signature>::add(name,Factory<type,signature>::call)
0146 #define DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(X,Y)
0147
0148 #define DD4HEP_OPEN_PLUGIN(ns,name) namespace ns { namespace { struct name {}; } } namespace dd4hep
0149 #define DD4HEP_PLUGINSVC_CNAME(name, serial) name##_dict_##serial
0150 #define DD4HEP_PLUGINSVC_FACTORY(type,name,signature,serial) \
0151 namespace { \
0152 struct DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial) { \
0153 DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial)() { \
0154 DD4HEP_FACTORY_CALL(type,#name,signature); }}; \
0155 static const DD4HEP_PLUGINSVC_CNAME(__typeFactory__,serial) \
0156 DD4HEP_PLUGINSVC_CNAME(s____typeFactory__,serial); \
0157 }
0158
0159
0160 #define DD4HEP_PLUGIN_FACTORY_ARGS_0(R) \
0161 template <typename P> class Factory<P, R()> \
0162 : public dd4hep::PluginFactoryBase { \
0163 public: \
0164 static R call(); \
0165 }; \
0166 template <typename P> inline R Factory<P,R()>::call()
0167
0168 #define DD4HEP_PLUGIN_FACTORY_ARGS_1(R,A0) \
0169 template <typename P> class Factory<P, R(A0)> \
0170 : public dd4hep::PluginFactoryBase { \
0171 public: \
0172 static R call(A0 a0); \
0173 }; \
0174 template <typename P> inline R Factory<P,R(A0)>::call(A0 a0)
0175
0176 #define DD4HEP_PLUGIN_FACTORY_ARGS_2(R,A0,A1) \
0177 template <typename P> class Factory<P, R(A0,A1)> \
0178 : public dd4hep::PluginFactoryBase { \
0179 public: \
0180 static R call(A0 a0,A1 a1); \
0181 }; \
0182 template <typename P> inline R Factory<P,R(A0,A1)>::call(A0 a0, A1 a1)
0183
0184 #define DD4HEP_PLUGIN_FACTORY_ARGS_3(R,A0,A1,A2) \
0185 template <typename P> class Factory<P, R(A0,A1,A2)> \
0186 : public dd4hep::PluginFactoryBase { \
0187 public: \
0188 static R call(A0 a0,A1 a1,A2 a2); \
0189 }; \
0190 template <typename P> inline R Factory<P,R(A0,A1,A2)>::call(A0 a0, A1 a1, A2 a2)
0191
0192 #define DD4HEP_PLUGIN_FACTORY_ARGS_4(R,A0,A1,A2,A3) \
0193 template <typename P> class Factory<P, R(A0,A1,A2,A3)> \
0194 : public dd4hep::PluginFactoryBase { \
0195 public: \
0196 static R call(A0 a0,A1 a1,A2 a2, A3 a3); \
0197 }; \
0198 template <typename P> inline R Factory<P,R(A0,A1,A2,A3)>::call(A0 a0, A1 a1, A2 a2, A3 a3)
0199
0200 #define DD4HEP_PLUGIN_FACTORY_ARGS_5(R,A0,A1,A2,A3,A4) \
0201 template <typename P> class Factory<P, R(A0,A1,A2,A3,A4)> \
0202 : public dd4hep::PluginFactoryBase { \
0203 public: \
0204 static R call(A0 a0,A1 a1,A2 a2, A3 a3, A4 a4); \
0205 }; \
0206 template <typename P> inline R Factory<P,R(A0,A1,A2,A3,A4)>::call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
0207
0208 #endif
0209 #endif