Warning, /include/DD4hep/detail/Plugins.inl is written in an unsupported language. File is not indexed.
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
0014 #ifndef DD4HEP_PLUGINS_INL
0015 #define DD4HEP_PLUGINS_INL
0016
0017 #include <DD4hep/Plugins.h>
0018
0019 #if !defined(DD4HEP_PARSERS_NO_ROOT) && ROOT_VERSION_CODE < ROOT_VERSION(6,0,0)
0020 #include <set>
0021 #include <map>
0022 #include <list>
0023 #include <vector>
0024
0025 #ifdef __APPLE__
0026 #define Reflex_CollectionProxy 1
0027 #endif
0028
0029 #include <DD4hep/Printout.h>
0030 #include <Reflex/PluginService.h>
0031 #include <Reflex/Reflex.h>
0032 #include <Reflex/Builder/ReflexBuilder.h>
0033
0034 /// The dd4hep namespace declaration
0035 namespace dd4hep {
0036
0037 /** Declaration and implementation of all templated Create methods.
0038 * Concrete instances must be created using the instantiators below.
0039 *
0040 * \author M.Frank
0041 * \date 10/03/2015
0042 */
0043 template <typename R> R PluginService::Create(const std::string& name)
0044 { return ROOT::Reflex::PluginService::Create<R>(name); }
0045
0046 template <typename R, typename A0> R PluginService::Create(const std::string& name, A0 a0)
0047 { return ROOT::Reflex::PluginService::Create<R>(name,a0); }
0048
0049 template <typename R, typename A0, typename A1>
0050 R PluginService::Create(const std::string& name, A0 a0, A1 a1)
0051 { return ROOT::Reflex::PluginService::Create<R>(name, a0, a1); }
0052
0053 template <typename R, typename A0, typename A1, typename A2>
0054 R PluginService::Create(const std::string& name, A0 a0, A1 a1, A2 a2)
0055 { return ROOT::Reflex::PluginService::Create<R>(name, a0, a1, a2); }
0056
0057 template <typename R, typename A0, typename A1, typename A2, typename A3>
0058 R PluginService::Create(const std::string& name, A0 a0, A1 a1, A2 a2, A3 a3)
0059 { return ROOT::Reflex::PluginService::Create<R>(name, a0, a1, a2, a3); }
0060
0061 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
0062 R PluginService::Create(const std::string& name, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
0063 { return ROOT::Reflex::PluginService::Create<R>(name, a0, a1, a2, a3, a4); }
0064
0065 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
0066 R PluginService::Create(const std::string& name, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
0067 { return ROOT::Reflex::PluginService::Create<R>(name, a0, a1, a2, a3, a4, a5); }
0068
0069
0070 /** Internal namespace -- should under no circumstances be used directly.
0071 * The named namespace is necessary to trick the linker. Entries in an anonymous
0072 * namespace would be oiptimized away.....
0073 *
0074 * \author M.Frank
0075 * \date 10/03/2015
0076 */
0077 namespace plugin_signatures_namespace {
0078
0079 namespace {
0080
0081 /// Helper to convert function pointer to void pointer.
0082 /**
0083 * \author M.Frank
0084 * \date 10/03/2015
0085 */
0086 template <typename T> union FuncPtr {
0087 FuncPtr(T t) { fcn = t; }
0088 void* ptr;
0089 T fcn;
0090 };
0091 /// Helper to convert function pointer to helper union
0092 template <typename T> FuncPtr<T> __func(T t) { return FuncPtr<T>(t); }
0093 }
0094
0095 /// Defined required creator functions to instantiate the "Create" signatures.
0096 /** The Create signatures are instantiated from a macro only containing
0097 * the arguments. Otherwise these functions are
0098 * pretty useless.
0099 *
0100 * \author M.Frank
0101 * \date 10/03/2015
0102 */
0103 template <typename R> void* instantiate_creator ()
0104 { return __func(PluginService::Create<R>).ptr; }
0105
0106 template <typename R, typename A0> void* instantiate_creator(A0)
0107 { return __func(PluginService::Create<R,A0>).ptr; }
0108
0109 template <typename R, typename A0, typename A1> void* instantiate_creator(A0,A1)
0110 { return __func(PluginService::Create<R,A0,A1>).ptr; }
0111
0112 template <typename R, typename A0, typename A1, typename A2>
0113 void* instantiate_creator(A0,A1,A2)
0114 { return __func(PluginService::Create<R,A0,A1,A2>).ptr; }
0115
0116 template <typename R, typename A0, typename A1, typename A2, typename A3>
0117 void* instantiate_creator(A0,A1,A2,A3)
0118 { return __func(PluginService::Create<R,A0,A1,A2,A3>).ptr; }
0119
0120 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
0121 void* instantiate_creator(A0,A1,A2,A3,A4)
0122 { return __func(PluginService::Create<R,A0,A1,A2,A3,A4>).ptr; }
0123
0124 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
0125 void* instantiate_creator(A0,A1,A2,A3,A4,A5)
0126 { return __func(PluginService::Create<R,A0,A1,A2,A3,A4,A5>).ptr; }
0127
0128 namespace {
0129 template <typename DD4HEP_SIGNATURE> static void reflex_plugin(const std::string& name, typename dd4hep::PluginRegistry<DD4HEP_SIGNATURE>::stub_t stub) {
0130 ROOT::Reflex::Type typ = ROOT::Reflex::TypeBuilder(name.c_str(),ROOT::Reflex::PUBLIC);
0131 ROOT::Reflex::Type sig = ROOT::Reflex::FunctionDistiller < DD4HEP_SIGNATURE > ::Get();
0132 std::string fname = (std::string(PLUGINSVC_FACTORY_NS "::") + ROOT::Reflex::PluginService::FactoryName(name));
0133 ROOT::Reflex::FunctionBuilder func(sig, fname.c_str(), stub, 0, "", ROOT::Reflex::PUBLIC);
0134 func.AddProperty("name", name).AddProperty("id", name);
0135 if ( PluginService::debug() ) {
0136 std::string sig_name = sig.Name();
0137 printout(INFO,"PluginService","+++ Declared factory for id %s with signature %s.",fname.c_str(),sig_name.c_str());
0138 }
0139 }
0140 }
0141
0142 }
0143 }
0144
0145 #define DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(R, ARGS) namespace dd4hep { \
0146 template <> void PluginRegistry< R ARGS >::add(const char* n, stub_t f) \
0147 { plugin_signatures_namespace::reflex_plugin< R ARGS >(n,f); } \
0148 namespace plugin_signatures_namespace { template void* instantiate_creator<R> ARGS ; }}
0149
0150 #endif
0151
0152 #endif // DD4HEP_PLUGINS_INL