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 
22 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
23 #include <mutex>
24 #endif
25 
26 #if __GNUC__ >= 4
27 # define GAUDIPS_HASCLASSVISIBILITY
28 #endif
29 
30 #if defined(GAUDIPS_HASCLASSVISIBILITY)
31 # define GAUDIPS_IMPORT __attribute__((visibility("default")))
32 # define GAUDIPS_EXPORT __attribute__((visibility("default")))
33 # define GAUDIPS_LOCAL __attribute__((visibility("hidden")))
34 #else
35 # define GAUDIPS_IMPORT
36 # define GAUDIPS_EXPORT
37 # define GAUDIPS_LOCAL
38 #endif
39 
40 #ifdef GaudiPluginService_EXPORTS
41 #define GAUDIPS_API GAUDIPS_EXPORT
42 #else
43 #define GAUDIPS_API GAUDIPS_IMPORT
44 #endif
45 
46 namespace Gaudi { namespace PluginService {
47 
48  namespace Details {
53  template <class T>
54  class Factory {
55  public:
56 
57  template <typename S>
58  static typename S::ReturnType create() {
59  return new T();
60  }
61 
62  template <typename S>
63  static typename S::ReturnType create(typename S::Arg1Type a1) {
64  return new T(a1);
65  }
66 
67  template <typename S>
68  static typename S::ReturnType create(typename S::Arg1Type a1,
69  typename S::Arg2Type a2) {
70  return new T(a1, a2);
71  }
72 
73  template <typename S>
74  static typename S::ReturnType create(typename S::Arg1Type a1,
75  typename S::Arg2Type a2,
76  typename S::Arg3Type a3) {
77  return new T(a1, a2, a3);
78  }
79 
80  };
81 
85  void* getCreator(const std::string& id, const std::string& type);
86 
99  template <typename F>
100  inline F getCreator(const std::string& id) {
101  union { void* src; F dst; } p2p;
102  p2p.src = getCreator(id, typeid(F).name());
103  return p2p.dst;
104  }
105 
109  std::string demangle(const std::type_info& id);
110 
112  template <typename T>
113  inline std::string demangle() { return demangle(typeid(T)); }
114 
117  public:
118  typedef std::string KeyType;
119 
121  typedef std::map<KeyType, std::string> Properties;
122 
123  struct FactoryInfo {
124  FactoryInfo(const std::string& lib, void* p=0,
125  const std::string& t="",
126  const std::string& rt="",
127  const std::string& cn="",
128  const Properties& props=Properties()):
129  library(lib), ptr(p), type(t), rtype(rt), className(cn), properties(props) {}
130 
131  std::string library;
132  void* ptr;
133  std::string type;
134  std::string rtype;
135  std::string className;
137 
138  FactoryInfo& addProperty(const KeyType& k, const std::string& v) {
139  properties[k] = v;
140  return *this;
141  }
142  };
143 
145  typedef std::map<KeyType, FactoryInfo> FactoryMap;
146 
148  static Registry& instance();
149 
151  template <typename F, typename T, typename I>
152  inline FactoryInfo& add(const I& id, typename F::FuncType ptr){
153  union { typename F::FuncType src; void* dst; } p2p;
154  p2p.src = ptr;
155  std::ostringstream o; o << id;
156  return add(o.str(), p2p.dst,
157  typeid(typename F::FuncType).name(),
158  typeid(typename F::ReturnType).name(),
159  demangle<T>());
160  }
161 
163  void* get(const std::string& id, const std::string& type) const;
164 
166  const FactoryInfo& getInfo(const std::string& id) const;
167 
169  Registry&
170  addProperty(const std::string& id,
171  const std::string& k,
172  const std::string& v);
173 
175  std::set<KeyType> loadedFactories() const;
176 
178  inline const FactoryMap& factories() const {
179  if (!m_initialized) const_cast<Registry*>(this)->initialize();
180  return m_factories;
181  }
182 
183  private:
188  Registry();
189 
191  Registry(const Registry&): m_initialized(false) {}
192 
194  FactoryInfo&
195  add(const std::string& id, void *factory,
196  const std::string& type, const std::string& rtype,
197  const std::string& className,
198  const Properties& props = Properties());
199 
201  inline FactoryMap& factories() {
202  if (!m_initialized) initialize();
203  return m_factories;
204  }
205 
208  void initialize();
209 
212 
215 
216 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
217  mutable std::recursive_mutex m_mutex;
219 #endif
220  };
221 
224  public:
225  enum Level { Debug=0, Info=1, Warning=2, Error=3 };
226  Logger(Level level = Warning): m_level(level) {}
227  virtual ~Logger() {}
228  inline Level level() const { return m_level; }
229  inline void setLevel(Level level) { m_level = level; }
230  inline void info(const std::string& msg) { report(Info, msg); }
231  inline void debug(const std::string& msg) { report(Debug, msg); }
232  inline void warning(const std::string& msg) { report(Warning, msg); }
233  inline void error(const std::string& msg) { report(Error, msg); }
234  private:
235  virtual void report(Level lvl, const std::string& msg);
237  };
238 
244  }
245 
247  GAUDIPS_API void SetDebug(int debugLevel);
249  GAUDIPS_API int Debug();
250 
251 }}
252 
253 #define _INTERNAL_FACTORY_REGISTER_CNAME(name, serial) \
254  _register_ ## _ ## serial
255 
256 #define _INTERNAL_DECLARE_FACTORY_WITH_CREATOR(type, typecreator, \
257  id, factory, serial) \
258  namespace { \
259  class _INTERNAL_FACTORY_REGISTER_CNAME(type, serial) { \
260  public: \
261  typedef factory s_t; \
262  typedef typecreator f_t; \
263  static s_t::FuncType creator() { return &f_t::create<s_t>; } \
264  _INTERNAL_FACTORY_REGISTER_CNAME(type, serial) () { \
265  using ::Gaudi::PluginService::Details::Registry; \
266  Registry::instance().add<s_t, type>(id, creator()); \
267  } \
268  } _INTERNAL_FACTORY_REGISTER_CNAME(s_ ## type, serial); \
269  }
270 
271 #define _INTERNAL_DECLARE_FACTORY(type, id, factory, serial) \
272  _INTERNAL_DECLARE_FACTORY_WITH_CREATOR(type, \
273  ::Gaudi::PluginService::Details::Factory<type>, \
274  id, factory, serial)
275 
276 #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).
static S::ReturnType create(typename S::Arg1Type a1, typename S::Arg2Type a2)
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.
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.
static S::ReturnType create(typename S::Arg1Type a1)
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:15
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.
static S::ReturnType create(typename S::Arg1Type a1, typename S::Arg2Type a2, typename S::Arg3Type a3)