The Gaudi Framework  v30r0 (c919700c)
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 #include <mutex>
24 
25 #if __GNUC__ >= 4
26 #define GAUDIPS_HASCLASSVISIBILITY
27 #endif
28 
29 #if defined( GAUDIPS_HASCLASSVISIBILITY )
30 #define GAUDIPS_IMPORT __attribute__( ( visibility( "default" ) ) )
31 #define GAUDIPS_EXPORT __attribute__( ( visibility( "default" ) ) )
32 #define GAUDIPS_LOCAL __attribute__( ( visibility( "hidden" ) ) )
33 #else
34 #define GAUDIPS_IMPORT
35 #define GAUDIPS_EXPORT
36 #define GAUDIPS_LOCAL
37 #endif
38 
39 #ifdef GaudiPluginService_EXPORTS
40 #define GAUDIPS_API GAUDIPS_EXPORT
41 #else
42 #define GAUDIPS_API GAUDIPS_IMPORT
43 #endif
44 
45 namespace Gaudi
46 {
47  namespace PluginService
48  {
49 
50  namespace Details
51  {
56  template <class T>
57  class Factory
58  {
59  public:
60 #if !defined( __REFLEX__ ) || defined( ATLAS )
61  template <typename S, typename... Args>
62  static typename S::ReturnType create( Args&&... args )
63  {
64  return new T( std::forward<Args>( args )... );
65  }
66 #endif
67  };
68 
72  void* getCreator( const std::string& id, const std::string& type );
73 
86  template <typename F>
87  inline F getCreator( const std::string& id )
88  {
89  union {
90  void* src;
91  F dst;
92  } p2p;
93  p2p.src = getCreator( id, typeid( F ).name() );
94  return p2p.dst;
95  }
96 
100  std::string demangle( const std::type_info& id );
101 
103  template <typename T>
105  {
106  return demangle( typeid( T ) );
107  }
108 
111  {
112  public:
114 
117 
118  struct FactoryInfo {
119  FactoryInfo( std::string lib, void* p = nullptr, std::string t = "", std::string rt = "", std::string cn = "",
120  Properties props = Properties() )
121  : library( std::move( lib ) )
122  , ptr( p )
123  , type( std::move( t ) )
124  , rtype( std::move( rt ) )
125  , className( std::move( cn ) )
126  , properties( std::move( props ) )
127  {
128  }
129 
131  void* ptr;
135  Properties properties;
136 
137  FactoryInfo& addProperty( const KeyType& k, std::string v )
138  {
139  properties[k] = std::move( v );
140  return *this;
141  }
142  };
143 
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  {
154  union {
155  typename F::FuncType src;
156  void* dst;
157  } p2p;
158  p2p.src = ptr;
160  o << id;
161  return add( o.str(), p2p.dst, typeid( typename F::FuncType ).name(), typeid( typename F::ReturnType ).name(),
162  demangle<T>() );
163  }
164 
166  void* get( const std::string& id, const std::string& type ) const;
167 
169  const FactoryInfo& getInfo( const std::string& id ) const;
170 
172  Registry& addProperty( const std::string& id, const std::string& k, const std::string& v );
173 
175  std::set<KeyType> loadedFactoryNames() const;
176 
178  inline const FactoryMap& factories() const
179  {
180  if ( !m_initialized ) const_cast<Registry*>( this )->initialize();
181  return m_factories;
182  }
183 
184  private:
189  Registry();
190 
192  Registry( const Registry& ) : m_initialized( false ) {}
193 
195  FactoryInfo& add( const std::string& id, void* factory, const std::string& type, const std::string& rtype,
196  const std::string& className, const Properties& props = Properties() );
197 
199  inline FactoryMap& factories()
200  {
201  if ( !m_initialized ) initialize();
202  return m_factories;
203  }
204 
207  void initialize();
208 
211 
213  FactoryMap m_factories;
214 
217  };
218 
221  {
222  public:
223  enum Level { Debug = 0, Info = 1, Warning = 2, Error = 3 };
224  Logger( Level level = Warning ) : m_level( level ) {}
225  virtual ~Logger() {}
226  inline Level level() const { return m_level; }
227  inline void setLevel( Level level ) { m_level = level; }
228  inline void info( const std::string& msg ) { report( Info, msg ); }
229  inline void debug( const std::string& msg ) { report( Debug, msg ); }
230  inline void warning( const std::string& msg ) { report( Warning, msg ); }
231  inline void error( const std::string& msg ) { report( Error, msg ); }
232 
233  private:
234  virtual void report( Level lvl, const std::string& msg );
236  };
237 
243  }
244 
246  GAUDIPS_API void SetDebug( int debugLevel );
248  GAUDIPS_API int Debug();
249  }
250 }
251 
252 #define _INTERNAL_FACTORY_REGISTER_CNAME( name, serial ) _register_##_##serial
253 
254 #define _INTERNAL_DECLARE_FACTORY_WITH_CREATOR( type, typecreator, id, factory, serial ) \
255  namespace \
256  { \
257  class _INTERNAL_FACTORY_REGISTER_CNAME( type, serial ) \
258  { \
259  public: \
260  typedef factory s_t; \
261  typedef typecreator f_t; \
262  static s_t::FuncType creator() { return &f_t::create<s_t>; } \
263  _INTERNAL_FACTORY_REGISTER_CNAME( type, serial )() \
264  { \
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, ::Gaudi::PluginService::Details::Factory<type>, id, factory, serial )
273 
274 #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.
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.
std::recursive_mutex m_mutex
Mutex used to control concurrent access to the internal data.
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
FactoryInfo(std::string lib, void *p=nullptr, std::string t="", std::string rt="", std::string cn="", Properties props=Properties())
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.