Warning, file /include/GaudiKernel/ToolHandle.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef GAUDIKERNEL_TOOLHANDLE_H
0012 #define GAUDIKERNEL_TOOLHANDLE_H
0013
0014
0015 #include <GaudiKernel/GaudiHandle.h>
0016 #include <GaudiKernel/IAlgTool.h>
0017 #include <GaudiKernel/IBinder.h>
0018 #include <GaudiKernel/INamedInterface.h>
0019 #include <GaudiKernel/IToolSvc.h>
0020 #include <GaudiKernel/ServiceHandle.h>
0021 #include <GaudiKernel/TaggedBool.h>
0022
0023 #include <stdexcept>
0024 #include <string>
0025 #include <type_traits>
0026 #include <vector>
0027
0028
0029 class IInterface;
0030 class IToolSvc;
0031
0032 namespace Gaudi {
0033 class Algorithm;
0034 }
0035 class AlgTool;
0036 class Service;
0037
0038 using DisableTool = Gaudi::tagged_bool<class DisableTool_tag>;
0039 using EnableTool = Gaudi::tagged_bool<class EnableTool_tag>;
0040
0041
0042 class ToolHandleInfo {
0043
0044 protected:
0045 ToolHandleInfo( const IInterface* parent = nullptr, bool createIf = true )
0046 : m_parent( parent ), m_createIf( createIf ) {}
0047
0048 public:
0049 virtual ~ToolHandleInfo() = default;
0050
0051 bool isPublic() const noexcept { return !m_parent; }
0052
0053 bool createIf() const noexcept { return m_createIf; }
0054
0055 const IInterface* parent() const noexcept { return m_parent; }
0056
0057
0058
0059
0060
0061 static std::string toolComponentType( const IInterface* parent ) { return parent ? "PrivateTool" : "PublicTool"; }
0062
0063 static std::string toolParentName( const IInterface* parent ) {
0064 auto* pNamed = ( parent ? dynamic_cast<const INamedInterface*>( parent ) : nullptr );
0065 return ( !parent ? "ToolSvc" : ( pNamed ? pNamed->name() : "" ) );
0066 }
0067
0068 protected:
0069 const IInterface* m_parent = nullptr;
0070 bool m_createIf{ true };
0071 };
0072
0073
0074
0075
0076
0077
0078
0079
0080 class BaseToolHandle : public ToolHandleInfo {
0081
0082 protected:
0083 BaseToolHandle( const IInterface* parent = nullptr, bool createIf = true ) : ToolHandleInfo( parent, createIf ) {}
0084
0085 virtual StatusCode i_retrieve( IAlgTool*& ) const = 0;
0086
0087 public:
0088 StatusCode retrieve( IAlgTool*& tool ) const { return i_retrieve( tool ); }
0089
0090 virtual StatusCode retrieve() const = 0;
0091 virtual StatusCode retrieve( DisableTool sd ) = 0;
0092 virtual StatusCode retrieve( EnableTool sd ) = 0;
0093
0094 const IAlgTool* get() const { return getAsIAlgTool(); }
0095
0096 IAlgTool* get() { return getAsIAlgTool(); }
0097
0098 virtual std::string typeAndName() const = 0;
0099
0100
0101 bool isEnabled() const {
0102
0103
0104 return ( m_enabled && !typeAndName().empty() ) || get();
0105 }
0106
0107 void enable() { m_enabled = true; }
0108
0109 void disable() { m_enabled = false; }
0110
0111 bool setEnabled( bool flag ) { return std::exchange( m_enabled, flag ); }
0112
0113 protected:
0114 virtual const IAlgTool* getAsIAlgTool() const = 0;
0115
0116 virtual IAlgTool* getAsIAlgTool() = 0;
0117
0118 bool m_enabled = true;
0119 };
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 template <class T>
0132 class ToolHandle : public BaseToolHandle, public GaudiHandle<T> {
0133
0134 friend class Gaudi::Algorithm;
0135 friend class AlgTool;
0136 friend class Service;
0137
0138 template <typename... Args, std::size_t... Is>
0139 ToolHandle( std::tuple<Args...>&& args, std::index_sequence<Is...> )
0140 : ToolHandle( std::get<Is>( std::move( args ) )... ) {}
0141
0142 public:
0143
0144
0145
0146 ToolHandle( const IInterface* parent = nullptr, bool createIf = true )
0147 : BaseToolHandle( parent, createIf )
0148 , GaudiHandle<T>( "", toolComponentType( parent ), toolParentName( parent ) )
0149 , m_pToolSvc( "ToolSvc", GaudiHandleBase::parentName() ) {}
0150
0151
0152 template <typename CT = T, typename NCT = std::remove_const_t<T>>
0153 requires( std::is_const_v<CT> && !std::is_same_v<CT, NCT> )
0154 ToolHandle( const ToolHandle<NCT>& other )
0155 : BaseToolHandle( other.parent(), other.createIf() )
0156 , GaudiHandle<CT>( other )
0157 , m_pToolSvc( "ToolSvc", GaudiHandleBase::parentName() ) {}
0158
0159 public:
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 #if defined( TOOLHANDLE_DEPR_WARN )
0184
0185 # pragma message( "Untracked ToolHandle: Migrate explicit DataHandle constructor to declareTool Algorithm Property" )
0186
0187 __attribute__( ( deprecated ) )
0188
0189 #endif
0190 ToolHandle( const std::string& toolTypeAndName, const IInterface* parent = nullptr, bool createIf = true )
0191 : BaseToolHandle( parent, createIf )
0192 , GaudiHandle<T>( toolTypeAndName, toolComponentType( parent ), toolParentName( parent ) )
0193 , m_pToolSvc( "ToolSvc", GaudiHandleBase::parentName() ) {
0194 }
0195
0196
0197
0198 template <std::derived_from<IProperty> OWNER>
0199 ToolHandle( OWNER* owner, std::string propName, std::string toolType, std::string doc = "" ) : ToolHandle( owner ) {
0200
0201
0202
0203 if ( !toolType.empty() and toolType.find( '/' ) == std::string::npos ) { toolType += '/' + toolType; }
0204 owner->declareTool( *this, std::move( toolType ) ).ignore();
0205 auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( propName ), *this, std::move( doc ) );
0206 p->template setOwnerType<OWNER>();
0207 }
0208
0209 template <typename... Args>
0210 ToolHandle( std::tuple<Args...>&& args ) : ToolHandle( std::move( args ), std::index_sequence_for<Args...>{} ) {}
0211
0212 public:
0213 StatusCode initialize( const std::string& toolTypeAndName, const IInterface* parent = nullptr,
0214 bool createIf = true ) {
0215
0216 GaudiHandleBase::setTypeAndName( toolTypeAndName );
0217 GaudiHandleBase::setComponentType( toolComponentType( parent ) );
0218 GaudiHandleBase::setParentName( toolParentName( parent ) );
0219
0220 m_parent = parent;
0221 m_createIf = createIf;
0222
0223 return m_pToolSvc.initialize( "ToolSvc", GaudiHandleBase::parentName() );
0224 }
0225
0226
0227
0228 StatusCode retrieve() const override {
0229 return GaudiHandle<T>::retrieve();
0230 }
0231
0232 StatusCode retrieve( DisableTool sd ) override {
0233 if ( isEnabled() && sd == DisableTool{ false } ) {
0234 return GaudiHandle<T>::retrieve();
0235 } else {
0236 disable();
0237 return StatusCode::SUCCESS;
0238 }
0239 }
0240
0241 StatusCode retrieve( EnableTool sd ) override {
0242 if ( isEnabled() && sd == EnableTool{ true } ) {
0243 return GaudiHandle<T>::retrieve();
0244 } else {
0245 disable();
0246 return StatusCode::SUCCESS;
0247 }
0248 }
0249
0250
0251
0252 StatusCode release() const {
0253 return GaudiHandle<T>::release();
0254 }
0255
0256
0257 StatusCode retrieve( T*& algTool ) const override {
0258 IAlgTool* iface = nullptr;
0259 if ( i_retrieve( iface ).isFailure() ) { return StatusCode::FAILURE; }
0260
0261 algTool = dynamic_cast<T*>( iface );
0262 if ( !algTool ) {
0263 throw GaudiException( "unable to dcast AlgTool " + typeAndName() + " to interface " +
0264 System::typeinfoName( typeid( T ) ),
0265 typeAndName() + " retrieve", StatusCode::FAILURE );
0266 }
0267 return StatusCode::SUCCESS;
0268 }
0269
0270
0271 StatusCode release( T* algTool ) const override { return m_pToolSvc->releaseTool( ::details::nonConst( algTool ) ); }
0272
0273 std::string typeAndName() const override { return GaudiHandleBase::typeAndName(); }
0274
0275 std::add_const_t<T>* get() const { return GaudiHandle<T>::get(); }
0276
0277 T* get() { return GaudiHandle<T>::get(); }
0278
0279 friend std::ostream& operator<<( std::ostream& os, const ToolHandle<T>& handle ) {
0280 return os << static_cast<const GaudiHandleInfo&>( handle );
0281 }
0282
0283 protected:
0284 const IAlgTool* getAsIAlgTool() const override {
0285
0286 return GaudiHandle<T>::get();
0287 }
0288
0289 IAlgTool* getAsIAlgTool() override {
0290
0291 return ::details::nonConst( GaudiHandle<T>::get() );
0292 }
0293
0294 StatusCode i_retrieve( IAlgTool*& algTool ) const override {
0295 return m_pToolSvc->retrieve( typeAndName(), IAlgTool::interfaceID(), algTool, ToolHandleInfo::parent(),
0296 ToolHandleInfo::createIf() );
0297 }
0298
0299 private:
0300
0301
0302
0303 mutable ServiceHandle<IToolSvc> m_pToolSvc;
0304 };
0305
0306
0307 template <typename IFace>
0308 class ToolHandle<Gaudi::Interface::Bind::IBinder<IFace>> : public ToolHandle<IAlgTool> {
0309
0310 void* m_ptr = nullptr;
0311 Gaudi::Interface::Bind::Box<IFace> ( *m_bind )( void const*, const EventContext& ) = nullptr;
0312
0313 public:
0314 using ToolHandle<IAlgTool>::ToolHandle;
0315 using ToolHandle<IAlgTool>::retrieve;
0316 StatusCode retrieve() const override {
0317
0318 auto self = const_cast<ToolHandle<Gaudi::Interface::Bind::IBinder<IFace>>*>( this );
0319
0320 return ToolHandle<IAlgTool>::retrieve().andThen( [&] {
0321 const IAlgTool* tool = get();
0322 assert( tool != nullptr );
0323 return const_cast<IAlgTool*>( tool )
0324 ->queryInterface( IFace::interfaceID(), &( self->m_ptr ) )
0325 .andThen( [&] {
0326
0327 self->m_bind = []( const void* ptr, const EventContext& ) {
0328 return Gaudi::Interface::Bind::Box<IFace>( static_cast<IFace const*>( ptr ) );
0329 };
0330 } )
0331 .orElse( [&]() {
0332 return const_cast<IAlgTool*>( tool )
0333 ->queryInterface( Gaudi::Interface::Bind::IBinder<IFace>::interfaceID(), &( self->m_ptr ) )
0334 .andThen( [&] {
0335
0336 self->m_bind = []( const void* ptr, const EventContext& ctx ) {
0337 return static_cast<Gaudi::Interface::Bind::IBinder<IFace> const*>( ptr )->bind( ctx );
0338 };
0339 } );
0340 } );
0341 } );
0342 }
0343
0344 auto bind( const EventContext& ctx ) const {
0345 if ( !m_bind || !m_ptr ) {
0346 throw GaudiException{ "request bind on toolhandle which was not (successfully) 'retrieved'", __PRETTY_FUNCTION__,
0347 StatusCode::FAILURE };
0348 }
0349 return ( *m_bind )( m_ptr, ctx );
0350 }
0351 };
0352
0353
0354
0355
0356 template <class T>
0357 class PublicToolHandle : public ToolHandle<T> {
0358 public:
0359 PublicToolHandle( bool createIf = true ) : ToolHandle<T>( nullptr, createIf ) {}
0360 PublicToolHandle( const char* toolTypeAndName, bool createIf = true )
0361 : PublicToolHandle{ std::string{ toolTypeAndName }, createIf } {}
0362 PublicToolHandle( const std::string& toolTypeAndName, bool createIf = true )
0363 : ToolHandle<T>( toolTypeAndName, nullptr, createIf ) {}
0364
0365
0366 template <typename CT = T, typename NCT = std::remove_const_t<T>>
0367 requires( std::is_const_v<CT> && !std::is_same_v<CT, NCT> )
0368 PublicToolHandle( const PublicToolHandle<NCT>& other )
0369 : ToolHandle<T>( static_cast<const ToolHandle<NCT>&>( other ) ) {}
0370
0371
0372
0373 template <std::derived_from<IProperty> OWNER>
0374 inline PublicToolHandle( OWNER* owner, std::string propName, std::string toolType, std::string doc = "" )
0375 : PublicToolHandle() {
0376
0377
0378
0379 if ( !toolType.empty() and toolType.find( '/' ) == std::string::npos ) { toolType += '/' + toolType; }
0380 owner->declareTool( *this, std::move( toolType ) ).ignore();
0381 auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( propName ), *this, std::move( doc ) );
0382 p->template setOwnerType<OWNER>();
0383 }
0384 };
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 template <class T>
0399 class ToolHandleArray : public ToolHandleInfo, public GaudiHandleArray<ToolHandle<T>> {
0400 public:
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410 ToolHandleArray( const std::vector<std::string>& myTypesAndNames, const IInterface* parent = nullptr,
0411 bool createIf = true )
0412 : ToolHandleInfo( parent, createIf )
0413 , GaudiHandleArray<ToolHandle<T>>( myTypesAndNames, ToolHandleInfo::toolComponentType( parent ),
0414 ToolHandleInfo::toolParentName( parent ) ) {}
0415
0416
0417
0418
0419
0420 ToolHandleArray( const IInterface* parent = nullptr, bool createIf = true )
0421 : ToolHandleInfo( parent, createIf )
0422 , GaudiHandleArray<ToolHandle<T>>( ToolHandleInfo::toolComponentType( parent ),
0423 ToolHandleInfo::toolParentName( parent ) ) {}
0424
0425
0426
0427
0428
0429 bool push_back( const std::string& toolTypeAndName ) override {
0430 ToolHandle<T> handle( toolTypeAndName, ToolHandleInfo::parent(), ToolHandleInfo::createIf() );
0431 GaudiHandleArray<ToolHandle<T>>::push_back( handle );
0432 return true;
0433 }
0434
0435
0436 bool push_back( const ToolHandle<T>& myHandle ) override { return push_back( myHandle.typeAndName() ); }
0437
0438
0439
0440 template <std::derived_from<IProperty> OWNER>
0441 inline ToolHandleArray( OWNER* owner, std::string name, const std::vector<std::string>& typesAndNames = {},
0442 std::string doc = "" )
0443 : ToolHandleArray( owner ) {
0444 owner->addToolsArray( *this );
0445 this->setTypesAndNames( typesAndNames );
0446 auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( name ), *this, std::move( doc ) );
0447 p->template setOwnerType<OWNER>();
0448 }
0449
0450 friend std::ostream& operator<<( std::ostream& os, const ToolHandleArray<T>& handle ) {
0451 return os << static_cast<const GaudiHandleInfo&>( handle );
0452 }
0453 };
0454
0455
0456
0457
0458 template <class T>
0459 class PublicToolHandleArray : public ToolHandleArray<T> {
0460 public:
0461 PublicToolHandleArray( bool createIf = true ) : ToolHandleArray<T>( nullptr, createIf ) {}
0462 PublicToolHandleArray( const std::vector<std::string>& typesAndNames, bool createIf = true )
0463 : ToolHandleArray<T>( typesAndNames, nullptr, createIf ) {}
0464
0465
0466
0467 template <std::derived_from<IProperty> OWNER>
0468 PublicToolHandleArray( OWNER* owner, std::string name, const std::vector<std::string>& typesAndNames = {},
0469 std::string doc = "" )
0470 : PublicToolHandleArray() {
0471 owner->addToolsArray( *this );
0472 this->setTypesAndNames( typesAndNames );
0473 auto p = owner->OWNER::PropertyHolderImpl::declareProperty( std::move( name ), *this, std::move( doc ) );
0474 p->template setOwnerType<OWNER>();
0475 }
0476 };
0477
0478 #endif