The Gaudi Framework  v30r3 (a5ef0a68)
IInterface.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_IINTERFACE_H
2 #define GAUDIKERNEL_IINTERFACE_H
3 
4 // Include files
5 #include "GaudiKernel/Kernel.h"
7 #include "GaudiKernel/System.h"
8 #include <ostream>
9 #include <type_traits>
10 #include <typeinfo>
11 
13 #define DeclareInterfaceID( iface, major, minor ) \
14  static const InterfaceID& interfaceID() { return iid::interfaceID(); } \
15  using iid = Gaudi::InterfaceId<iface, major, minor>; \
16  using ext_iids = iid::iids
17 
30 {
31 public:
32 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
33  constexpr InterfaceID( unsigned long lid )
35  : m_id( lid & 0xFFFF ), m_major_ver( ( lid & 0xFF000000 ) >> 24 ), m_minor_ver( ( lid & 0xFF0000 ) >> 16 )
36  {
37  }
38 #endif
39  constexpr InterfaceID( unsigned long id, unsigned long major, unsigned long minor = 0 )
41  : m_id( id ), m_major_ver( major ), m_minor_ver( minor )
42  {
43  }
45  InterfaceID( const char* name, unsigned long major, unsigned long minor = 0 )
46  : m_id( hash32( name ) ), m_major_ver( major ), m_minor_ver( minor )
47  {
48  }
49 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
50  constexpr operator unsigned long() const { return ( m_major_ver << 24 ) + ( m_minor_ver << 16 ) + m_id; }
52 #endif
53  constexpr unsigned long id() const { return m_id; }
56  constexpr unsigned long majorVersion() const { return m_major_ver; }
58  constexpr unsigned long minorVersion() const { return m_minor_ver; }
62  constexpr bool versionMatch( const InterfaceID& iid ) const
63  {
64  return ( id() == iid.id() && majorVersion() == iid.majorVersion() && minorVersion() >= iid.minorVersion() );
65  }
67  constexpr bool fullMatch( const InterfaceID& iid ) const
68  {
69  return ( id() == iid.id() && majorVersion() == iid.majorVersion() && minorVersion() == iid.minorVersion() );
70  }
72  constexpr bool operator==( const InterfaceID& iid ) const { return fullMatch( iid ); }
74  static unsigned int hash32( const char* key )
75  {
76  unsigned int hash = 0;
77  for ( const char* k = key; *k; ++k ) {
78  hash += *k;
79  hash += ( hash << 10 );
80  hash ^= ( hash >> 6 );
81  }
82  hash += ( hash << 3 );
83  hash ^= ( hash >> 11 );
84  hash += ( hash << 15 );
85  return hash;
86  }
87 
88 private:
89  unsigned long m_id;
90  unsigned long m_major_ver;
91  unsigned long m_minor_ver;
92 };
93 
94 namespace Gaudi
95 {
96 
97  template <typename... I>
98  struct interface_list {
99  };
100 
101  namespace meta
102  {
103  // identity T -> type = T; note that id_<T> is a complete type, even if T is not
104  template <typename T>
105  struct id_ {
106  using type = T;
107  };
108 
109  namespace detail
110  {
111  template <typename... Is>
112  struct inherit_from : Is... {
113  };
114 
115  template <typename List, typename I>
116  struct append1 {
117  };
118 
119  // interpose an id_<I> as id_<I> is a complete type, even if I is not... and we need complete
120  // types to inherit from
121  template <typename... Is, typename I>
122  struct append1<interface_list<Is...>, I>
123  : id_<typename std::conditional<std::is_base_of<id_<I>, inherit_from<id_<Is>...>>::value,
124  interface_list<Is...>, interface_list<Is..., I>>::type> {
125  };
126 
127  template <typename, typename>
128  struct appendN {
129  };
130 
131  template <typename State>
132  struct appendN<interface_list<>, State> : id_<State> {
133  };
134 
135  template <typename... Is, typename I, typename List>
136  struct appendN<interface_list<I, Is...>, List> : appendN<interface_list<Is...>, typename append1<List, I>::type> {
137  };
138  }
139 
140  template <typename... Is>
142  }
143 
144  // interface_list concatenation
145  template <typename... I>
147 
148  // identity
149  template <typename... I>
151  };
152 
153  // binary op
154  template <typename... I1, typename... I2>
156  };
157 
158  // induction of binary op
159  template <typename... I1, typename... I2, typename... Others>
160  struct interface_list_cat<interface_list<I1...>, interface_list<I2...>, Others...>
161  : interface_list_cat<interface_list<I1..., I2...>, Others...> {
162  };
163 
164  // append is a special case of concatenation...
165  template <typename... I>
167 
168  template <typename... Is, typename I>
170  : interface_list_cat<interface_list<Is...>, interface_list<I>> {
171  };
172 
173  // helpers for implementation of interface cast
174  namespace iid_cast_details
175  {
176  template <typename I>
177  constexpr void* void_cast( const I* i )
178  {
179  return const_cast<I*>( i );
180  }
181 
182  template <typename... Is>
183  struct iid_cast_t;
184 
185  template <>
186  struct iid_cast_t<> {
187  template <typename P>
188  constexpr void* operator()( const InterfaceID&, P* ) const
189  {
190  return nullptr;
191  }
192  };
193 
194  template <typename I, typename... Is>
195  struct iid_cast_t<I, Is...> {
196  template <typename P>
197  inline void* operator()( const InterfaceID& tid, P* ptr ) const
198  {
199  return tid.versionMatch( I::interfaceID() ) ? void_cast<typename I::interface_type>( ptr )
200  : iid_cast_t<Is...>{}( tid, ptr );
201  }
202  };
203  }
204 
205  template <typename... Is>
207  {
208  return {Is::name()...};
209  }
210 
211  template <typename... Is, typename P>
212  inline void* iid_cast( const InterfaceID& tid, Gaudi::interface_list<Is...>, P* ptr )
213  {
214  constexpr auto iid_cast_ = iid_cast_details::iid_cast_t<Is...>{};
215  return iid_cast_( tid, ptr );
216  }
217 
221  template <typename INTERFACE, unsigned long majVers, unsigned long minVers>
222  struct InterfaceId final {
224  using interface_type = INTERFACE;
227 
228  static inline std::string name() { return System::typeinfoName( typeid( INTERFACE ) ); }
229  static constexpr unsigned long majorVersion() { return majVers; }
230  static constexpr unsigned long minorVersion() { return minVers; }
231 
232  static inline const std::type_info& TypeInfo() { return typeid( typename iids::type ); }
233 
234  static inline const InterfaceID& interfaceID()
235  {
236  static const InterfaceID s_iid( name().c_str(), majVers, minVers );
237  return s_iid;
238  }
239  };
240 
241  constexpr struct fullMatch_t {
242  template <typename IFACE1, typename IFACE2, unsigned long major1, unsigned long major2, unsigned long minor1,
243  unsigned long minor2>
245  {
246  return false;
247  }
248  template <typename IFACE, unsigned long major, unsigned long minor>
250  {
251  return true;
252  }
253  } fullMatch{};
254 
255  constexpr struct majorMatch_t {
256  template <typename IFACE1, typename IFACE2, unsigned long major1, unsigned long major2, unsigned long minor1,
257  unsigned long minor2>
259  {
260  return false;
261  }
262  template <typename IFACE, unsigned long major, unsigned long minor1, unsigned long minor2>
264  {
265  return true;
266  }
267  } majorMatch{};
268 }
269 
278 {
279 public:
282 
285 
287  static inline const InterfaceID& interfaceID() { return iid::interfaceID(); }
288 
290  virtual void* i_cast( const InterfaceID& ) const
291 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
292  {
293  return nullptr;
294  }
295 #else
296  = 0;
297 #endif
298 
301 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
302  {
303  return {};
304  }
305 #else
306  = 0;
307 #endif
308 
310  virtual unsigned long addRef() = 0;
311 
313  virtual unsigned long release() = 0;
314 
316  virtual unsigned long refCount() const
317 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
318  {
319  IInterface* ths = const_cast<IInterface*>( this );
320  ths->addRef();
321  return ths->release();
322  } // new method, so we need a default implementation for v20 compatibility
323 #else
324  = 0;
325 #endif
326 
328  virtual StatusCode queryInterface( const InterfaceID& ti, void** pp ) = 0;
329 
331  enum class Status : StatusCode::code_t {
333  FAILURE = 0,
335  SUCCESS = 1,
337  NO_INTERFACE,
339  VERSMISMATCH,
341  LAST_ERROR
342  };
343 
345  virtual ~IInterface() = default;
346 };
347 
349 
350 namespace Gaudi
351 {
353  template <typename TARGET>
354  TARGET* Cast( IInterface* i )
355  {
356  return reinterpret_cast<TARGET*>( i->i_cast( TARGET::interfaceID() ) );
357  }
360  template <typename TARGET>
361  const TARGET* Cast( const IInterface* i )
362  {
363  return reinterpret_cast<const TARGET*>( i->i_cast( TARGET::interfaceID() ) );
364  }
365 }
366 
377 template <class I>
378 bool isValidInterface( I* i )
379 {
380  void* ii = nullptr;
381  ;
382  StatusCode sc = i->queryInterface( I::interfaceID(), &ii );
383  return sc.isSuccess();
384 }
385 
386 //#ifdef GAUDI_V20_COMPAT
389 {
390  s << "IID_" << id.id();
391  return s;
392 }
393 //#endif
394 
405 template <class DEST, class SRC>
406 inline DEST** pp_cast( SRC** ptr )
407 {
408  return reinterpret_cast<DEST**>( ptr );
409 }
410 
412 #include "GaudiKernel/extends.h"
413 #include "GaudiKernel/implements.h"
414 
415 #endif // GAUDIKERNEL_IINTERFACE_H
std::ostream & operator<<(std::ostream &s, const InterfaceID &id)
ostream operator for InterfaceID. Needed by PluginSvc
Definition: IInterface.h:388
constexpr bool operator()(InterfaceId< IFACE, major, minor1 >, InterfaceId< IFACE, major, minor2 >) const
Definition: IInterface.h:263
constexpr bool operator()(InterfaceId< IFACE1, major1, minor1 >, InterfaceId< IFACE2, major2, minor2 >) const
Definition: IInterface.h:244
constexpr void * operator()(const InterfaceID &, P *) const
Definition: IInterface.h:188
const TARGET * Cast(const IInterface *i)
Cast a IInterface pointer to an IInterface specialization (TARGET).
Definition: IInterface.h:361
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:332
bool isSuccess() const
Definition: StatusCode.h:287
static unsigned int hash32(const char *key)
Jenkins one-at-time hash function – see https://en.wikipedia.org/wiki/Jenkins_hash_function.
Definition: IInterface.h:74
unsigned long m_id
Definition: IInterface.h:89
#define STATUSCODE_ENUM_DECL(ENUM)
Declare an enum to be used as StatusCode value.
Definition: StatusCode.h:258
bool isValidInterface(I *i)
Templated function that throws an exception if the version if the interface implemented by the object...
Definition: IInterface.h:378
State
Allowed states for classes implementing the state machine (ApplicationMgr, Algorithm, Service, AlgTool).
Definition: StateMachine.h:14
INTERFACE interface_type
interface type
Definition: IInterface.h:224
static constexpr unsigned long majorVersion()
Definition: IInterface.h:229
Class to handle automatically the versioning of the interfaces when they are inheriting from other in...
Definition: IInterface.h:222
DEST ** pp_cast(SRC **ptr)
Small function to be used instead of the construct (void**)&pointer, which produces, on gcc 4.1 optimized, the warning warning: dereferencing type-punned pointer will break strict-aliasing rules The assempler code produced is equivalent to the one with the direct cast.
Definition: IInterface.h:406
STL class.
virtual void * i_cast(const InterfaceID &) const =0
main cast function
Interface ID class.
Definition: IInterface.h:29
unsigned long m_minor_ver
Definition: IInterface.h:91
TupleObj.h GaudiAlg/TupleObj.h namespace with few technical implementations.
constexpr bool operator()(InterfaceId< IFACE, major, minor >, InterfaceId< IFACE, major, minor >) const
Definition: IInterface.h:249
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
Definition of the basic interface.
Definition: IInterface.h:277
constexpr unsigned long minorVersion() const
get the minor version of the interface
Definition: IInterface.h:58
Status
Return status.
Definition: IInterface.h:331
constexpr bool versionMatch(const InterfaceID &iid) const
check compatibility.
Definition: IInterface.h:62
static std::string name()
Definition: IInterface.h:228
static constexpr unsigned long minorVersion()
Definition: IInterface.h:230
unsigned long m_major_ver
Definition: IInterface.h:90
virtual unsigned long release()=0
Release Interface instance.
constexpr bool operator()(InterfaceId< IFACE1, major1, minor1 >, InterfaceId< IFACE2, major2, minor2 >) const
Definition: IInterface.h:258
void * operator()(const InterfaceID &tid, P *ptr) const
Definition: IInterface.h:197
static const InterfaceID & interfaceID()
Definition: IInterface.h:234
constexpr unsigned long id() const
get the interface identifier
Definition: IInterface.h:54
string s
Definition: gaudirun.py:253
constexpr bool operator==(const InterfaceID &iid) const
compare operator
Definition: IInterface.h:72
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
Gaudi::interface_list< iid > ext_iids
Extra interfaces.
Definition: IInterface.h:284
std::vector< std::string > getInterfaceNames(Gaudi::interface_list< Is... >)
Definition: IInterface.h:206
constexpr void * void_cast(const I *i)
Definition: IInterface.h:177
constexpr unsigned long majorVersion() const
get the major version of the interface
Definition: IInterface.h:56
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
constexpr bool fullMatch(const InterfaceID &iid) const
check full compatibility.
Definition: IInterface.h:67
InterfaceID(const char *name, unsigned long major, unsigned long minor=0)
constructor from components
Definition: IInterface.h:45
void * iid_cast(const InterfaceID &tid, Gaudi::interface_list< Is... >, P *ptr)
Definition: IInterface.h:212
#define GAUDI_API
Definition: Kernel.h:104
STL class.
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:287
typename Gaudi::interface_list_append< typename interface_type::ext_iids, InterfaceId >::type iids
List of interfaces.
Definition: IInterface.h:226
Helper functions to set/get the application return code.
Definition: __init__.py:1
unsigned long code_t
type of StatusCode value
Definition: StatusCode.h:54
Gaudi::InterfaceId< IInterface, 0, 0 > iid
Interface ID.
Definition: IInterface.h:281
static const std::type_info & TypeInfo()
Definition: IInterface.h:232