The Gaudi Framework  v29r0 (ff2e7097)
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 <map>
17 #include <set>
18 #include <sstream>
19 #include <string>
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
48 {
49  namespace PluginService
50  {
51 
52  namespace Details
53  {
58  template <class T>
59  class Factory
60  {
61  public:
62 #if !defined( __REFLEX__ ) || defined( ATLAS )
63  template <typename S, typename... Args>
64  static typename S::ReturnType create( Args&&... args )
65  {
66  return new T( std::forward<Args>( args )... );
67  }
68 #endif
69  };
70 
74  void* getCreator( const std::string& id, const std::string& type );
75 
88  template <typename F>
89  inline F getCreator( const std::string& id )
90  {
91  union {
92  void* src;
93  F dst;
94  } p2p;
95  p2p.src = getCreator( id, typeid( F ).name() );
96  return p2p.dst;
97  }
98 
102  std::string demangle( const std::type_info& id );
103 
105  template <typename T>
107  {
108  return demangle( typeid( T ) );
109  }
110 
113  {
114  public:
116 
119 
120  struct FactoryInfo {
121  FactoryInfo( std::string lib, void* p = 0, std::string t = "", std::string rt = "", std::string cn = "",
122  Properties props = Properties() )
123  : library( std::move( lib ) )
124  , ptr( p )
125  , type( std::move( t ) )
126  , rtype( std::move( rt ) )
127  , className( std::move( cn ) )
128  , properties( std::move( props ) )
129  {
130  }
131 
133  void* ptr;
137  Properties properties;
138 
139  FactoryInfo& addProperty( const KeyType& k, std::string v )
140  {
141  properties[k] = std::move( v );
142  return *this;
143  }
144  };
145 
148 
150  static Registry& instance();
151 
153  template <typename F, typename T, typename I>
154  inline FactoryInfo& add( const I& id, typename F::FuncType ptr )
155  {
156  union {
157  typename F::FuncType src;
158  void* dst;
159  } p2p;
160  p2p.src = ptr;
162  o << id;
163  return add( o.str(), p2p.dst, typeid( typename F::FuncType ).name(), typeid( typename F::ReturnType ).name(),
164  demangle<T>() );
165  }
166 
168  void* get( const std::string& id, const std::string& type ) const;
169 
171  const FactoryInfo& getInfo( const std::string& id ) const;
172 
174  Registry& addProperty( const std::string& id, const std::string& k, const std::string& v );
175 
177  std::set<KeyType> loadedFactories() const;
178 
180  inline const FactoryMap& factories() const
181  {
182  if ( !m_initialized ) const_cast<Registry*>( this )->initialize();
183  return m_factories;
184  }
185 
186  private:
191  Registry();
192 
194  Registry( const Registry& ) : m_initialized( false ) {}
195 
197  FactoryInfo& add( const std::string& id, void* factory, const std::string& type, const std::string& rtype,
198  const std::string& className, const Properties& props = Properties() );
199 
201  inline FactoryMap& factories()
202  {
203  if ( !m_initialized ) initialize();
204  return m_factories;
205  }
206 
209  void initialize();
210 
213 
215  FactoryMap m_factories;
216 
217 #if defined( __GXX_EXPERIMENTAL_CXX0X__ ) || __cplusplus >= 201103L
218  mutable std::recursive_mutex m_mutex;
220 #endif
221  };
222 
225  {
226  public:
227  enum Level { Debug = 0, Info = 1, Warning = 2, Error = 3 };
228  Logger( Level level = Warning ) : m_level( level ) {}
229  virtual ~Logger() {}
230  inline Level level() const { return m_level; }
231  inline void setLevel( Level level ) { m_level = level; }
232  inline void info( const std::string& msg ) { report( Info, msg ); }
233  inline void debug( const std::string& msg ) { report( Debug, msg ); }
234  inline void warning( const std::string& msg ) { report( Warning, msg ); }
235  inline void error( const std::string& msg ) { report( Error, msg ); }
236 
237  private:
238  virtual void report( Level lvl, const std::string& msg );
240  };
241 
247  }
248 
250  GAUDIPS_API void SetDebug( int debugLevel );
252  GAUDIPS_API int Debug();
253  }
254 }
255 
256 #define _INTERNAL_FACTORY_REGISTER_CNAME( name, serial ) _register_##_##serial
257 
258 #define _INTERNAL_DECLARE_FACTORY_WITH_CREATOR( type, typecreator, id, factory, serial ) \
259  namespace \
260  { \
261  class _INTERNAL_FACTORY_REGISTER_CNAME( type, serial ) \
262  { \
263  public: \
264  typedef factory s_t; \
265  typedef typecreator f_t; \
266  static s_t::FuncType creator() { return &f_t::create<s_t>; } \
267  _INTERNAL_FACTORY_REGISTER_CNAME( type, serial )() \
268  { \
269  using ::Gaudi::PluginService::Details::Registry; \
270  Registry::instance().add<s_t, type>( id, creator() ); \
271  } \
272  } _INTERNAL_FACTORY_REGISTER_CNAME( s_##type, serial ); \
273  }
274 
275 #define _INTERNAL_DECLARE_FACTORY( type, id, factory, serial ) \
276  _INTERNAL_DECLARE_FACTORY_WITH_CREATOR( type, ::Gaudi::PluginService::Details::Factory<type>, id, factory, serial )
277 
278 #endif //_GAUDI_PLUGIN_SERVICE_DETAILS_H_
#define GAUDIPS_API
Registry(const Registry &)
Private copy constructor for the singleton pattern.
Class providing default factory functions.
STL namespace.
FactoryMap & factories()
Return the known factories (loading the list if not yet done).
std::vector< Gaudi::Details::PropertyBase * > Properties
Definition: PropertyMgr.h:134
GAUDIPS_API Logger & logger()
Return the current logger instance.
FactoryInfo & addProperty(const KeyType &k, std::string v)
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)
STL class.
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
FactoryInfo(std::string lib, void *p=0, std::string t="", std::string rt="", std::string cn="", Properties props=Properties())
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).
T move(T...args)
void warning(const std::string &msg)
STL class.
GAUDIPS_API void * getCreator(const std::string &id, const std::string &type)
Function used to load a specific factory function.
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.
std::map< KeyType, FactoryInfo > FactoryMap
Type used for the database implementation.
FactoryMap m_factories
Internal storage for factories.
Helper functions to set/get the application return code.
Definition: __init__.py:1
bool m_initialized
Flag recording if the registry has been initialized or not.