The Gaudi Framework  master (29688f1e)
Loading...
Searching...
No Matches
GaudiHandle.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 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/Property.h>
16#include <GaudiKernel/System.h>
17#include <algorithm>
18#include <iostream>
19#include <string>
20#include <type_traits>
21#include <vector>
22
23namespace details {
25 template <class T>
26 std::remove_const_t<T>* nonConst( T* p ) {
27 return const_cast<std::remove_const_t<T>*>( p );
28 }
29} // namespace details
30
32protected:
41 GaudiHandleInfo( std::string myComponentType, std::string myParentName )
42 : m_componentType( std::move( myComponentType ) ), m_parentName( std::move( myParentName ) ) {}
43
44public:
46 // Don't use =default here. Otherwise, in c++20 mode, clang will
47 // instantiate the handle virtual functions early, breaking the case
48 // where handles are used with a forward-declared class.
49 virtual ~GaudiHandleInfo() {}
50 //
51 // Public member functions
52 //
53 const std::string& componentType() const { return m_componentType; }
54
56 const std::string& propertyName() const { return m_propertyName; }
57
59 void setPropertyName( std::string propName ) { m_propertyName = std::move( propName ); }
60
62 const std::string& parentName() const { return m_parentName; }
63
67 virtual std::string pythonPropertyClassName() const = 0;
68
73 virtual std::string pythonRepr() const = 0;
74
75 // Easy printing out of Handles and HandleArrays
76 // It prints <propertyName> = <HandleType>( <HandleType(s)AndName(s)> )
77 friend std::ostream& operator<<( std::ostream& os, const GaudiHandleInfo& handle );
78
79protected:
81 void setComponentType( std::string componentType ) { m_componentType = std::move( componentType ); }
82
84 void setParentName( std::string parent ) { m_parentName = std::move( parent ); }
85
86private:
87 //
88 // Data members
89 //
90 std::string m_componentType; // e.g.: "PublicTool","PrivateTool","Service"
91 std::string m_propertyName; // name as used in declareProperty(name,gaudiHandle)
92 std::string m_parentName; // name of the parent having this handle as a member
93};
94
103 //
104 // Ctors etc
105 //
106protected:
118 GaudiHandleBase( std::string myTypeAndName, std::string myComponentType, std::string myParentName )
119 : GaudiHandleInfo( std::move( myComponentType ), std::move( myParentName ) ) {
120 setTypeAndName( std::move( myTypeAndName ) );
121 }
122
123public:
124 //
125 // Public member functions
126 //
128 const std::string& typeAndName() const { return m_typeAndName; }
129
131 std::string type() const;
132
134 std::string name() const;
135
137 bool empty() const { return m_typeAndName.empty(); }
138
140 void setTypeAndName( std::string myTypeAndName );
141
143 void setName( std::string_view myName );
144
148 std::string pythonPropertyClassName() const override;
149
151 std::string messageName() const;
152
156 std::string pythonRepr() const override;
157
159 GaudiHandleBase& operator=( const std::string& typeAndName ) {
161 return *this;
162 }
163
166 setTypeAndName( std::move( typeAndName ) );
167 return *this;
168 }
169
171
172private:
173 //
174 // Data member
175 //
176 std::string m_typeAndName; // the full type and name: "type/name"
177};
178
187template <class T>
189 //
190 // Constructors etc.
191 //
192protected:
193 GaudiHandle( std::string myTypeAndName, std::string myComponentType, std::string myParentName )
194 : GaudiHandleBase( std::move( myTypeAndName ), std::move( myComponentType ), std::move( myParentName ) ) {}
195
196public:
198 template <typename CT = T, typename NCT = std::remove_const_t<T>>
200 requires( std::is_const_v<CT> && !std::is_same_v<CT, NCT> )
201 : GaudiHandleBase( other ), m_pObject( other.get() ) {
202 if ( m_pObject ) ::details::nonConst( m_pObject.load() )->addRef();
203 }
204
206 GaudiHandle( const GaudiHandle& other ) : GaudiHandleBase( other ), m_pObject( other.m_pObject.load() ) {
207 if ( m_pObject ) ::details::nonConst( m_pObject.load() )->addRef();
208 }
209
211 template <typename CT = T, typename NCT = std::remove_const_t<T>>
212 requires( std::is_const_v<CT> && !std::is_same_v<CT, NCT> )
215 // release any current tool
216 release().ignore();
217 m_pObject = other.get();
218 // update ref-counting
219 if ( m_pObject ) ::details::nonConst( m_pObject.load() )->addRef();
220 return *this;
221 }
222
226 // release any current tool
227 release().ignore();
228 m_pObject = other.m_pObject.load();
229 // update ref-counting
230 if ( m_pObject ) ::details::nonConst( m_pObject.load() )->addRef();
231 return *this;
232 }
233
236 // not really const, because it updates m_pObject
237 // Do the lookup into a temporary pointer.
238 T* p = nullptr;
239 if ( retrieve( p ).isFailure() ) { return StatusCode::FAILURE; }
240
241 // If m_pObject is null, then copy p to m_pObject.
242 // Otherwise, release p.
243 T* old = nullptr;
244 if ( m_pObject.compare_exchange_strong( old, p ) ) { return StatusCode::SUCCESS; }
245 return release( p );
246 }
247
250 // not really const, because it updates m_pObject
252 if ( m_pObject ) {
253 sc = release( m_pObject );
254 m_pObject = nullptr;
255 }
256 return sc;
257 }
258
260 bool isValid() const {
261 // not really const, because it may update m_pObject
262 return m_pObject || retrieve().isSuccess();
263 }
264
267 operator bool() const {
268 // not really const, because it may update m_pObject
269 return isValid();
270 }
271
273 T* get() { return m_pObject; }
274
276 std::add_const_t<T>* get() const { return m_pObject; }
277
279 bool isSet() const { return get(); }
280
282 assertObject();
283 return *m_pObject;
284 }
285
287 assertObject();
288 return m_pObject;
289 }
290
291 std::add_const_t<T>& operator*() const {
292 // not really const, because it may update m_pObject
293 assertObject();
294 return *m_pObject;
295 }
296
297 std::add_const_t<T>* operator->() const {
298 // not really const, because it may update m_pObject
299 assertObject();
300 return m_pObject;
301 }
302
304 std::string getDefaultType() { return System::typeinfoName( typeid( T ) ); }
305
306 std::string getDefaultName() {
307 const auto defName = GaudiHandleBase::type();
308 return ( defName.empty() ? getDefaultType() : defName );
309 }
310
311protected:
313 virtual StatusCode retrieve( T*& ) const = 0; // not really const, because it updates m_pObject
314
317 virtual StatusCode release( T* comp ) const { // not really const, because it updates m_pObject
318 // const cast to support T being a const type
319 ::details::nonConst( comp )->release();
320 return StatusCode::SUCCESS;
321 }
322
323private:
326 void assertObject() const { // not really const, because it may update m_pObject
327 if ( !isValid() ) {
328 throw GaudiException( "Failed to retrieve " + componentType() + ": " + typeAndName(),
329 componentType() + " retrieve", StatusCode::FAILURE );
330 }
331 }
332
333private:
334 //
335 // Data members
336 //
337 mutable std::atomic<T*> m_pObject = nullptr;
338};
339
345
347protected:
348 GaudiHandleArrayBase( std::string myComponentType, std::string myParentName )
349 : GaudiHandleInfo( std::move( myComponentType ), std::move( myParentName ) ) {}
350
351public:
353 typedef std::vector<GaudiHandleBase*> BaseHandleArray;
354 typedef std::vector<const GaudiHandleBase*> ConstBaseHandleArray;
355
358 bool setTypesAndNames( const std::vector<std::string>& myTypesAndNamesList );
359
362 const std::vector<std::string> typesAndNames() const;
363
365 const std::vector<std::string> types() const;
366
368 const std::vector<std::string> names() const;
369
372 const std::vector<std::string> getBaseInfos( auto ( GaudiHandleBase::*pMemFunc )() const ) const;
373
377 std::string pythonPropertyClassName() const override;
378
382 std::string pythonRepr() const override;
383
387 virtual bool push_back( const std::string& myHandleTypeAndName ) = 0;
388
390 virtual void clear() = 0;
391
393 virtual bool empty() const = 0;
394
398
402
404 virtual StatusCode retrieve() = 0;
405
407 virtual StatusCode release() = 0;
408
410 virtual bool retrieved() const = 0;
411};
412
414template <class T>
416public:
417 //
418 // public nested types
419 //
420 typedef std::vector<T> HandleVector;
421 typedef typename HandleVector::value_type value_type;
422 typedef typename HandleVector::size_type size_type;
423 typedef typename HandleVector::reference reference;
424 typedef typename HandleVector::const_reference const_reference;
425 typedef typename HandleVector::iterator iterator;
426 typedef typename HandleVector::const_iterator const_iterator;
427 typedef typename HandleVector::reverse_iterator reverse_iterator;
428 typedef typename HandleVector::const_reverse_iterator const_reverse_iterator;
429
430protected:
431 //
432 // Constructors
433 //
438 GaudiHandleArray( const std::vector<std::string>& myTypesAndNamesList, std::string myComponentType,
439 std::string myParentName )
440 : GaudiHandleArrayBase( std::move( myComponentType ), std::move( myParentName ) ) {
441 setTypesAndNames( myTypesAndNamesList );
442 }
443
448 GaudiHandleArray( const std::string& myComponentType, const std::string& myParentName )
449 : GaudiHandleArrayBase( myComponentType, myParentName ) {}
450
451public:
453 GaudiHandleArray& operator=( const std::vector<std::string>& myTypesAndNamesList ) {
454 setTypesAndNames( myTypesAndNamesList );
455 return *this;
456 }
457
460 for ( auto& h : m_handleArray ) baseArray.push_back( &h );
461 return baseArray;
462 }
463
466 for ( auto& h : m_handleArray ) baseArray.push_back( &h );
467 return baseArray;
468 }
469
470 //
471 // Simulate (part of) an std::vector
472 //
473 iterator begin() { return m_handleArray.begin(); }
474
475 iterator end() { return m_handleArray.end(); }
476
477 const_iterator begin() const { return m_handleArray.begin(); }
478
479 const_iterator end() const { return m_handleArray.end(); }
480
481 const_iterator rbegin() const { return m_handleArray.rbegin(); }
482
483 const_iterator rend() const { return m_handleArray.rend(); }
484
485 size_type size() const { return m_handleArray.size(); }
486
487 void clear() override { m_handleArray.clear(); }
488
489 bool empty() const override { return m_handleArray.empty(); }
490
491 T& operator[]( int index ) { return m_handleArray[index]; }
492
493 const T& operator[]( int index ) const { return m_handleArray[index]; }
494
496 T* operator[]( std::string_view name ) {
497 auto it = std::find_if( begin(), end(), [&]( const_reference r ) { return r.name() == name; } );
498 return it != end() ? &*it : nullptr;
499 }
500
502 const T* operator[]( std::string_view name ) const {
503 auto it = std::find_if( begin(), end(), [&]( const_reference r ) { return r.name() == name; } );
504 return it != end() ? &*it : nullptr;
505 }
506
509 using GaudiHandleArrayBase::push_back; // avoid compiler warning
510 virtual bool push_back( const T& myHandle ) {
511 m_handleArray.push_back( myHandle );
512 return true;
513 }
514
516 StatusCode retrieve() override {
518 for ( auto& i : *this ) {
519 // stop at first failure
520 if ( i.retrieve().isFailure() ) {
522 break;
523 }
524 }
525 if ( sc ) { m_retrieved = true; }
526 return sc;
527 }
528
530 StatusCode release() override {
532 for ( auto& i : *this ) {
533 // continue trying to release other tools even if we fail...
534 if ( i.release().isFailure() ) sc = StatusCode::FAILURE;
535 }
536 return sc;
537 }
538
540 virtual bool retrieved() const override { return m_retrieved; }
541
542private:
543 //
544 // Private data members
545 //
547 bool m_retrieved{ false };
548};
std::ostream & operator<<(std::ostream &s, AlgsExecutionStates::State x)
Streaming of State values.
#define GAUDI_API
Definition Kernel.h:49
Define general base for Gaudi exception.
virtual bool push_back(const std::string &myHandleTypeAndName)=0
Add a handle to the array with "type/name" given in <myHandleTypeAndName>.
GaudiHandleArrayBase(std::string myComponentType, std::string myParentName)
std::vector< const GaudiHandleBase * > ConstBaseHandleArray
virtual void clear()=0
Clear the list of handles.
bool setTypesAndNames(const std::vector< std::string > &myTypesAndNamesList)
Set the array of handles from list of "type/name" strings in <myTypesAndNamesList>.
std::vector< GaudiHandleBase * > BaseHandleArray
std::string pythonRepr() const override
Python representation of array of handles, i.e.
const std::vector< std::string > typesAndNames() const
Return a vector with "type/name" strings of all handles in the array.
const std::vector< std::string > types() const
Return a vector with "type" strings of all handles in the array.
const std::vector< std::string > getBaseInfos(auto(GaudiHandleBase::*pMemFunc)() const) const
Helper function to get a vector of strings filled with the return value of each tool of a member func...
virtual ConstBaseHandleArray getBaseArray() const =0
Get a read-only vector of const GaudiHandleBase* pointing to the real handles.
virtual BaseHandleArray getBaseArray()=0
Get a read-write vector of GaudiHandleBase* pointing to the real handles.
virtual StatusCode retrieve()=0
Retrieve all tools.
virtual bool empty() const =0
Return whether the list of tools is empty.
const std::vector< std::string > names() const
Return a vector with "type/name" strings of all handles in the array.
virtual StatusCode release()=0
Release all tools.
GaudiHandleArrayProperty PropertyType
virtual bool retrieved() const =0
To be able to tell if Array was ever retreived.
std::string pythonPropertyClassName() const override
Name of the componentType with "HandleArray" appended.
virtual bool push_back(const T &myHandle)
HandleVector::iterator iterator
T & operator[](int index)
const_iterator end() const
const T * operator[](std::string_view name) const
Get const pointer (!) to ToolHandle by instance name.
void clear() override
Clear the list of handles.
std::vector< T > HandleVector
HandleVector::reverse_iterator reverse_iterator
HandleVector::size_type size_type
size_type size() const
const T & operator[](int index) const
HandleVector m_handleArray
StatusCode release() override
Release all tools.
StatusCode retrieve() override
Retrieve all tools.
const_iterator rend() const
HandleVector::value_type value_type
T * operator[](std::string_view name)
Get pointer (!) to ToolHandle by instance name.
GaudiHandleArrayBase::BaseHandleArray getBaseArray() override
Get a read-write vector of GaudiHandleBase* pointing to the real handles.
iterator begin()
bool empty() const override
Return whether the list of tools is empty.
HandleVector::const_reference const_reference
GaudiHandleArray(const std::string &myComponentType, const std::string &myParentName)
Constructor creating an empty array.
HandleVector::const_reverse_iterator const_reverse_iterator
virtual bool retrieved() const override
has Array been retreived?
const_iterator begin() const
GaudiHandleArrayBase::ConstBaseHandleArray getBaseArray() const override
Get a read-only vector of const GaudiHandleBase* pointing to the real handles.
const_iterator rbegin() const
HandleVector::const_iterator const_iterator
GaudiHandleArray(const std::vector< std::string > &myTypesAndNamesList, std::string myComponentType, std::string myParentName)
Generic constructor.
HandleVector::reference reference
GaudiHandleArray & operator=(const std::vector< std::string > &myTypesAndNamesList)
Set the array of GaudiHandles from typeAndNames given in vector of strings.
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
GaudiHandleBase(std::string myTypeAndName, std::string myComponentType, std::string myParentName)
Create a handle ('smart pointer') to a gaudi component.
GaudiHandleProperty PropertyType
GaudiHandleBase & operator=(std::string &&typeAndName)
Set "type/name" from string.
const std::string & typeAndName() const
The full type and name: "type/name".
bool empty() const
Check if the handle has been set to empty string (i.e.
std::string m_typeAndName
GaudiHandleBase & operator=(const std::string &typeAndName)
Set "type/name" from string.
void setTypeAndName(std::string myTypeAndName)
The component "type/name" string.
std::string type() const
The concrete component class name: the part before the '/'.
StatusCode release() const
Release the component.
T * get()
Return the wrapped pointer, not calling retrieve() if null.
std::add_const_t< T > & operator*() const
bool isValid() const
Check if the handle is valid (try to retrive the object is not done yet).
T * operator->()
GaudiHandle(const GaudiHandle &other)
Copy constructor needed for correct ref-counting.
StatusCode retrieve() const
Retrieve the component.
GaudiHandle & operator=(const GaudiHandle &other)
Assignment operator for correct ref-counting.
std::add_const_t< T > * get() const
Return the wrapped pointer, not calling retrieve() if null.
void assertObject() const
Load the pointer to the component.
virtual StatusCode release(T *comp) const
Release the component.
GaudiHandle(std::string myTypeAndName, std::string myComponentType, std::string myParentName)
GaudiHandle & operator=(const GaudiHandle< NCT > &other)
Assignment operator for correct ref-counting.
std::string getDefaultName()
virtual StatusCode retrieve(T *&) const =0
Retrieve the component.
std::string getDefaultType()
Helper function to get default type string from the class type.
bool isSet() const
True if the wrapped pointer is not null.
std::add_const_t< T > * operator->() const
GaudiHandle(const GaudiHandle< NCT > &other)
Copy constructor needed for correct ref-counting.
std::atomic< T * > m_pObject
T & operator*()
std::string m_componentType
Definition GaudiHandle.h:90
const std::string & componentType() const
Definition GaudiHandle.h:53
std::string m_propertyName
Definition GaudiHandle.h:91
GaudiHandleInfo(std::string myComponentType, std::string myParentName)
Some basic information and helper functions shared between various handles/arrays.
Definition GaudiHandle.h:41
const std::string & propertyName() const
name as used in declareProperty(name,gaudiHandle)
Definition GaudiHandle.h:56
void setParentName(std::string parent)
The name of the parent.
Definition GaudiHandle.h:84
virtual std::string pythonPropertyClassName() const =0
The python class name for the property in the genconf-generated configurables.
std::string m_parentName
Definition GaudiHandle.h:92
void setPropertyName(std::string propName)
set name as used in declareProperty(name,gaudiHandle).
Definition GaudiHandle.h:59
const std::string & parentName() const
The name of the parent.
Definition GaudiHandle.h:62
virtual ~GaudiHandleInfo()
virtual destructor so that derived class destructor is called.
Definition GaudiHandle.h:49
void setComponentType(std::string componentType)
The component type.
Definition GaudiHandle.h:81
virtual std::string pythonRepr() const =0
Python representation of handle, i.e.
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:254
std::remove_const_t< T > * nonConst(T *p)
Cast a pointer to a non const type.
Definition GaudiHandle.h:26
STL namespace.