Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-13 09:07:04

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 #ifndef DD4HEP_PLUGINS_H
0014 #define DD4HEP_PLUGINS_H
0015 
0016 // Framework include files
0017 #include <DD4hep/config.h>
0018 
0019 // ROOT include files
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 } // namespace std
0036 #endif
0037 
0038 #ifndef DD4HEP_PARSERS_NO_ROOT
0039 #include <RVersion.h>
0040 #endif
0041 
0042 /// Namespace for the AIDA detector description toolkit
0043 namespace dd4hep {
0044 
0045   class Detector;
0046   class NamedObject;
0047   template <typename T> class Handle;
0048 
0049   /// Factory base class implementing some utilities
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   /// Helper to debug plugin manager calls
0065   /**
0066    *  Small helper class to adjust the plugin service debug level
0067    *  for a limited code scope. Automatically back-adjusts the debug
0068    *  level at object destruction.
0069    *
0070    *  \author  M.Frank
0071    *  \version 1.0
0072    *  \ingroup DD4HEP
0073    */
0074   struct PluginDebug {
0075     int m_debug;
0076     /// Default constructor
0077     PluginDebug(int dbg = 2)  noexcept(false);
0078     /// Default destructor
0079     ~PluginDebug()  noexcept(false);
0080     /// Helper to check factory existence
0081     std::string missingFactory(const std::string& name) const;
0082   };
0083 
0084   /// Factory template for the plugin mechanism
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   /// Factory template for the plugin mechanism
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 } /* End namespace dd4hep      */
0139 
0140 namespace {
0141   /// Base factory template
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    /* __CINT__          */
0209 #endif // DD4HEP_PLUGINS_H