The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
IInterface.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 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#pragma once
12
13#include <Gaudi/Concepts.h>
14#include <GaudiKernel/Kernel.h>
16#include <GaudiKernel/System.h>
17#include <ostream>
18#include <type_traits>
19#include <typeinfo>
20
22#define DeclareInterfaceID( iface, major, minor ) \
23 static const InterfaceID& interfaceID() { return iid::interfaceID(); } \
24 using iid = Gaudi::InterfaceId<iface, major, minor>; \
25 using ext_iids = typename iid::iids
26
39public:
41 constexpr InterfaceID( unsigned long id, unsigned long major, unsigned long minor = 0 )
42 : m_id( id ), m_major_ver( major ), m_minor_ver( minor ) {}
43
44 InterfaceID( const char* name, unsigned long major, unsigned long minor = 0 )
45 : m_id( hash32( name ) ), m_major_ver( major ), m_minor_ver( minor ) {}
46
47 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 }
58
59 constexpr bool fullMatch( const InterfaceID& iid ) const {
60 return ( id() == iid.id() && majorVersion() == iid.majorVersion() && minorVersion() == iid.minorVersion() );
61 }
62
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
79 friend std::ostream& operator<<( std::ostream& s, const InterfaceID& id ) {
80 s << "IID_" << id.id();
81 return s;
82 }
83
84private:
85 unsigned long m_id;
86 unsigned long m_major_ver;
87 unsigned long m_minor_ver;
88};
89
90namespace Gaudi {
91
92 template <typename... I>
93 struct interface_list {};
94
95 namespace meta {
96 // identity T -> type = T; note that id_<T> is a complete type, even if T is not
97 template <typename T>
98 struct id_ {
99 using type = T;
100 };
101
102 namespace detail {
103 template <typename... Is>
104 struct inherit_from : Is... {};
105
106 template <typename List, typename I>
107 struct append1 {};
108
109 // interpose an id_<I> as id_<I> is a complete type, even if I is not... and we need complete
110 // types to inherit from
111 template <typename... Is, typename I>
112 struct append1<interface_list<Is...>, I>
113 : id_<std::conditional_t<std::is_base_of_v<id_<I>, inherit_from<id_<Is>...>>, interface_list<Is...>,
114 interface_list<Is..., I>>> {};
115
116 template <typename, typename>
117 struct appendN {};
118
119 template <typename State>
120 struct appendN<interface_list<>, State> : id_<State> {};
121
122 template <typename... Is, typename I, typename List>
123 struct appendN<interface_list<I, Is...>, List> : appendN<interface_list<Is...>, typename append1<List, I>::type> {
124 };
125 } // namespace detail
126
127 template <typename... Is>
129 } // namespace meta
130
131 // interface_list concatenation
132 template <typename... I>
134
135 // identity
136 template <typename... I>
138
139 // binary op
140 template <typename... I1, typename... I2>
142 };
143
144 // induction of binary op
145 template <typename... I1, typename... I2, typename... Others>
146 struct interface_list_cat<interface_list<I1...>, interface_list<I2...>, Others...>
147 : interface_list_cat<interface_list<I1..., I2...>, Others...> {};
148
149 // append is a special case of concatenation...
150 template <typename... I>
152
153 template <typename... Is, typename I>
155 : interface_list_cat<interface_list<Is...>, interface_list<I>> {};
156
157 template <typename... Is>
159 return { Is::name()... };
160 }
161
162 template <typename... Is, typename P>
163 void* iid_cast( const InterfaceID& tid, Gaudi::interface_list<Is...>, P* ptr ) {
164 const void* target = nullptr;
165 ( ( tid.versionMatch( Is::interfaceID() ) &&
166 ( target = static_cast<typename Is::interface_type const*>( ptr ), true ) ) ||
167 ... );
168 return const_cast<void*>( target );
169 }
170
174 template <typename INTERFACE, unsigned long majVers, unsigned long minVers>
175 struct InterfaceId final {
177 using interface_type = INTERFACE;
180
181 static inline std::string name() { return System::typeinfoName( typeid( INTERFACE ) ); }
182 static constexpr unsigned long majorVersion() { return majVers; }
183 static constexpr unsigned long minorVersion() { return minVers; }
184
185 static inline const std::type_info& TypeInfo() { return typeid( typename iids::type ); }
186
187 static inline const InterfaceID& interfaceID() {
188 static const InterfaceID s_iid( name().c_str(), majVers, minVers );
189 return s_iid;
190 }
191 };
192
193 constexpr struct fullMatch_t {
194 template <typename IFACE1, typename IFACE2, unsigned long major1, unsigned long major2, unsigned long minor1,
195 unsigned long minor2>
199 template <typename IFACE, unsigned long major, unsigned long minor>
201 return true;
202 }
203 } fullMatch{};
204
205 constexpr struct majorMatch_t {
206 template <typename IFACE1, typename IFACE2, unsigned long major1, unsigned long major2, unsigned long minor1,
207 unsigned long minor2>
211 template <typename IFACE, unsigned long major, unsigned long minor1, unsigned long minor2>
213 return true;
214 }
215 } majorMatch{};
216} // namespace Gaudi
217
226public:
229
232
234 static inline const InterfaceID& interfaceID() { return iid::interfaceID(); }
235
236 template <Gaudi::IsInterface TARGET>
237 TARGET* cast() {
238 if ( auto output = i_cast( TARGET::interfaceID() ) ) { return reinterpret_cast<TARGET*>( output ); }
239 if constexpr ( Gaudi::IsInterface<TARGET> ) {
240 void* tgt = nullptr;
241 queryInterface( TARGET::interfaceID(), &tgt ).ignore();
242 if ( tgt ) {
243 // queryInterface bumps the reference count of the target object, but we should not
244 auto* target = reinterpret_cast<TARGET*>( tgt );
245 // we cannot use release() because we may be called with an object with initial reference count of 0 and that
246 // would delete the object
247 static_cast<const IInterface*>( target )->decRef();
248 return target;
249 }
250 }
251 return nullptr;
252 }
253
254 template <Gaudi::IsInterface TARGET>
255 TARGET const* cast() const {
256 if ( auto output = i_cast( TARGET::interfaceID() ) ) { return reinterpret_cast<TARGET const*>( output ); }
257 if constexpr ( Gaudi::IsInterface<TARGET> ) {
258 void* tgt = nullptr;
259 const_cast<IInterface*>( this )->queryInterface( TARGET::interfaceID(), &tgt ).ignore();
260 if ( tgt ) {
261 // queryInterface bumps the reference count of the target object, but we should not
262 auto* target = reinterpret_cast<const TARGET*>( tgt );
263 // we cannot use release() because we may be called with an object with initial reference count of 0 and that
264 // would delete the object
265 static_cast<const IInterface*>( target )->decRef();
266 return target;
267 }
268 }
269 return nullptr;
270 }
271
272 template <typename TARGET>
273 requires( !Gaudi::IsInterface<TARGET> )
274 TARGET* cast() {
275 return dynamic_cast<TARGET*>( this );
276 }
277
278 template <typename TARGET>
279 requires( !Gaudi::IsInterface<TARGET> )
280 TARGET const* cast() const {
281 return dynamic_cast<TARGET const*>( this );
282 }
283
285 virtual std::vector<std::string> getInterfaceNames() const = 0;
286
288 virtual unsigned long addRef() const = 0;
289
291 virtual unsigned long release() const = 0;
292
294 virtual unsigned long refCount() const = 0;
295
297 virtual StatusCode queryInterface( const InterfaceID& ti, void** pp ) = 0;
298
312
314 virtual ~IInterface() = default;
315
316 // Note: these cannot be protected methods because they may be needed by specializations
317 // that delegate to other instances (like queryInterface does).
318 virtual void const* i_cast( const InterfaceID& ) const = 0;
319
320 void* i_cast( const InterfaceID& iid ) {
321 return const_cast<void*>( const_cast<const IInterface*>( this )->i_cast( iid ) );
322 }
323
324protected:
326 virtual unsigned long decRef() const = 0;
327};
328
330
331namespace Gaudi {
332 template <typename TARGET>
333 TARGET* Cast( IInterface* i ) {
334 return i ? i->cast<TARGET>() : nullptr;
335 }
336
337 template <typename TARGET>
338 const TARGET* Cast( const IInterface* i ) {
339 return i ? i->cast<const TARGET>() : nullptr;
340 }
341} // namespace Gaudi
342
353template <class IFace>
354bool isValidInterface( IFace* i ) {
355 void* ii = nullptr;
356 return i->queryInterface( IFace::interfaceID(), &ii ).isSuccess();
357}
358
369template <class DEST, class SRC>
370inline DEST** pp_cast( SRC** ptr ) {
371 return reinterpret_cast<DEST**>( ptr );
372}
373
375#include <GaudiKernel/extends.h>
DEST ** pp_cast(SRC **ptr)
Small function to be used instead of the construct (void**)&pointer, which produces,...
Definition IInterface.h:370
bool isValidInterface(IFace *i)
Templated function that throws an exception if the version if the interface implemented by the object...
Definition IInterface.h:354
#define GAUDI_API
Definition Kernel.h:49
#define STATUSCODE_ENUM_DECL(ENUM)
Declare an enum to be used as StatusCode value.
Definition StatusCode.h:286
Definition of the basic interface.
Definition IInterface.h:225
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
TARGET const * cast() const
Definition IInterface.h:255
TARGET * cast()
Definition IInterface.h:237
TARGET const * cast() const
Definition IInterface.h:280
virtual void const * i_cast(const InterfaceID &) const =0
TARGET * cast()
Definition IInterface.h:274
virtual unsigned long refCount() const =0
Current reference count.
virtual std::vector< std::string > getInterfaceNames() const =0
Returns a vector of strings containing the names of all the implemented interfaces.
Status
Return status.
Definition IInterface.h:300
@ LAST_ERROR
Last error.
Definition IInterface.h:310
@ VERSMISMATCH
Requested interface version is incompatible.
Definition IInterface.h:308
@ NO_INTERFACE
Requested interface is not available.
Definition IInterface.h:306
@ SUCCESS
Normal successful completion.
Definition IInterface.h:304
Gaudi::interface_list< iid > ext_iids
Extra interfaces.
Definition IInterface.h:231
void * i_cast(const InterfaceID &iid)
Definition IInterface.h:320
Gaudi::InterfaceId< IInterface, 0, 0 > iid
Interface ID.
Definition IInterface.h:228
virtual unsigned long decRef() const =0
Decrement reference count and return the new reference count.
virtual unsigned long addRef() const =0
Increment the reference count of Interface instance.
virtual ~IInterface()=default
Virtual destructor.
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition IInterface.h:234
virtual unsigned long release() const =0
Release Interface instance.
Interface ID class.
Definition IInterface.h:38
constexpr bool versionMatch(const InterfaceID &iid) const
check compatibility.
Definition IInterface.h:55
unsigned long m_minor_ver
Definition IInterface.h:87
constexpr bool operator==(const InterfaceID &iid) const
compare operator
Definition IInterface.h:63
friend std::ostream & operator<<(std::ostream &s, const InterfaceID &id)
ostream operator for InterfaceID. Needed by PluginSvc
Definition IInterface.h:79
constexpr unsigned long majorVersion() const
get the major version of the interface
Definition IInterface.h:49
constexpr InterfaceID(unsigned long id, unsigned long major, unsigned long minor=0)
constructor from components
Definition IInterface.h:41
constexpr unsigned long id() const
get the interface identifier
Definition IInterface.h:47
InterfaceID(const char *name, unsigned long major, unsigned long minor=0)
constructor from components
Definition IInterface.h:44
unsigned long m_major_ver
Definition IInterface.h:86
constexpr bool fullMatch(const InterfaceID &iid) const
check full compatibility.
Definition IInterface.h:59
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
constexpr unsigned long minorVersion() const
get the minor version of the interface
Definition IInterface.h:51
unsigned long m_id
Definition IInterface.h:85
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
unsigned long code_t
type of StatusCode value
Definition StatusCode.h:66
detail::appendN< interface_list< Is... >, interface_list<> > unique_interface_list
Definition IInterface.h:128
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
void * iid_cast(const InterfaceID &tid, Gaudi::interface_list< Is... >, P *ptr)
Definition IInterface.h:163
std::vector< std::string > getInterfaceNames(Gaudi::interface_list< Is... >)
Definition IInterface.h:158
TARGET * Cast(IInterface *i)
Definition IInterface.h:333
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:260
Class to handle automatically the versioning of the interfaces when they are inheriting from other in...
Definition IInterface.h:175
static const InterfaceID & interfaceID()
Definition IInterface.h:187
static constexpr unsigned long minorVersion()
Definition IInterface.h:183
typename Gaudi::interface_list_append< typename interface_type::ext_iids, InterfaceId >::type iids
List of interfaces.
Definition IInterface.h:179
static constexpr unsigned long majorVersion()
Definition IInterface.h:182
INTERFACE interface_type
interface type
Definition IInterface.h:177
static std::string name()
Definition IInterface.h:181
static const std::type_info & TypeInfo()
Definition IInterface.h:185
constexpr bool operator()(InterfaceId< IFACE, major, minor >, InterfaceId< IFACE, major, minor >) const
Definition IInterface.h:200
constexpr bool operator()(InterfaceId< IFACE1, major1, minor1 >, InterfaceId< IFACE2, major2, minor2 >) const
Definition IInterface.h:196
constexpr bool operator()(InterfaceId< IFACE1, major1, minor1 >, InterfaceId< IFACE2, major2, minor2 >) const
Definition IInterface.h:208
constexpr bool operator()(InterfaceId< IFACE, major, minor1 >, InterfaceId< IFACE, major, minor2 >) const
Definition IInterface.h:212