The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
ToolHandle.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
15#include <GaudiKernel/IBinder.h>
20#include <cassert>
21#include <concepts>
22#include <ostream>
23#include <string>
24#include <tuple>
25#include <type_traits>
26#include <utility>
27#include <vector>
28
29class IInterface;
30class IToolSvc;
31namespace Gaudi {
32 class Algorithm;
33}
34class AlgTool;
35class Service;
38
41
42protected:
43 ToolHandleInfo( const IInterface* parent = nullptr, bool createIf = true )
45
46public:
47 virtual ~ToolHandleInfo() = default;
48
49 bool isPublic() const noexcept { return !m_parent; }
50
51 bool createIf() const noexcept { return m_createIf; }
52
53 const IInterface* parent() const noexcept { return m_parent; }
54
55 //
56 // Some helper functions
57 //
58
59 static std::string toolComponentType( const IInterface* parent ) { return parent ? "PrivateTool" : "PublicTool"; }
60
61 static std::string toolParentName( const IInterface* parent ) {
62 auto* pNamed = ( parent ? dynamic_cast<const INamedInterface*>( parent ) : nullptr );
63 return ( !parent ? "ToolSvc" : ( pNamed ? pNamed->name() : "" ) );
64 }
65
66protected:
67 const IInterface* m_parent = nullptr;
68 bool m_createIf{ true };
69};
70
79
80protected:
81 BaseToolHandle( const IInterface* parent = nullptr, bool createIf = true ) : ToolHandleInfo( parent, createIf ) {}
82
83 virtual StatusCode i_retrieve( IAlgTool*& ) const = 0;
84
85public:
86 StatusCode retrieve( IAlgTool*& tool ) const { return i_retrieve( tool ); }
87
88 virtual StatusCode retrieve() const = 0;
89 virtual StatusCode retrieve( DisableTool sd ) = 0;
90 virtual StatusCode retrieve( EnableTool sd ) = 0;
91
92 virtual StatusCode release() const = 0;
93
94 const IAlgTool* get() const { return getAsIAlgTool(); }
95
96 IAlgTool* get() { return getAsIAlgTool(); }
97
98 virtual std::string typeAndName() const = 0;
99
101 bool isEnabled() const {
102 // the handle is considered enabled if the type/name is valid and the
103 // enabled flag was set to true, or it was already retrieved
104 return ( m_enabled && !typeAndName().empty() ) || get();
105 }
106
107 void enable() { m_enabled = true; }
108
109 void disable() { m_enabled = false; }
110
111 bool setEnabled( bool flag ) { return std::exchange( m_enabled, flag ); }
112
113protected:
114 virtual const IAlgTool* getAsIAlgTool() const = 0;
115
116 virtual IAlgTool* getAsIAlgTool() = 0;
117
118 bool m_enabled = true;
119};
120
131template <class T>
132class ToolHandle : public BaseToolHandle, public GaudiHandle<T> {
133
134 friend class Gaudi::Algorithm;
135 friend class AlgTool;
136 friend class Service;
137
138 template <typename... Args, std::size_t... Is>
139 ToolHandle( std::tuple<Args...>&& args, std::index_sequence<Is...> )
140 : ToolHandle( std::get<Is>( std::move( args ) )... ) {}
141
142public:
146 ToolHandle( const IInterface* parent = nullptr, bool createIf = true )
149 , m_pToolSvc( "ToolSvc", GaudiHandleBase::parentName() ) {}
150
152 template <typename CT = T, typename NCT = std::remove_const_t<T>>
153 requires( std::is_const_v<CT> && !std::is_same_v<CT, NCT> )
155 : BaseToolHandle( other.parent(), other.createIf() )
156 , GaudiHandle<CT>( other )
157 , m_pToolSvc( "ToolSvc", GaudiHandleBase::parentName() ) {}
158
159public:
160 //
161 // Constructors etc.
162 //
163
182
183#if defined( TOOLHANDLE_DEPR_WARN )
184// warn about using deprecated explicit ToolHandle construction
185# pragma message( "Untracked ToolHandle: Migrate explicit DataHandle constructor to declareTool Algorithm Property" )
186
187 __attribute__( ( deprecated ) )
188
189#endif
190 ToolHandle( const std::string& toolTypeAndName, const IInterface* parent = nullptr, bool createIf = true )
192 , GaudiHandle<T>( toolTypeAndName, toolComponentType( parent ), toolParentName( parent ) )
193 , m_pToolSvc( "ToolSvc", GaudiHandleBase::parentName() ) {
194 }
195
198 template <std::derived_from<IProperty> OWNER>
199 ToolHandle( OWNER* owner, std::string propName, std::string toolType, std::string doc = "" ) : ToolHandle( owner ) {
200 // convert name and type to a valid type/name string
201 // - if type does not contain '/' use type/type
202 // - otherwise type is already a type/name string
203 if ( !toolType.empty() and toolType.find( '/' ) == std::string::npos ) { toolType += '/' + toolType; }
204 owner->declareTool( *this, std::move( toolType ) ).ignore();
205 auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( propName ), *this, std::move( doc ) );
206 p->template setOwnerType<OWNER>();
207 }
208
209 template <typename... Args>
210 ToolHandle( std::tuple<Args...>&& args ) : ToolHandle( std::move( args ), std::index_sequence_for<Args...>{} ) {}
211
212public:
213 StatusCode initialize( const std::string& toolTypeAndName, const IInterface* parent = nullptr,
214 bool createIf = true ) {
215
216 GaudiHandleBase::setTypeAndName( toolTypeAndName );
219
222
223 return m_pToolSvc.initialize( "ToolSvc", GaudiHandleBase::parentName() );
224 }
225
228 StatusCode retrieve() const override { // not really const, because it updates m_pObject
230 }
231
233 if ( isEnabled() && sd == DisableTool{ false } ) {
235 } else {
236 disable();
237 return StatusCode::SUCCESS;
238 }
239 }
240
242 if ( isEnabled() && sd == EnableTool{ true } ) {
244 } else {
245 disable();
246 return StatusCode::SUCCESS;
247 }
248 }
249
252 StatusCode release() const override { // not really const, because it updates m_pObject
254 }
255
257 StatusCode retrieve( T*& algTool ) const override {
258 IAlgTool* iface = nullptr;
259 if ( i_retrieve( iface ).isFailure() ) { return StatusCode::FAILURE; }
260
261 algTool = dynamic_cast<T*>( iface );
262 if ( !algTool ) {
263 throw GaudiException( "unable to dcast AlgTool " + typeAndName() + " to interface " +
264 System::typeinfoName( typeid( T ) ),
265 typeAndName() + " retrieve", StatusCode::FAILURE );
266 }
267 return StatusCode::SUCCESS;
268 }
269
271 StatusCode release( T* algTool ) const override { return m_pToolSvc->releaseTool( ::details::nonConst( algTool ) ); }
272
273 std::string typeAndName() const override { return GaudiHandleBase::typeAndName(); }
274
275 std::add_const_t<T>* get() const { return GaudiHandle<T>::get(); }
276
277 T* get() { return GaudiHandle<T>::get(); }
278
279 friend std::ostream& operator<<( std::ostream& os, const ToolHandle<T>& handle ) {
280 return os << static_cast<const GaudiHandleInfo&>( handle );
281 }
282
283protected:
284 const IAlgTool* getAsIAlgTool() const override {
285 // const cast to support T being const
286 return GaudiHandle<T>::get();
287 }
288
290 // const cast to support T being const
291 return ::details::nonConst( GaudiHandle<T>::get() );
292 }
293
294 StatusCode i_retrieve( IAlgTool*& algTool ) const override {
295 return m_pToolSvc->retrieve( typeAndName(), IAlgTool::interfaceID(), algTool, ToolHandleInfo::parent(),
297 }
298
299private:
300 //
301 // Private data members
302 //
304};
305
306// explicit specialization for IBinder<IFace>
307template <typename IFace>
308class ToolHandle<Gaudi::Interface::Bind::IBinder<IFace>> : public ToolHandle<IAlgTool> {
309
310 void* m_ptr = nullptr;
311 Gaudi::Interface::Bind::Box<IFace> ( *m_bind )( void const*, const EventContext& ) = nullptr;
312
313public:
316 StatusCode retrieve() const override {
317 // FIXME: why is `retrieve` const????
318 auto self = const_cast<ToolHandle<Gaudi::Interface::Bind::IBinder<IFace>>*>( this );
319
321 const IAlgTool* tool = get();
322 assert( tool != nullptr ); // retrieve was succesfull, so get() better return something valid!
323 return const_cast<IAlgTool*>( tool )
324 ->queryInterface( IFace::interfaceID(), &( self->m_ptr ) )
325 .andThen( [&] {
326 // TODO: what happens to the refCount?
327 self->m_bind = []( const void* ptr, const EventContext& ) {
328 return Gaudi::Interface::Bind::Box<IFace>( static_cast<IFace const*>( ptr ) );
329 };
330 } )
331 .orElse( [&]() {
332 return const_cast<IAlgTool*>( tool )
333 ->queryInterface( Gaudi::Interface::Bind::IBinder<IFace>::interfaceID(), &( self->m_ptr ) )
334 .andThen( [&] {
335 // TODO: what happens to the refCount?
336 self->m_bind = []( const void* ptr, const EventContext& ctx ) {
337 return static_cast<Gaudi::Interface::Bind::IBinder<IFace> const*>( ptr )->bind( ctx );
338 };
339 } );
340 } );
341 } );
342 }
343
344 auto bind( const EventContext& ctx ) const {
345 if ( !m_bind || !m_ptr ) {
346 throw GaudiException{ "request bind on toolhandle which was not (successfully) 'retrieved'", __PRETTY_FUNCTION__,
348 }
349 return ( *m_bind )( m_ptr, ctx );
350 }
351};
352
356template <class T>
357class PublicToolHandle : public ToolHandle<T> {
358public:
359 PublicToolHandle( bool createIf = true ) : ToolHandle<T>( nullptr, createIf ) {}
360 PublicToolHandle( const char* toolTypeAndName, bool createIf = true )
361 : PublicToolHandle{ std::string{ toolTypeAndName }, createIf } {}
362 PublicToolHandle( const std::string& toolTypeAndName, bool createIf = true )
363 : ToolHandle<T>( toolTypeAndName, nullptr, createIf ) {}
364
366 template <typename CT = T, typename NCT = std::remove_const_t<T>>
367 requires( std::is_const_v<CT> && !std::is_same_v<CT, NCT> )
369 : ToolHandle<T>( static_cast<const ToolHandle<NCT>&>( other ) ) {}
370
373 template <std::derived_from<IProperty> OWNER>
374 inline PublicToolHandle( OWNER* owner, std::string propName, std::string toolType, std::string doc = "" )
375 : PublicToolHandle() {
376 // convert name and type to a valid type/name string
377 // - if type does not contain '/' use type/type
378 // - otherwise type is already a type/name string
379 if ( !toolType.empty() and toolType.find( '/' ) == std::string::npos ) { toolType += '/' + toolType; }
380 owner->declareTool( *this, std::move( toolType ) ).ignore();
381 auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( propName ), *this, std::move( doc ) );
382 p->template setOwnerType<OWNER>();
383 }
384};
385
386//-------------------------------------------------------------------------//
387
397
398template <class T>
399class ToolHandleArray : public ToolHandleInfo, public GaudiHandleArray<ToolHandle<T>> {
400public:
401 //
402 // Constructors
403 //
410 ToolHandleArray( const std::vector<std::string>& myTypesAndNames, const IInterface* parent = nullptr,
411 bool createIf = true )
415
424
429 bool push_back( const std::string& toolTypeAndName ) override {
430 ToolHandle<T> handle( toolTypeAndName, ToolHandleInfo::parent(), ToolHandleInfo::createIf() );
432 return true;
433 }
434
436 bool push_back( const ToolHandle<T>& myHandle ) override { return push_back( myHandle.typeAndName() ); }
437
440 template <std::derived_from<IProperty> OWNER>
441 inline ToolHandleArray( OWNER* owner, std::string name, const std::vector<std::string>& typesAndNames = {},
442 std::string doc = "" )
443 : ToolHandleArray( owner ) {
444 owner->addToolsArray( *this );
446 auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( name ), *this, std::move( doc ) );
447 p->template setOwnerType<OWNER>();
448 }
449
450 friend std::ostream& operator<<( std::ostream& os, const ToolHandleArray<T>& handle ) {
451 return os << static_cast<const GaudiHandleInfo&>( handle );
452 }
453};
454
458template <class T>
460public:
461 PublicToolHandleArray( bool createIf = true ) : ToolHandleArray<T>( nullptr, createIf ) {}
462 PublicToolHandleArray( const std::vector<std::string>& typesAndNames, bool createIf = true )
463 : ToolHandleArray<T>( typesAndNames, nullptr, createIf ) {}
464
467 template <std::derived_from<IProperty> OWNER>
468 PublicToolHandleArray( OWNER* owner, std::string name, const std::vector<std::string>& typesAndNames = {},
469 std::string doc = "" )
471 owner->addToolsArray( *this );
473 auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( name ), *this, std::move( doc ) );
474 p->template setOwnerType<OWNER>();
475 }
476};
Gaudi::tagged_bool< class DisableTool_tag > DisableTool
Definition ToolHandle.h:36
Gaudi::tagged_bool< class EnableTool_tag > EnableTool
Definition ToolHandle.h:37
Base class from which all the concrete tool classes should be derived.
Definition AlgTool.h:55
const IAlgTool * get() const
Definition ToolHandle.h:94
virtual std::string typeAndName() const =0
bool isEnabled() const
Helper to check if the ToolHandle should be retrieved.
Definition ToolHandle.h:101
virtual StatusCode retrieve(EnableTool sd)=0
virtual const IAlgTool * getAsIAlgTool() const =0
bool setEnabled(bool flag)
Definition ToolHandle.h:111
virtual StatusCode retrieve(DisableTool sd)=0
BaseToolHandle(const IInterface *parent=nullptr, bool createIf=true)
Definition ToolHandle.h:81
virtual StatusCode i_retrieve(IAlgTool *&) const =0
IAlgTool * get()
Definition ToolHandle.h:96
StatusCode retrieve(IAlgTool *&tool) const
Definition ToolHandle.h:86
virtual StatusCode release() const =0
virtual StatusCode retrieve() const =0
virtual IAlgTool * getAsIAlgTool()=0
This class represents an entry point to all the event specific data.
Base class from which all concrete algorithm classes should be derived.
Definition Algorithm.h:87
Define general base for Gaudi exception.
bool setTypesAndNames(const std::vector< std::string > &myTypesAndNamesList)
Set the array of handles from list of "type/name" strings in <myTypesAndNamesList>.
const std::vector< std::string > typesAndNames() const
Return a vector with "type/name" strings of all handles in the array.
GaudiHandleArray(const std::vector< std::string > &myTypesAndNamesList, std::string myComponentType, std::string myParentName)
GaudiHandleBase(std::string myTypeAndName, std::string myComponentType, std::string myParentName)
Create a handle ('smart pointer') to a gaudi component.
const std::string & typeAndName() const
The full type and name: "type/name".
void setTypeAndName(std::string myTypeAndName)
The component "type/name" string.
StatusCode release() const
Release the component.
T * get()
Return the wrapped pointer, not calling retrieve() if null.
StatusCode retrieve() const
Retrieve the component.
GaudiHandle(std::string myTypeAndName, std::string myComponentType, std::string myParentName)
void setParentName(std::string parent)
The name of the parent.
Definition GaudiHandle.h:84
const std::string & parentName() const
The name of the parent.
Definition GaudiHandle.h:62
void setComponentType(std::string componentType)
The component type.
Definition GaudiHandle.h:81
The interface implemented by the AlgTool base class.
Definition IAlgTool.h:29
Definition of the basic interface.
Definition IInterface.h:225
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition IInterface.h:234
IInterface compliant class extending IInterface with the name() method.
The interface implemented by the IToolSvc base class.
Definition IToolSvc.h:28
Helper class to construct ToolHandle instances for public tools via the auto registering constructor.
Definition ToolHandle.h:459
PublicToolHandleArray(const std::vector< std::string > &typesAndNames, bool createIf=true)
Definition ToolHandle.h:462
PublicToolHandleArray(bool createIf=true)
Definition ToolHandle.h:461
PublicToolHandleArray(OWNER *owner, std::string name, const std::vector< std::string > &typesAndNames={}, std::string doc="")
Autodeclaring constructor with property name, tool type/name and documentation.
Definition ToolHandle.h:468
PublicToolHandle(const PublicToolHandle< NCT > &other)
Copy constructor from a non const T to const T tool handle.
Definition ToolHandle.h:368
PublicToolHandle(const std::string &toolTypeAndName, bool createIf=true)
Definition ToolHandle.h:362
PublicToolHandle(OWNER *owner, std::string propName, std::string toolType, std::string doc="")
Autodeclaring constructor with property propName, tool type/name and documentation.
Definition ToolHandle.h:374
PublicToolHandle(bool createIf=true)
Definition ToolHandle.h:359
PublicToolHandle(const char *toolTypeAndName, bool createIf=true)
Definition ToolHandle.h:360
Handle to be used in lieu of naked pointers to services.
Base class for all services.
Definition Service.h:39
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
StatusCode andThen(F &&f, ARGS &&... args) const
Chain code blocks making the execution conditional a success result.
Definition StatusCode.h:163
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
Array of Handles to be used in lieu of vector of naked pointers to tools.
Definition ToolHandle.h:399
ToolHandleArray(OWNER *owner, std::string name, const std::vector< std::string > &typesAndNames={}, std::string doc="")
Autodeclaring constructor with property name, tool type/name and documentation.
Definition ToolHandle.h:441
ToolHandleArray(const IInterface *parent=nullptr, bool createIf=true)
Constructor which creates and empty list.
Definition ToolHandle.h:420
ToolHandleArray(const std::vector< std::string > &myTypesAndNames, const IInterface *parent=nullptr, bool createIf=true)
Generic constructor.
Definition ToolHandle.h:410
friend std::ostream & operator<<(std::ostream &os, const ToolHandleArray< T > &handle)
Definition ToolHandle.h:450
bool push_back(const std::string &toolTypeAndName) override
Add a handle to the array with given tool type and name.
Definition ToolHandle.h:429
bool push_back(const ToolHandle< T > &myHandle) override
Ensure that for added handles the parent and creatIf are taken from this array.
Definition ToolHandle.h:436
Handle to be used in lieu of naked pointers to tools.
Definition ToolHandle.h:132
auto bind(const EventContext &ctx) const
Definition ToolHandle.h:344
ServiceHandle< IToolSvc > m_pToolSvc
Definition ToolHandle.h:303
friend class AlgTool
Definition ToolHandle.h:135
ToolHandle(const std::string &toolTypeAndName, const IInterface *parent=nullptr, bool createIf=true)
Create a handle ('smart pointer') to a tool.
Definition ToolHandle.h:190
ToolHandle(std::tuple< Args... > &&args)
Definition ToolHandle.h:210
ToolHandle(std::tuple< Args... > &&args, std::index_sequence< Is... >)
Definition ToolHandle.h:139
IAlgTool * getAsIAlgTool() override
Definition ToolHandle.h:289
ToolHandle(const ToolHandle< NCT > &other)
Copy constructor from a non const T to const T tool handle.
Definition ToolHandle.h:154
std::string typeAndName() const override
Definition ToolHandle.h:273
StatusCode release(T *algTool) const override
Do the real release of the AlgTool.
Definition ToolHandle.h:271
StatusCode retrieve(T *&algTool) const override
Do the real retrieval of the AlgTool.
Definition ToolHandle.h:257
ToolHandle(OWNER *owner, std::string propName, std::string toolType, std::string doc="")
Autodeclaring constructor with property propName, tool type/name and documentation.
Definition ToolHandle.h:199
friend class Service
Definition ToolHandle.h:136
friend std::ostream & operator<<(std::ostream &os, const ToolHandle< T > &handle)
Definition ToolHandle.h:279
const IAlgTool * getAsIAlgTool() const override
Definition ToolHandle.h:284
std::add_const_t< T > * get() const
Definition ToolHandle.h:275
Gaudi::Interface::Bind::Box< IFace >(* m_bind)(void const *, const EventContext &)
Definition ToolHandle.h:311
StatusCode initialize(const std::string &toolTypeAndName, const IInterface *parent=nullptr, bool createIf=true)
Definition ToolHandle.h:213
StatusCode retrieve(EnableTool sd) override
Definition ToolHandle.h:241
StatusCode retrieve(DisableTool sd) override
Definition ToolHandle.h:232
StatusCode release() const override
Release the AlgTool.
Definition ToolHandle.h:252
StatusCode i_retrieve(IAlgTool *&algTool) const override
Definition ToolHandle.h:294
ToolHandle(const IInterface *parent=nullptr, bool createIf=true)
Constructor for a tool with default tool type and name.
Definition ToolHandle.h:146
StatusCode retrieve() const override
Retrieve the AlgTool.
Definition ToolHandle.h:228
bool createIf() const noexcept
Definition ToolHandle.h:51
const IInterface * parent() const noexcept
Definition ToolHandle.h:53
ToolHandleInfo(const IInterface *parent=nullptr, bool createIf=true)
Definition ToolHandle.h:43
bool isPublic() const noexcept
Definition ToolHandle.h:49
const IInterface * m_parent
Definition ToolHandle.h:67
static std::string toolParentName(const IInterface *parent)
Definition ToolHandle.h:61
virtual ~ToolHandleInfo()=default
static std::string toolComponentType(const IInterface *parent)
Definition ToolHandle.h:59
STL class.
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:260
std::remove_const_t< T > * nonConst(T *p)
Cast a pointer to a non const type.
Definition GaudiHandle.h:26
STL namespace.
static const InterfaceID & interfaceID()