Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
29 class GAUDI_API InterfaceID final {
30 public:
31 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
32  constexpr InterfaceID( unsigned long lid )
34  : m_id( lid & 0xFFFF ), m_major_ver( ( lid & 0xFF000000 ) >> 24 ), m_minor_ver( ( lid & 0xFF0000 ) >> 16 ) {}
35 #endif
36  constexpr InterfaceID( unsigned long id, unsigned long major, unsigned long minor = 0 )
38  : m_id( id ), m_major_ver( major ), m_minor_ver( minor ) {}
40  InterfaceID( const char* name, unsigned long major, unsigned long minor = 0 )
41  : m_id( hash32( name ) ), m_major_ver( major ), m_minor_ver( minor ) {}
42 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
43  constexpr operator unsigned long() const { return ( m_major_ver << 24 ) + ( m_minor_ver << 16 ) + m_id; }
45 #endif
46  constexpr unsigned long id() const { return m_id; }
49  constexpr unsigned long majorVersion() const { return m_major_ver; }
51  constexpr unsigned long minorVersion() const { return m_minor_ver; }
55  constexpr bool versionMatch( const InterfaceID& iid ) const {
56  return ( id() == iid.id() && majorVersion() == iid.majorVersion() && minorVersion() >= iid.minorVersion() );
57  }
59  constexpr bool fullMatch( const InterfaceID& iid ) const {
60  return ( id() == iid.id() && majorVersion() == iid.majorVersion() && minorVersion() == iid.minorVersion() );
61  }
63  constexpr bool operator==( const InterfaceID& iid ) const { return fullMatch( iid ); }
65  static unsigned int hash32( const char* key ) {
66  unsigned int hash = 0;
67  for ( const char* k = key; *k; ++k ) {
68  hash += *k;
69  hash += ( hash << 10 );
70  hash ^= ( hash >> 6 );
71  }
72  hash += ( hash << 3 );
73  hash ^= ( hash >> 11 );
74  hash += ( hash << 15 );
75  return hash;
76  }
77 
78 private:
79  unsigned long m_id;
80  unsigned long m_major_ver;
81  unsigned long m_minor_ver;
82 };
83 
84 namespace Gaudi {
85 
86  template <typename... I>
87  struct interface_list {};
88 
89  namespace meta {
90  // identity T -> type = T; note that id_<T> is a complete type, even if T is not
91  template <typename T>
92  struct id_ {
93  using type = T;
94  };
95 
96  namespace detail {
97  template <typename... Is>
98  struct inherit_from : Is... {};
99 
100  template <typename List, typename I>
101  struct append1 {};
102 
103  // interpose an id_<I> as id_<I> is a complete type, even if I is not... and we need complete
104  // types to inherit from
105  template <typename... Is, typename I>
106  struct append1<interface_list<Is...>, I>
107  : id_<typename std::conditional<std::is_base_of<id_<I>, inherit_from<id_<Is>...>>::value,
108  interface_list<Is...>, interface_list<Is..., I>>::type> {};
109 
110  template <typename, typename>
111  struct appendN {};
112 
113  template <typename State>
114  struct appendN<interface_list<>, State> : id_<State> {};
115 
116  template <typename... Is, typename I, typename List>
117  struct appendN<interface_list<I, Is...>, List> : appendN<interface_list<Is...>, typename append1<List, I>::type> {
118  };
119  } // namespace detail
120 
121  template <typename... Is>
123  } // namespace meta
124 
125  // interface_list concatenation
126  template <typename... I>
128 
129  // identity
130  template <typename... I>
132 
133  // binary op
134  template <typename... I1, typename... I2>
136  };
137 
138  // induction of binary op
139  template <typename... I1, typename... I2, typename... Others>
140  struct interface_list_cat<interface_list<I1...>, interface_list<I2...>, Others...>
141  : interface_list_cat<interface_list<I1..., I2...>, Others...> {};
142 
143  // append is a special case of concatenation...
144  template <typename... I>
146 
147  template <typename... Is, typename I>
149  : interface_list_cat<interface_list<Is...>, interface_list<I>> {};
150 
151  // helpers for implementation of interface cast
152  namespace iid_cast_details {
153  template <typename I>
154  constexpr void* void_cast( const I* i ) {
155  return const_cast<I*>( i );
156  }
157 
158  template <typename... Is>
159  struct iid_cast_t;
160 
161  template <>
162  struct iid_cast_t<> {
163  template <typename P>
164  constexpr void* operator()( const InterfaceID&, P* ) const {
165  return nullptr;
166  }
167  };
168 
169  template <typename I, typename... Is>
170  struct iid_cast_t<I, Is...> {
171  template <typename P>
172  inline void* operator()( const InterfaceID& tid, P* ptr ) const {
173  return tid.versionMatch( I::interfaceID() ) ? void_cast<typename I::interface_type>( ptr )
174  : iid_cast_t<Is...>{}( tid, ptr );
175  }
176  };
177  } // namespace iid_cast_details
178 
179  template <typename... Is>
181  return {Is::name()...};
182  }
183 
184  template <typename... Is, typename P>
185  inline void* iid_cast( const InterfaceID& tid, Gaudi::interface_list<Is...>, P* ptr ) {
186  constexpr auto iid_cast_ = iid_cast_details::iid_cast_t<Is...>{};
187  return iid_cast_( tid, ptr );
188  }
189 
193  template <typename INTERFACE, unsigned long majVers, unsigned long minVers>
194  struct InterfaceId final {
196  using interface_type = INTERFACE;
199 
200  static inline std::string name() { return System::typeinfoName( typeid( INTERFACE ) ); }
201  static constexpr unsigned long majorVersion() { return majVers; }
202  static constexpr unsigned long minorVersion() { return minVers; }
203 
204  static inline const std::type_info& TypeInfo() { return typeid( typename iids::type ); }
205 
206  static inline const InterfaceID& interfaceID() {
207  static const InterfaceID s_iid( name().c_str(), majVers, minVers );
208  return s_iid;
209  }
210  };
211 
212  constexpr struct fullMatch_t {
213  template <typename IFACE1, typename IFACE2, unsigned long major1, unsigned long major2, unsigned long minor1,
214  unsigned long minor2>
216  return false;
217  }
218  template <typename IFACE, unsigned long major, unsigned long minor>
220  return true;
221  }
222  } fullMatch{};
223 
224  constexpr struct majorMatch_t {
225  template <typename IFACE1, typename IFACE2, unsigned long major1, unsigned long major2, unsigned long minor1,
226  unsigned long minor2>
228  return false;
229  }
230  template <typename IFACE, unsigned long major, unsigned long minor1, unsigned long minor2>
232  return true;
233  }
234  } majorMatch{};
235 } // namespace Gaudi
236 
245 public:
248 
251 
253  static inline const InterfaceID& interfaceID() { return iid::interfaceID(); }
254 
256  virtual void* i_cast( const InterfaceID& ) const
257 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
258  {
259  return nullptr;
260  }
261 #else
262  = 0;
263 #endif
264 
267 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
268  {
269  return {};
270  }
271 #else
272  = 0;
273 #endif
274 
276  virtual unsigned long addRef() = 0;
277 
279  virtual unsigned long release() = 0;
280 
282  virtual unsigned long refCount() const
283 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
284  {
285  IInterface* ths = const_cast<IInterface*>( this );
286  ths->addRef();
287  return ths->release();
288  } // new method, so we need a default implementation for v20 compatibility
289 #else
290  = 0;
291 #endif
292 
294  virtual StatusCode queryInterface( const InterfaceID& ti, void** pp ) = 0;
295 
297  enum class Status : StatusCode::code_t {
299  FAILURE = 0,
301  SUCCESS = 1,
303  NO_INTERFACE,
305  VERSMISMATCH,
307  LAST_ERROR
308  };
309 
311  virtual ~IInterface() = default;
312 };
313 
315 
316 namespace Gaudi {
318  template <typename TARGET>
319  TARGET* Cast( IInterface* i ) {
320  return reinterpret_cast<TARGET*>( i->i_cast( TARGET::interfaceID() ) );
321  }
324  template <typename TARGET>
325  const TARGET* Cast( const IInterface* i ) {
326  return reinterpret_cast<const TARGET*>( i->i_cast( TARGET::interfaceID() ) );
327  }
328 } // namespace Gaudi
329 
340 template <class I>
341 bool isValidInterface( I* i ) {
342  void* ii = nullptr;
343  ;
344  StatusCode sc = i->queryInterface( I::interfaceID(), &ii );
345  return sc.isSuccess();
346 }
347 
348 //#ifdef GAUDI_V20_COMPAT
351  s << "IID_" << id.id();
352  return s;
353 }
354 //#endif
355 
366 template <class DEST, class SRC>
367 inline DEST** pp_cast( SRC** ptr ) {
368  return reinterpret_cast<DEST**>( ptr );
369 }
370 
372 #include "GaudiKernel/extends.h"
373 #include "GaudiKernel/implements.h"
374 
375 #endif // GAUDIKERNEL_IINTERFACE_H
std::ostream & operator<<(std::ostream &s, const InterfaceID &id)
ostream operator for InterfaceID. Needed by PluginSvc
Definition: IInterface.h:350
constexpr bool operator()(InterfaceId< IFACE, major, minor1 >, InterfaceId< IFACE, major, minor2 >) const
Definition: IInterface.h:231
constexpr bool operator()(InterfaceId< IFACE1, major1, minor1 >, InterfaceId< IFACE2, major2, minor2 >) const
Definition: IInterface.h:215
constexpr void * operator()(const InterfaceID &, P *) const
Definition: IInterface.h:164
const TARGET * Cast(const IInterface *i)
Cast a IInterface pointer to an IInterface specialization (TARGET).
Definition: IInterface.h:325
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:309
bool isSuccess() const
Definition: StatusCode.h:267
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:65
unsigned long m_id
Definition: IInterface.h:79
#define STATUSCODE_ENUM_DECL(ENUM)
Declare an enum to be used as StatusCode value.
Definition: StatusCode.h:239
bool isValidInterface(I *i)
Templated function that throws an exception if the version if the interface implemented by the object...
Definition: IInterface.h:341
State
Allowed states for classes implementing the state machine (ApplicationMgr, Algorithm, Service, AlgTool).
Definition: StateMachine.h:12
INTERFACE interface_type
interface type
Definition: IInterface.h:196
static constexpr unsigned long majorVersion()
Definition: IInterface.h:201
Class to handle automatically the versioning of the interfaces when they are inheriting from other in...
Definition: IInterface.h:194
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:367
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:81
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:219
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
Definition of the basic interface.
Definition: IInterface.h:244
constexpr unsigned long minorVersion() const
get the minor version of the interface
Definition: IInterface.h:51
Status
Return status.
Definition: IInterface.h:297
constexpr bool versionMatch(const InterfaceID &iid) const
check compatibility.
Definition: IInterface.h:55
static std::string name()
Definition: IInterface.h:200
static constexpr unsigned long minorVersion()
Definition: IInterface.h:202
unsigned long m_major_ver
Definition: IInterface.h:80
virtual unsigned long release()=0
Release Interface instance.
constexpr bool operator()(InterfaceId< IFACE1, major1, minor1 >, InterfaceId< IFACE2, major2, minor2 >) const
Definition: IInterface.h:227
void * operator()(const InterfaceID &tid, P *ptr) const
Definition: IInterface.h:172
static const InterfaceID & interfaceID()
Definition: IInterface.h:206
constexpr unsigned long id() const
get the interface identifier
Definition: IInterface.h:47
string s
Definition: gaudirun.py:312
constexpr bool operator==(const InterfaceID &iid) const
compare operator
Definition: IInterface.h:63
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
Gaudi::interface_list< iid > ext_iids
Extra interfaces.
Definition: IInterface.h:250
std::vector< std::string > getInterfaceNames(Gaudi::interface_list< Is... >)
Definition: IInterface.h:180
constexpr void * void_cast(const I *i)
Definition: IInterface.h:154
constexpr unsigned long majorVersion() const
get the major version of the interface
Definition: IInterface.h:49
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
constexpr bool fullMatch(const InterfaceID &iid) const
check full compatibility.
Definition: IInterface.h:59
InterfaceID(const char *name, unsigned long major, unsigned long minor=0)
constructor from components
Definition: IInterface.h:40
void * iid_cast(const InterfaceID &tid, Gaudi::interface_list< Is... >, P *ptr)
Definition: IInterface.h:185
#define GAUDI_API
Definition: Kernel.h:71
STL class.
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:253
typename Gaudi::interface_list_append< typename interface_type::ext_iids, InterfaceId >::type iids
List of interfaces.
Definition: IInterface.h:198
Helper functions to set/get the application return code.
Definition: __init__.py:1
unsigned long code_t
type of StatusCode value
Definition: StatusCode.h:52
Gaudi::InterfaceId< IInterface, 0, 0 > iid
Interface ID.
Definition: IInterface.h:247
static const std::type_info & TypeInfo()
Definition: IInterface.h:204