The Gaudi Framework  v33r2 (a6f0ec87)
GaudiHandle.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2020 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_GAUDIHANDLE_H
12 #define GAUDIKERNEL_GAUDIHANDLE_H
13 
14 // Includes
16 #include "GaudiKernel/IInterface.h"
17 #include "GaudiKernel/Property.h"
18 #include "GaudiKernel/System.h"
19 
20 #include <algorithm>
21 #include <iostream>
22 #include <stdexcept>
23 #include <string>
24 #include <type_traits>
25 #include <vector>
26 
27 namespace details {
29  template <class T>
30  std::remove_const_t<T>* nonConst( T* p ) {
31  return const_cast<std::remove_const_t<T>*>( p );
32  }
33 } // namespace details
34 
36 protected:
45  GaudiHandleInfo( std::string myComponentType, std::string myParentName )
46  : m_componentType( std::move( myComponentType ) ), m_parentName( std::move( myParentName ) ) {}
47 
48 public:
50  virtual ~GaudiHandleInfo() = default;
51  //
52  // Public member functions
53  //
54  const std::string& componentType() const { return m_componentType; }
55 
57  const std::string& propertyName() const { return m_propertyName; }
58 
60  void setPropertyName( std::string propName ) { m_propertyName = std::move( propName ); }
61 
63  const std::string& parentName() const { return m_parentName; }
64 
68  virtual std::string pythonPropertyClassName() const = 0;
69 
74  virtual std::string pythonRepr() const = 0;
75 
76 protected:
78  void setComponentType( std::string componentType ) { m_componentType = std::move( componentType ); }
79 
81  void setParentName( std::string parent ) { m_parentName = std::move( parent ); }
82 
83 private:
84  //
85  // Data members
86  //
87  std::string m_componentType; // e.g.: "PublicTool","PrivateTool","Service"
88  std::string m_propertyName; // name as used in declareProperty(name,gaudiHandle)
89  std::string m_parentName; // name of the parent having this handle as a member
90 };
91 
100  //
101  // Ctors etc
102  //
103 protected:
115  GaudiHandleBase( std::string myTypeAndName, std::string myComponentType, std::string myParentName )
116  : GaudiHandleInfo( std::move( myComponentType ), std::move( myParentName ) ) {
117  setTypeAndName( std::move( myTypeAndName ) );
118  }
119 
120 public:
121  //
122  // Public member functions
123  //
125  std::string typeAndName() const { return m_typeAndName; }
126 
128  std::string type() const;
129 
131  std::string name() const;
132 
134  bool empty() const { return m_typeAndName.empty(); }
135 
137  void setTypeAndName( std::string myTypeAndName );
138 
140  void setName( std::string_view myName );
141 
145  std::string pythonPropertyClassName() const override;
146 
148  std::string messageName() const;
149 
153  std::string pythonRepr() const override;
154 
156 
157 private:
158  //
159  // Data member
160  //
161  std::string m_typeAndName; // the full type and name: "type/name"
162 };
163 
172 template <class T>
174  //
175  // Constructors etc.
176  //
177 protected:
178  GaudiHandle( std::string myTypeAndName, std::string myComponentType, std::string myParentName )
179  : GaudiHandleBase( std::move( myTypeAndName ), std::move( myComponentType ), std::move( myParentName ) ) {}
180 
181 public:
183  template <typename CT = T, typename NCT = std::remove_const_t<T>>
185  std::enable_if_t<std::is_const_v<CT> && !std::is_same_v<CT, NCT>>* = nullptr )
186  : GaudiHandleBase( other ) {
187  m_pObject = other.get();
188  if ( m_pObject ) ::details::nonConst( m_pObject.load() )->addRef();
189  }
190 
192  GaudiHandle( const GaudiHandle& other ) : GaudiHandleBase( other ) {
193  m_pObject = other.m_pObject.load();
194  if ( m_pObject ) ::details::nonConst( m_pObject.load() )->addRef();
195  }
196 
198  template <typename CT = T, typename NCT = std::remove_const_t<T>>
199  std::enable_if_t<std::is_const_v<CT> && !std::is_same_v<CT, NCT>, GaudiHandle&>
200  operator=( const GaudiHandle<NCT>& other ) {
201  GaudiHandleBase::operator=( other );
202  // release any current tool
203  release().ignore();
204  m_pObject = other.get();
205  // update ref-counting
206  if ( m_pObject ) ::details::nonConst( m_pObject.load() )->addRef();
207  return *this;
208  }
209 
211  GaudiHandle& operator=( const GaudiHandle& other ) {
212  GaudiHandleBase::operator=( other );
213  // release any current tool
214  release().ignore();
215  m_pObject = other.m_pObject.load();
216  // update ref-counting
217  if ( m_pObject ) ::details::nonConst( m_pObject.load() )->addRef();
218  return *this;
219  }
220 
223  // not really const, because it updates m_pObject
224  // Do the lookup into a temporary pointer.
225  T* p = nullptr;
226  if ( retrieve( p ).isFailure() ) { return StatusCode::FAILURE; }
227 
228  // If m_pObject is null, then copy p to m_pObject.
229  // Otherwise, release p.
230  T* old = nullptr;
231  if ( m_pObject.compare_exchange_strong( old, p ) ) { return StatusCode::SUCCESS; }
232  return release( p );
233  }
234 
236  StatusCode release() const {
237  // not really const, because it updates m_pObject
239  if ( m_pObject ) {
240  sc = release( m_pObject );
241  m_pObject = nullptr;
242  }
243  return sc;
244  }
245 
247  bool isValid() const {
248  // not really const, because it may update m_pObject
249  return m_pObject || retrieve().isSuccess();
250  }
251 
254  operator bool() const {
255  // not really const, because it may update m_pObject
256  return isValid();
257  }
258 
260  T* get() { return m_pObject; }
261 
263  std::add_const_t<T>* get() const { return m_pObject; }
264 
266  bool isSet() const { return get(); }
267 
268  T& operator*() {
269  assertObject();
270  return *m_pObject;
271  }
272 
273  T* operator->() {
274  assertObject();
275  return m_pObject;
276  }
277 
278  std::add_const_t<T>& operator*() const {
279  // not really const, because it may update m_pObject
280  assertObject();
281  return *m_pObject;
282  }
283 
284  std::add_const_t<T>* operator->() const {
285  // not really const, because it may update m_pObject
286  assertObject();
287  return m_pObject;
288  }
289 
291  std::string getDefaultType() { return System::typeinfoName( typeid( T ) ); }
292 
294  const auto defName = GaudiHandleBase::type();
295  return ( defName.empty() ? getDefaultType() : defName );
296  }
297 
298 protected:
300  virtual StatusCode retrieve( T*& ) const = 0; // not really const, because it updates m_pObject
301 
304  virtual StatusCode release( T* comp ) const { // not really const, because it updates m_pObject
305  // const cast to support T being a const type
306  ::details::nonConst( comp )->release();
307  return StatusCode::SUCCESS;
308  }
309 
310 private:
313  const std::string& myType = getDefaultType();
314  GaudiHandleBase::setTypeAndName( myType + '/' + myType );
315  }
316 
318  void setDefaultType() { GaudiHandleBase::setTypeAndName( getDefaultType() ); }
319 
322  void assertObject() const { // not really const, because it may update m_pObject
323  if ( UNLIKELY( !isValid() ) ) {
324  throw GaudiException( "Failed to retrieve " + componentType() + ": " + typeAndName(),
325  componentType() + " retrieve", StatusCode::FAILURE );
326  }
327  }
328 
329 private:
330  //
331  // Data members
332  //
333  mutable std::atomic<T*> m_pObject = nullptr;
334 };
335 
343 protected:
344  GaudiHandleArrayBase( std::string myComponentType, std::string myParentName )
345  : GaudiHandleInfo( std::move( myComponentType ), std::move( myParentName ) ) {}
346 
347 public:
351 
354  bool setTypesAndNames( const std::vector<std::string>& myTypesAndNamesList );
355 
358  const std::vector<std::string> typesAndNames() const;
359 
361  const std::vector<std::string> types() const;
362 
364  const std::vector<std::string> names() const;
365 
368  const std::vector<std::string> getBaseInfos( std::string ( GaudiHandleBase::*pMemFunc )() const ) const;
369 
373  std::string pythonPropertyClassName() const override;
374 
378  std::string pythonRepr() const override;
379 
383  virtual bool push_back( const std::string& myHandleTypeAndName ) = 0;
384 
386  virtual void clear() = 0;
387 
389  virtual bool empty() const = 0;
390 
393  virtual ConstBaseHandleArray getBaseArray() const = 0;
394 
397  virtual BaseHandleArray getBaseArray() = 0;
398 
400  virtual bool retrieved() const = 0;
401 };
402 
404 template <class T>
406 public:
407  //
408  // public nested types
409  //
411  typedef typename HandleVector::value_type value_type;
412  typedef typename HandleVector::size_type size_type;
413  typedef typename HandleVector::reference reference;
414  typedef typename HandleVector::const_reference const_reference;
415  typedef typename HandleVector::iterator iterator;
416  typedef typename HandleVector::const_iterator const_iterator;
417  typedef typename HandleVector::reverse_iterator reverse_iterator;
418  typedef typename HandleVector::const_reverse_iterator const_reverse_iterator;
419 
420 protected:
421  //
422  // Constructors
423  //
428  GaudiHandleArray( const std::vector<std::string>& myTypesAndNamesList, std::string myComponentType,
429  std::string myParentName )
430  : GaudiHandleArrayBase( std::move( myComponentType ), std::move( myParentName ) ) {
431  setTypesAndNames( myTypesAndNamesList );
432  }
433 
438  GaudiHandleArray( const std::string& myComponentType, const std::string& myParentName )
439  : GaudiHandleArrayBase( myComponentType, myParentName ) {}
440 
441 public:
443  GaudiHandleArray& operator=( const std::vector<std::string>& myTypesAndNamesList ) {
444  setTypesAndNames( myTypesAndNamesList );
445  return *this;
446  }
447 
450  for ( auto& h : m_handleArray ) baseArray.push_back( &h );
451  return baseArray;
452  }
453 
456  for ( auto& h : m_handleArray ) baseArray.push_back( &h );
457  return baseArray;
458  }
459 
460  //
461  // Simulate (part of) an std::vector
462  //
463  iterator begin() { return m_handleArray.begin(); }
464 
465  iterator end() { return m_handleArray.end(); }
466 
467  const_iterator begin() const { return m_handleArray.begin(); }
468 
469  const_iterator end() const { return m_handleArray.end(); }
470 
471  const_iterator rbegin() const { return m_handleArray.rbegin(); }
472 
473  const_iterator rend() const { return m_handleArray.rend(); }
474 
475  size_type size() const { return m_handleArray.size(); }
476 
477  void clear() override { m_handleArray.clear(); }
478 
479  bool empty() const override { return m_handleArray.empty(); }
480 
481  T& operator[]( int index ) { return m_handleArray[index]; }
482 
483  const T& operator[]( int index ) const { return m_handleArray[index]; }
484 
486  T* operator[]( std::string_view name ) {
487  auto it = std::find_if( begin(), end(), [&]( const_reference r ) { return r.name() == name; } );
488  return it != end() ? &*it : nullptr;
489  }
490 
492  const T* operator[]( std::string_view name ) const {
493  auto it = std::find_if( begin(), end(), [&]( const_reference r ) { return r.name() == name; } );
494  return it != end() ? &*it : nullptr;
495  }
496 
499  using GaudiHandleArrayBase::push_back; // avoid compiler warning
500  virtual bool push_back( const T& myHandle ) {
501  m_handleArray.push_back( myHandle );
502  return true;
503  }
504 
508  for ( auto& i : *this ) {
509  // stop at first failure
510  if ( i.retrieve().isFailure() ) {
511  sc = StatusCode::FAILURE;
512  break;
513  }
514  }
515  if ( sc ) { m_retrieved = true; }
516  return sc;
517  }
518 
522  for ( auto& i : *this ) {
523  // continue trying to release other tools even if we fail...
524  if ( i.release().isFailure() ) sc = StatusCode::FAILURE;
525  }
526  return sc;
527  }
528 
530  virtual bool retrieved() const override { return m_retrieved; }
531 
532 private:
533  //
534  // Private data members
535  //
537  bool m_retrieved{false};
538 };
539 
540 // Easy printing out of Handles and HandleArrays
541 // It prints <propertyName> = <HandleType>( <HandleType(s)AndName(s)> )
542 std::ostream& operator<<( std::ostream& os, const GaudiHandleInfo& handle );
543 
544 #endif // ! GAUDIKERNEL_GAUDIHANDLE_H
GaudiHandle & operator=(const GaudiHandle &other)
Assignment operator for correct ref-counting.
Definition: GaudiHandle.h:211
HandleVector::const_reference const_reference
Definition: GaudiHandle.h:414
#define UNLIKELY(x)
Definition: Kernel.h:106
HandleVector::value_type value_type
Definition: GaudiHandle.h:411
Handle to be used in lieu of naked pointers to gaudis.
Definition: GaudiHandle.h:173
StatusCode release() const
Release the component.
Definition: GaudiHandle.h:236
void clear() override
Clear the list of handles.
Definition: GaudiHandle.h:477
std::string getDefaultType()
Helper function to get default type string from the class type.
Definition: GaudiHandle.h:291
Define general base for Gaudi exception.
std::add_const_t< T > * get() const
Return the wrapped pointer, not calling retrieve() if null.
Definition: GaudiHandle.h:263
bool empty() const
Check if the handle has been set to empty string (i.e.
Definition: GaudiHandle.h:134
HandleVector::iterator iterator
Definition: GaudiHandle.h:415
GaudiHandleArrayBase::BaseHandleArray getBaseArray() override
Get a read-write vector of GaudiHandleBase* pointing to the real handles.
Definition: GaudiHandle.h:448
void setTypeAndName(std::string myTypeAndName)
The component "type/name" string.
Definition: GaudiHandle.cpp:19
const std::string & propertyName() const
name as used in declareProperty(name,gaudiHandle)
Definition: GaudiHandle.h:57
GaudiHandle(const GaudiHandle< NCT > &other, std::enable_if_t< std::is_const_v< CT > &&!std::is_same_v< CT, NCT >> *=nullptr)
Copy constructor needed for correct ref-counting.
Definition: GaudiHandle.h:184
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:308
std::vector< T > HandleVector
Definition: GaudiHandle.h:410
std::string typeAndName() const
The full type and name: "type/name".
Definition: GaudiHandle.h:125
HandleVector::const_reverse_iterator const_reverse_iterator
Definition: GaudiHandle.h:418
std::string getDefaultName()
Definition: GaudiHandle.h:293
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
size_type size() const
Definition: GaudiHandle.h:475
STL namespace.
StatusCode retrieve() const
Retrieve the component.
Definition: GaudiHandle.h:222
GaudiHandle(std::string myTypeAndName, std::string myComponentType, std::string myParentName)
Definition: GaudiHandle.h:178
void setComponentType(std::string componentType)
The component type.
Definition: GaudiHandle.h:78
void setDefaultType()
Helper function to set default type from the class type T.
Definition: GaudiHandle.h:318
std::string m_componentType
Definition: GaudiHandle.h:87
GaudiHandleArray(const std::vector< std::string > &myTypesAndNamesList, std::string myComponentType, std::string myParentName)
Generic constructor.
Definition: GaudiHandle.h:428
HandleVector::size_type size_type
Definition: GaudiHandle.h:412
GaudiHandleArray & operator=(const std::vector< std::string > &myTypesAndNamesList)
Set the array of GaudiHandles from typeAndNames given in vector of strings.
Definition: GaudiHandle.h:443
bool empty() const override
Return whether the list of tools is empty.
Definition: GaudiHandle.h:479
HandleVector::reference reference
Definition: GaudiHandle.h:413
virtual bool push_back(const T &myHandle)
Definition: GaudiHandle.h:500
std::enable_if_t< std::is_const_v< CT > &&!std::is_same_v< CT, NCT >, GaudiHandle & > operator=(const GaudiHandle< NCT > &other)
Assignment operator for correct ref-counting.
Definition: GaudiHandle.h:200
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
const T & operator[](int index) const
Definition: GaudiHandle.h:483
auto operator *(const std::chrono::duration< Rep1, Period > &lhs, const std::chrono::duration< Rep2, Period > &rhs)
Multiplication of two std::chrono::duration objects with same Period.
Definition: Counters.h:40
std::add_const_t< T > * operator->() const
Definition: GaudiHandle.h:284
STL class.
void push_back(Container &c, const Value &v, std::true_type)
T push_back(T... args)
void setDefaultTypeAndName()
Helper function to set default name and type.
Definition: GaudiHandle.h:312
virtual std::string pythonRepr() const =0
Python representation of handle, i.e.
HandleVector m_handleArray
Definition: GaudiHandle.h:536
StatusCode retrieve()
Retrieve all tools.
Definition: GaudiHandle.h:506
const_iterator rend() const
Definition: GaudiHandle.h:473
iterator begin()
Definition: GaudiHandle.h:463
std::remove_const_t< T > * nonConst(T *p)
Cast a pointer to a non const type.
Definition: GaudiHandle.h:30
bool setTypesAndNames(const std::vector< std::string > &myTypesAndNamesList)
Set the array of handles from list of "type/name" strings in <myTypesAndNamesList>.
Definition: GaudiHandle.cpp:63
const_iterator end() const
Definition: GaudiHandle.h:469
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
const std::string & parentName() const
The name of the parent.
Definition: GaudiHandle.h:63
virtual bool retrieved() const override
has Array been retreived?
Definition: GaudiHandle.h:530
T * get()
Return the wrapped pointer, not calling retrieve() if null.
Definition: GaudiHandle.h:260
GaudiHandleArrayBase::ConstBaseHandleArray getBaseArray() const override
Get a read-only vector of const GaudiHandleBase* pointing to the real handles.
Definition: GaudiHandle.h:454
std::string m_typeAndName
Definition: GaudiHandle.h:161
def end
Definition: IOTest.py:123
const T * operator[](std::string_view name) const
Get const pointer (!) to ToolHandle by instance name.
Definition: GaudiHandle.h:492
const_iterator rbegin() const
Definition: GaudiHandle.h:471
std::vector< const GaudiHandleBase * > ConstBaseHandleArray
Definition: GaudiHandle.h:350
T move(T... args)
T * operator->()
Definition: GaudiHandle.h:273
void assertObject() const
Load the pointer to the component.
Definition: GaudiHandle.h:322
const std::string & componentType() const
Definition: GaudiHandle.h:54
std::atomic< T * > m_pObject
Definition: GaudiHandle.h:333
T find_if(T... args)
HandleVector::const_iterator const_iterator
Definition: GaudiHandle.h:416
Base class of array's of various gaudihandles.
Definition: GaudiHandle.h:342
virtual StatusCode release(T *comp) const
Release the component.
Definition: GaudiHandle.h:304
virtual std::string pythonPropertyClassName() const =0
The python class name for the property in the genconf-generated configurables.
STL class.
bool isSet() const
True if the wrapped pointer is not null.
Definition: GaudiHandle.h:266
std::string type() const
The concrete component class name: the part before the '/'.
Definition: GaudiHandle.cpp:21
GaudiHandleInfo(std::string myComponentType, std::string myParentName)
Some basic information and helper functions shared between various handles/arrays.
Definition: GaudiHandle.h:45
void setPropertyName(std::string propName)
set name as used in declareProperty(name,gaudiHandle).
Definition: GaudiHandle.h:60
HandleVector::reverse_iterator reverse_iterator
Definition: GaudiHandle.h:417
virtual bool push_back(const std::string &myHandleTypeAndName)=0
Add a handle to the array with "type/name" given in <myHandleTypeAndName>.
std::vector< GaudiHandleBase * > BaseHandleArray
Definition: GaudiHandle.h:349
void setParentName(std::string parent)
The name of the parent.
Definition: GaudiHandle.h:81
constexpr static const auto FAILURE
Definition: StatusCode.h:101
std::ostream & operator<<(std::ostream &os, const GaudiHandleInfo &handle)
const Gaudi::Algorithm & parent
iterator end()
Definition: GaudiHandle.h:465
T & operator[](int index)
Definition: GaudiHandle.h:481
const_iterator begin() const
Definition: GaudiHandle.h:467
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
Definition: GaudiHandle.h:99
AttribStringParser::Iterator begin(const AttribStringParser &parser)
GaudiHandleArrayBase(std::string myComponentType, std::string myParentName)
Definition: GaudiHandle.h:344
#define GAUDI_API
Definition: Kernel.h:81
T * operator[](std::string_view name)
Get pointer (!) to ToolHandle by instance name.
Definition: GaudiHandle.h:486
STL class.
GaudiHandleBase(std::string myTypeAndName, std::string myComponentType, std::string myParentName)
Create a handle ('smart pointer') to a gaudi component.
Definition: GaudiHandle.h:115
std::string m_propertyName
Definition: GaudiHandle.h:88
T load(T... args)
GaudiHandle(const GaudiHandle &other)
Copy constructor needed for correct ref-counting.
Definition: GaudiHandle.h:192
bool isValid() const
Check if the handle is valid (try to retrive the object is not done yet).
Definition: GaudiHandle.h:247
T is the concrete handle type, e.g.
Definition: GaudiHandle.h:405
std::string m_parentName
Definition: GaudiHandle.h:89
StatusCode release()
Release all tools.
Definition: GaudiHandle.h:520
GaudiHandleArray(const std::string &myComponentType, const std::string &myParentName)
Constructor creating an empty array.
Definition: GaudiHandle.h:438