The Gaudi Framework  v30r3 (a5ef0a68)
PluginServiceDetailsV2.h
Go to the documentation of this file.
1 #ifndef _GAUDI_PLUGIN_SERVICE_DETAILS_V2_H_
2 #define _GAUDI_PLUGIN_SERVICE_DETAILS_V2_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 
17 
18 #if __cplusplus >= 201703
19 #include <any>
20 #else
21 #include <boost/any.hpp>
22 namespace std
23 {
24  using boost::any;
25  using boost::any_cast;
26  using boost::bad_any_cast;
27 }
28 #endif
29 
30 #include <functional>
31 #include <map>
32 #include <memory>
33 #include <mutex>
34 #include <set>
35 #include <sstream>
36 #include <string>
37 #include <typeinfo>
38 #include <utility>
39 
40 namespace Gaudi
41 {
42  namespace PluginService
43  {
45  {
47  template <typename>
48  struct Factory;
50 
52  namespace Details
53  {
54  template <typename>
55  struct Traits;
56 
57  template <typename R, typename... Args>
58  struct Traits<R( Args... )> {
59  using ReturnType = std::unique_ptr<std::remove_pointer_t<R>>;
60  using FactoryType = std::function<ReturnType( Args... )>;
61  };
62 
66  std::string demangle( const std::type_info& id );
67 
69  template <typename T>
70  inline std::string demangle()
71  {
72  return demangle( typeid( T ) );
73  }
74 
76  template <typename ID>
77  inline std::string stringify_id( const ID& id )
78  {
80  o << id;
81  return o.str();
82  }
84  template <>
85  inline std::string stringify_id<std::string>( const std::string& id )
86  {
87  return id;
88  }
89 
91  void reportBadAnyCast( const std::type_info& factory_type, const std::string& id );
92 
94  class GAUDIPS_API Logger
95  {
96  public:
97  enum Level { Debug = 0, Info = 1, Warning = 2, Error = 3 };
98  Logger( Level level = Warning ) : m_level( level ) {}
99  virtual ~Logger() {}
100  inline Level level() const { return m_level; }
101  inline void setLevel( Level level ) { m_level = level; }
102  inline void info( const std::string& msg ) { report( Info, msg ); }
103  inline void debug( const std::string& msg ) { report( Debug, msg ); }
104  inline void warning( const std::string& msg ) { report( Warning, msg ); }
105  inline void error( const std::string& msg ) { report( Error, msg ); }
106 
107  private:
108  virtual void report( Level lvl, const std::string& msg );
109  Level m_level;
110  };
111 
113  GAUDIPS_API Logger& logger();
116  GAUDIPS_API void setLogger( Logger* logger );
117 
119  class GAUDIPS_API Registry
120  {
121  public:
122  using KeyType = std::string;
123 
126 
127  struct FactoryInfo {
128  std::string library;
129  std::any factory{};
131 
132  inline bool is_set() const
133  {
134 #if __cplusplus >= 201703
135  return factory.has_value();
136 #else
137  return !factory.empty();
138 #endif
139  }
140  Properties::mapped_type getprop( const Properties::key_type& name ) const;
141  };
142 
144  using FactoryMap = std::map<KeyType, FactoryInfo>;
145 
147  template <typename F>
148  F get( const KeyType& id )
149  {
150  const FactoryInfo& info = Registry::instance().getInfo( id, true );
151 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
152  if ( !info.getprop( "ReflexName" ).empty() ) {
153  const std::string real_name = info.getprop( "ClassName" );
154  logger().warning( "requesting factory via old name '" + id + "' use '" +
155  ( real_name.empty() ? "<undefined>" : real_name ) + "' instead" );
156  }
157 #endif
158  return std::any_cast<F>( info.factory );
159  }
160 
162  static Registry& instance();
163 
165  FactoryInfo& add( const KeyType& id, FactoryInfo info );
166 
168  const FactoryInfo& getInfo( const KeyType& id, const bool load = false ) const;
169 
171  Registry& addProperty( const KeyType& id, const KeyType& k, const std::string& v );
172 
174  std::set<KeyType> loadedFactoryNames() const;
175 
181  const FactoryMap& factories() const;
182 
183  private:
185  Registry();
186 
188  Registry( const Registry& ) = delete;
189 
191  FactoryMap& factories();
192 
195  void initialize();
196 
198  mutable std::once_flag m_initialized;
199 
201  FactoryMap m_factories;
202 
204  mutable std::recursive_mutex m_mutex;
205  };
206 
211  template <typename, typename>
212  struct DefaultFactory;
213  template <typename T, typename R, typename... Args>
214  struct DefaultFactory<T, Factory<R( Args... )>> {
215  inline typename Factory<R( Args... )>::ReturnType operator()( Args... args )
216  {
217  return std::make_unique<T>( std::forward<Args>( args )... );
218  }
219  };
220 
224  std::string getDSONameFor( void* fptr );
225  }
226 
228  GAUDIPS_API void SetDebug( int debugLevel );
230  GAUDIPS_API int Debug();
231  }
232  }
233 }
234 
235 #define _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME_TOKEN( serial ) _register_##serial
236 #define _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME( serial ) \
237  _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME_TOKEN( serial )
238 #define _PS_V2_INTERNAL_FACTORY_REGISTER_CNAME _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME( __LINE__ )
239 
240 #endif //_GAUDI_PLUGIN_SERVICE_DETAILS_H_
T empty(T...args)
#define GAUDI_PLUGIN_SERVICE_V2_INLINE
GAUDIPS_API void setLogger(Logger *logger)
Set the logger instance to use.
STL namespace.
std::string getDSONameFor(void *fptr)
void reportBadAnyCast(const std::type_info &factory_type, const std::string &id)
STL class.
GAUDIPS_API Logger & logger()
Return the current logger instance.
#define GAUDIPS_API
STL class.
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
STL class.
GAUDIPS_API std::string demangle(const std::type_info &id)
Return a canonical name for type_info object (implementation borrowed from GaudiKernel/System).
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
Helper functions to set/get the application return code.
Definition: __init__.py:1