All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PluginServiceDetails.h
Go to the documentation of this file.
1 #ifndef _GAUDI_PLUGIN_SERVICE_DETAILS_H_
2 #define _GAUDI_PLUGIN_SERVICE_DETAILS_H_
3 /*****************************************************************************\
4 * (c) Copyright 2013 CERN *
5 * *
6 * This software is distributed under the terms of the GNU General Public *
7 * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENCE". *
8 * *
9 * In applying this licence, CERN does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 \*****************************************************************************/
13 
15 
16 #include <string>
17 #include <sstream>
18 #include <map>
19 #include <set>
20 #include <typeinfo>
21 #include <utility>
22 
23 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
24 #include <mutex>
25 #endif
26 
27 #if __GNUC__ >= 4
28 # define GAUDIPS_HASCLASSVISIBILITY
29 #endif
30 
31 #if defined(GAUDIPS_HASCLASSVISIBILITY)
32 # define GAUDIPS_IMPORT __attribute__((visibility("default")))
33 # define GAUDIPS_EXPORT __attribute__((visibility("default")))
34 # define GAUDIPS_LOCAL __attribute__((visibility("hidden")))
35 #else
36 # define GAUDIPS_IMPORT
37 # define GAUDIPS_EXPORT
38 # define GAUDIPS_LOCAL
39 #endif
40 
41 #ifdef GaudiPluginService_EXPORTS
42 #define GAUDIPS_API GAUDIPS_EXPORT
43 #else
44 #define GAUDIPS_API GAUDIPS_IMPORT
45 #endif
46 
47 namespace Gaudi { namespace PluginService {
48 
49  namespace Details {
54  template <class T>
55  class Factory {
56  public:
57 #if !defined(__REFLEX__) || defined(ATLAS)
58  template <typename S, typename... Args>
59  static typename S::ReturnType create(Args&&... args) {
60  return new T(std::forward<Args>(args)...);
61  }
62 #endif
63  };
64 
68  void* getCreator(const std::string& id, const std::string& type);
69 
82  template <typename F>
83  inline F getCreator(const std::string& id) {
84  union { void* src; F dst; } p2p;
85  p2p.src = getCreator(id, typeid(F).name());
86  return p2p.dst;
87  }
88 
92  std::string demangle(const std::type_info& id);
93 
95  template <typename T>
96  inline std::string demangle() { return demangle(typeid(T)); }
97 
100  public:
101  typedef std::string KeyType;
102 
104  typedef std::map<KeyType, std::string> Properties;
105 
106  struct FactoryInfo {
107  FactoryInfo(const std::string& lib, void* p=0,
108  const std::string& t="",
109  const std::string& rt="",
110  const std::string& cn="",
111  const Properties& props=Properties()):
112  library(lib), ptr(p), type(t), rtype(rt), className(cn), properties(props) {}
113 
114  std::string library;
115  void* ptr;
116  std::string type;
117  std::string rtype;
118  std::string className;
120 
121  FactoryInfo& addProperty(const KeyType& k, const std::string& v) {
122  properties[k] = v;
123  return *this;
124  }
125  };
126 
128  typedef std::map<KeyType, FactoryInfo> FactoryMap;
129 
131  static Registry& instance();
132 
134  template <typename F, typename T, typename I>
135  inline FactoryInfo& add(const I& id, typename F::FuncType ptr){
136  union { typename F::FuncType src; void* dst; } p2p;
137  p2p.src = ptr;
138  std::ostringstream o; o << id;
139  return add(o.str(), p2p.dst,
140  typeid(typename F::FuncType).name(),
141  typeid(typename F::ReturnType).name(),
142  demangle<T>());
143  }
144 
146  void* get(const std::string& id, const std::string& type) const;
147 
149  const FactoryInfo& getInfo(const std::string& id) const;
150 
152  Registry&
153  addProperty(const std::string& id,
154  const std::string& k,
155  const std::string& v);
156 
158  std::set<KeyType> loadedFactories() const;
159 
161  inline const FactoryMap& factories() const {
162  if (!m_initialized) const_cast<Registry*>(this)->initialize();
163  return m_factories;
164  }
165 
166  private:
171  Registry();
172 
174  Registry(const Registry&): m_initialized(false) {}
175 
177  FactoryInfo&
178  add(const std::string& id, void *factory,
179  const std::string& type, const std::string& rtype,
180  const std::string& className,
181  const Properties& props = Properties());
182 
184  inline FactoryMap& factories() {
185  if (!m_initialized) initialize();
186  return m_factories;
187  }
188 
191  void initialize();
192 
195 
198 
199 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
200  mutable std::recursive_mutex m_mutex;
202 #endif
203  };
204 
207  public:
208  enum Level { Debug=0, Info=1, Warning=2, Error=3 };
209  Logger(Level level = Warning): m_level(level) {}
210  virtual ~Logger() {}
211  inline Level level() const { return m_level; }
212  inline void setLevel(Level level) { m_level = level; }
213  inline void info(const std::string& msg) { report(Info, msg); }
214  inline void debug(const std::string& msg) { report(Debug, msg); }
215  inline void warning(const std::string& msg) { report(Warning, msg); }
216  inline void error(const std::string& msg) { report(Error, msg); }
217  private:
218  virtual void report(Level lvl, const std::string& msg);
220  };
221 
227  }
228 
230  GAUDIPS_API void SetDebug(int debugLevel);
232  GAUDIPS_API int Debug();
233 
234 }}
235 
236 #define _INTERNAL_FACTORY_REGISTER_CNAME(name, serial) \
237  _register_ ## _ ## serial
238 
239 #define _INTERNAL_DECLARE_FACTORY_WITH_CREATOR(type, typecreator, \
240  id, factory, serial) \
241  namespace { \
242  class _INTERNAL_FACTORY_REGISTER_CNAME(type, serial) { \
243  public: \
244  typedef factory s_t; \
245  typedef typecreator f_t; \
246  static s_t::FuncType creator() { return &f_t::create<s_t>; } \
247  _INTERNAL_FACTORY_REGISTER_CNAME(type, serial) () { \
248  using ::Gaudi::PluginService::Details::Registry; \
249  Registry::instance().add<s_t, type>(id, creator()); \
250  } \
251  } _INTERNAL_FACTORY_REGISTER_CNAME(s_ ## type, serial); \
252  }
253 
254 #define _INTERNAL_DECLARE_FACTORY(type, id, factory, serial) \
255  _INTERNAL_DECLARE_FACTORY_WITH_CREATOR(type, \
256  ::Gaudi::PluginService::Details::Factory<type>, \
257  id, factory, serial)
258 
259 #endif //_GAUDI_PLUGIN_SERVICE_DETAILS_H_
#define GAUDIPS_API
Registry(const Registry &)
Private copy constructor for the singleton pattern.
FactoryInfo & addProperty(const KeyType &k, const std::string &v)
FactoryInfo(const std::string &lib, void *p=0, const std::string &t="", const std::string &rt="", const std::string &cn="", const Properties &props=Properties())
Class providing default factory functions.
FactoryMap & factories()
Return the known factories (loading the list if not yet done).
GAUDIPS_API Logger & logger()
Return the current logger instance.
std::map< KeyType, std::string > Properties
Type used for the properties implementation.
Simple logging class, just to provide a default implementation.
static S::ReturnType create(Args &&...args)
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
string type
Definition: gaudirun.py:126
GAUDIPS_API std::string demangle(const std::type_info &id)
Return a canonical name for type_info object (implementation borrowed from GaudiKernel/System).
const FactoryMap & factories() const
Return the known factories (loading the list if not yet done).
void warning(const std::string &msg)
GAUDIPS_API void * getCreator(const std::string &id, const std::string &type)
Function used to load a specific factory function.
list args
Definition: gaudirun.py:254
In-memory database of the loaded factories.
FactoryInfo & add(const I &id, typename F::FuncType ptr)
Add a factory to the database.
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
GAUDIPS_API void setLogger(Logger *logger)
Set the logger instance to use.
This is a number of static methods for bootstrapping the Gaudi framework.
Definition: Bootstrap.h:14
std::map< KeyType, FactoryInfo > FactoryMap
Type used for the database implementation.
FactoryMap m_factories
Internal storage for factories.
bool m_initialized
Flag recording if the registry has been initialized or not.