The Gaudi Framework  master (37c0b60a)
IInterface.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #ifndef GAUDIKERNEL_IINTERFACE_H
12 #define GAUDIKERNEL_IINTERFACE_H
13 
14 // Include files
15 #include <GaudiKernel/Kernel.h>
16 #include <GaudiKernel/StatusCode.h>
17 #include <GaudiKernel/System.h>
18 #include <ostream>
19 #include <type_traits>
20 #include <typeinfo>
21 
23 #define DeclareInterfaceID( iface, major, minor ) \
24  static const InterfaceID& interfaceID() { return iid::interfaceID(); } \
25  using iid = Gaudi::InterfaceId<iface, major, minor>; \
26  using ext_iids = typename iid::iids
27 
39 class GAUDI_API InterfaceID final {
40 public:
41 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
42  [[deprecated( "use InterfaceID(id, major, minor) instead" )]] constexpr InterfaceID( unsigned long lid )
44  : m_id( lid & 0xFFFF ), m_major_ver( ( lid & 0xFF000000 ) >> 24 ), m_minor_ver( ( lid & 0xFF0000 ) >> 16 ) {}
45 #endif
46  constexpr InterfaceID( unsigned long id, unsigned long major, unsigned long minor = 0 )
48  : m_id( id ), m_major_ver( major ), m_minor_ver( minor ) {}
50  InterfaceID( const char* name, unsigned long major, unsigned long minor = 0 )
51  : m_id( hash32( name ) ), m_major_ver( major ), m_minor_ver( minor ) {}
52 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
53  [[deprecated]] constexpr operator unsigned long() const {
55  return ( m_major_ver << 24 ) + ( m_minor_ver << 16 ) + m_id;
56  }
57 #endif
58  constexpr unsigned long id() const { return m_id; }
61  constexpr unsigned long majorVersion() const { return m_major_ver; }
63  constexpr unsigned long minorVersion() const { return m_minor_ver; }
67  constexpr bool versionMatch( const InterfaceID& iid ) const {
68  return ( id() == iid.id() && majorVersion() == iid.majorVersion() && minorVersion() >= iid.minorVersion() );
69  }
71  constexpr bool fullMatch( const InterfaceID& iid ) const {
72  return ( id() == iid.id() && majorVersion() == iid.majorVersion() && minorVersion() == iid.minorVersion() );
73  }
75  constexpr bool operator==( const InterfaceID& iid ) const { return fullMatch( iid ); }
77  static unsigned int hash32( const char* key ) {
78  unsigned int hash = 0;
79  for ( const char* k = key; *k; ++k ) {
80  hash += *k;
81  hash += ( hash << 10 );
82  hash ^= ( hash >> 6 );
83  }
84  hash += ( hash << 3 );
85  hash ^= ( hash >> 11 );
86  hash += ( hash << 15 );
87  return hash;
88  }
89 
90  // #ifdef GAUDI_V20_COMPAT
93  s << "IID_" << id.id();
94  return s;
95  }
96  // #endif
97 
98 private:
99  unsigned long m_id;
100  unsigned long m_major_ver;
101  unsigned long m_minor_ver;
102 };
103 
104 namespace Gaudi {
105 
106  template <typename... I>
107  struct interface_list {};
108 
109  namespace meta {
110  // identity T -> type = T; note that id_<T> is a complete type, even if T is not
111  template <typename T>
112  struct id_ {
113  using type = T;
114  };
115 
116  namespace detail {
117  template <typename... Is>
118  struct inherit_from : Is... {};
119 
120  template <typename List, typename I>
121  struct append1 {};
122 
123  // interpose an id_<I> as id_<I> is a complete type, even if I is not... and we need complete
124  // types to inherit from
125  template <typename... Is, typename I>
126  struct append1<interface_list<Is...>, I>
127  : id_<std::conditional_t<std::is_base_of_v<id_<I>, inherit_from<id_<Is>...>>, interface_list<Is...>,
128  interface_list<Is..., I>>> {};
129 
130  template <typename, typename>
131  struct appendN {};
132 
133  template <typename State>
134  struct appendN<interface_list<>, State> : id_<State> {};
135 
136  template <typename... Is, typename I, typename List>
137  struct appendN<interface_list<I, Is...>, List> : appendN<interface_list<Is...>, typename append1<List, I>::type> {
138  };
139  } // namespace detail
140 
141  template <typename... Is>
143  } // namespace meta
144 
145  // interface_list concatenation
146  template <typename... I>
148 
149  // identity
150  template <typename... I>
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  // append is a special case of concatenation...
164  template <typename... I>
166 
167  template <typename... Is, typename I>
169  : interface_list_cat<interface_list<Is...>, interface_list<I>> {};
170 
171  template <typename... Is>
173  return { Is::name()... };
174  }
175 
176  template <typename... Is, typename P>
177  void* iid_cast( const InterfaceID& tid, Gaudi::interface_list<Is...>, P* ptr ) {
178  const void* target = nullptr;
179  ( ( tid.versionMatch( Is::interfaceID() ) &&
180  ( target = static_cast<typename Is::interface_type const*>( ptr ), true ) ) ||
181  ... );
182  return const_cast<void*>( target );
183  }
184 
188  template <typename INTERFACE, unsigned long majVers, unsigned long minVers>
189  struct InterfaceId final {
191  using interface_type = INTERFACE;
194 
195  static inline std::string name() { return System::typeinfoName( typeid( INTERFACE ) ); }
196  static constexpr unsigned long majorVersion() { return majVers; }
197  static constexpr unsigned long minorVersion() { return minVers; }
198 
199  static inline const std::type_info& TypeInfo() { return typeid( typename iids::type ); }
200 
201  static inline const InterfaceID& interfaceID() {
202  static const InterfaceID s_iid( name().c_str(), majVers, minVers );
203  return s_iid;
204  }
205  };
206 
207  constexpr struct fullMatch_t {
208  template <typename IFACE1, typename IFACE2, unsigned long major1, unsigned long major2, unsigned long minor1,
209  unsigned long minor2>
211  return false;
212  }
213  template <typename IFACE, unsigned long major, unsigned long minor>
215  return true;
216  }
218 
219  constexpr struct majorMatch_t {
220  template <typename IFACE1, typename IFACE2, unsigned long major1, unsigned long major2, unsigned long minor1,
221  unsigned long minor2>
223  return false;
224  }
225  template <typename IFACE, unsigned long major, unsigned long minor1, unsigned long minor2>
227  return true;
228  }
230 } // namespace Gaudi
231 
240 public:
243 
246 
248  static inline const InterfaceID& interfaceID() { return iid::interfaceID(); }
249 
251  virtual void* i_cast( const InterfaceID& ) const
252 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
253  {
254  return nullptr;
255  }
256 #else
257  = 0;
258 #endif
259 
262 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
263  {
264  return {};
265  }
266 #else
267  = 0;
268 #endif
269 
271  virtual unsigned long addRef() = 0;
272 
274  virtual unsigned long release() = 0;
275 
277  virtual unsigned long refCount() const
278 #if defined( GAUDI_V20_COMPAT ) && !defined( G21_NEW_INTERFACES )
279  {
280  IInterface* ths = const_cast<IInterface*>( this );
281  ths->addRef();
282  return ths->release();
283  } // new method, so we need a default implementation for v20 compatibility
284 #else
285  = 0;
286 #endif
287 
289  virtual StatusCode queryInterface( const InterfaceID& ti, void** pp ) = 0;
290 
292  enum class Status : StatusCode::code_t {
294  FAILURE = 0,
296  SUCCESS = 1,
298  NO_INTERFACE,
300  VERSMISMATCH,
302  LAST_ERROR
303  };
304 
306  virtual ~IInterface() = default;
307 };
308 
310 
311 namespace Gaudi {
313  template <typename TARGET>
314  TARGET* Cast( IInterface* i ) {
315  return reinterpret_cast<TARGET*>( i->i_cast( TARGET::interfaceID() ) );
316  }
319  template <typename TARGET>
320  const TARGET* Cast( const IInterface* i ) {
321  return reinterpret_cast<const TARGET*>( i->i_cast( TARGET::interfaceID() ) );
322  }
323 } // namespace Gaudi
324 
335 template <class IFace>
336 bool isValidInterface( IFace* i ) {
337  void* ii = nullptr;
338  return i->queryInterface( IFace::interfaceID(), &ii ).isSuccess();
339 }
340 
351 template <class DEST, class SRC>
352 inline DEST** pp_cast( SRC** ptr ) {
353  return reinterpret_cast<DEST**>( ptr );
354 }
355 
357 #include <GaudiKernel/extends.h>
358 #include <GaudiKernel/implements.h>
359 
360 #endif // GAUDIKERNEL_IINTERFACE_H
GaudiPython.Bindings.FAILURE
FAILURE
Definition: Bindings.py:84
extend_interfaces.h
Gaudi::InterfaceId
Class to handle automatically the versioning of the interfaces when they are inheriting from other in...
Definition: IInterface.h:189
InterfaceID::fullMatch
constexpr bool fullMatch(const InterfaceID &iid) const
check full compatibility.
Definition: IInterface.h:71
std::string
STL class.
Gaudi::fullMatch
constexpr struct Gaudi::fullMatch_t fullMatch
Gaudi::InterfaceId::majorVersion
static constexpr unsigned long majorVersion()
Definition: IInterface.h:196
System.h
gaudirun.s
string s
Definition: gaudirun.py:346
std::vector< std::string >
std::type_info
Gaudi::meta::detail::appendN
Definition: IInterface.h:131
InterfaceID::m_id
unsigned long m_id
Definition: IInterface.h:99
Gaudi::fullMatch_t
Definition: IInterface.h:207
detail
Definition: HistogramSvc.h:46
Gaudi::interface_list_cat
Definition: IInterface.h:147
IInterface::queryInterface
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
Gaudi::InterfaceId::minorVersion
static constexpr unsigned long minorVersion()
Definition: IInterface.h:197
extends.h
StatusCode::code_t
unsigned long code_t
type of StatusCode value
Definition: StatusCode.h:67
Gaudi::interface_list_append
Definition: IInterface.h:165
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:315
GaudiPartProp.tests.id
id
Definition: tests.py:111
StatusCode.h
Gaudi::meta::detail::inherit_from
Definition: IInterface.h:118
InterfaceID::id
constexpr unsigned long id() const
get the interface identifier
Definition: IInterface.h:59
compareOutputFiles.target
target
Definition: compareOutputFiles.py:489
IInterface::Status
Status
Return status.
Definition: IInterface.h:292
Gaudi::StateMachine::State
State
Allowed states for classes implementing the state machine (ApplicationMgr, Algorithm,...
Definition: StateMachine.h:22
IInterface::~IInterface
virtual ~IInterface()=default
Virtual destructor.
Gaudi::InterfaceId::interfaceID
static const InterfaceID & interfaceID()
Definition: IInterface.h:201
StatusCode
Definition: StatusCode.h:65
IInterface::i_cast
virtual void * i_cast(const InterfaceID &) const =0
main cast function
IInterface::interfaceID
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:248
InterfaceID::m_minor_ver
unsigned long m_minor_ver
Definition: IInterface.h:101
std::ostream
STL class.
InterfaceID::majorVersion
constexpr unsigned long majorVersion() const
get the major version of the interface
Definition: IInterface.h:61
Gaudi::InterfaceId::interface_type
INTERFACE interface_type
interface type
Definition: IInterface.h:191
InterfaceID::m_major_ver
unsigned long m_major_ver
Definition: IInterface.h:100
InterfaceID::operator==
constexpr bool operator==(const InterfaceID &iid) const
compare operator
Definition: IInterface.h:75
Gaudi::meta::id_< State >::type
State type
Definition: IInterface.h:113
Gaudi::meta::id_
Definition: IInterface.h:112
Gaudi::fullMatch_t::operator()
constexpr bool operator()(InterfaceId< IFACE, major, minor >, InterfaceId< IFACE, major, minor >) const
Definition: IInterface.h:214
Gaudi::InterfaceId::name
static std::string name()
Definition: IInterface.h:195
GaudiPython.Bindings.SUCCESS
SUCCESS
Definition: Bindings.py:83
Gaudi::interface_list
Definition: IInterface.h:107
Gaudi::majorMatch
constexpr struct Gaudi::majorMatch_t majorMatch
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
pp_cast
DEST ** pp_cast(SRC **ptr)
Small function to be used instead of the construct (void**)&pointer, which produces,...
Definition: IInterface.h:352
InterfaceID::minorVersion
constexpr unsigned long minorVersion() const
get the minor version of the interface
Definition: IInterface.h:63
Gaudi::InterfaceId::TypeInfo
static const std::type_info & TypeInfo()
Definition: IInterface.h:199
gaudirun.type
type
Definition: gaudirun.py:160
Gaudi::majorMatch_t
Definition: IInterface.h:219
Gaudi::fullMatch_t::operator()
constexpr bool operator()(InterfaceId< IFACE1, major1, minor1 >, InterfaceId< IFACE2, major2, minor2 >) const
Definition: IInterface.h:210
STATUSCODE_ENUM_DECL
#define STATUSCODE_ENUM_DECL(ENUM)
Declare an enum to be used as StatusCode value.
Definition: StatusCode.h:286
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
Gaudi::meta::detail::append1
Definition: IInterface.h:121
Gaudi::iid_cast
void * iid_cast(const InterfaceID &tid, Gaudi::interface_list< Is... >, P *ptr)
Definition: IInterface.h:177
Gaudi::getInterfaceNames
std::vector< std::string > getInterfaceNames(Gaudi::interface_list< Is... >)
Definition: IInterface.h:172
Kernel.h
IInterface
Definition: IInterface.h:239
InterfaceID::versionMatch
constexpr bool versionMatch(const InterfaceID &iid) const
check compatibility.
Definition: IInterface.h:67
InterfaceID::hash32
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:77
IInterface::getInterfaceNames
virtual std::vector< std::string > getInterfaceNames() const =0
Returns a vector of strings containing the names of all the implemented interfaces.
isValidInterface
bool isValidInterface(IFace *i)
Templated function that throws an exception if the version if the interface implemented by the object...
Definition: IInterface.h:336
implements.h
Gaudi::InterfaceId::iids
typename Gaudi::interface_list_append< typename interface_type::ext_iids, InterfaceId >::type iids
List of interfaces.
Definition: IInterface.h:193
Gaudi::majorMatch_t::operator()
constexpr bool operator()(InterfaceId< IFACE1, major1, minor1 >, InterfaceId< IFACE2, major2, minor2 >) const
Definition: IInterface.h:222
Gaudi::majorMatch_t::operator()
constexpr bool operator()(InterfaceId< IFACE, major, minor1 >, InterfaceId< IFACE, major, minor2 >) const
Definition: IInterface.h:226
InterfaceID::InterfaceID
InterfaceID(const char *name, unsigned long major, unsigned long minor=0)
constructor from components
Definition: IInterface.h:50
InterfaceID
Definition: IInterface.h:39
IInterface::refCount
virtual unsigned long refCount() const =0
Current reference count.
IInterface::release
virtual unsigned long release()=0
Release Interface instance.
compareOutputFiles.pp
pp
Definition: compareOutputFiles.py:507
InterfaceID::operator<<
friend std::ostream & operator<<(std::ostream &s, const InterfaceID &id)
ostream operator for InterfaceID. Needed by PluginSvc
Definition: IInterface.h:92
ProduceConsume.key
key
Definition: ProduceConsume.py:84
Gaudi::Cast
TARGET * Cast(IInterface *i)
Cast a IInterface pointer to an IInterface specialization (TARGET).
Definition: IInterface.h:314
IInterface::addRef
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
GAUDI_API
#define GAUDI_API
Definition: Kernel.h:81