The Gaudi Framework  v32r2 (46d42edc)
GaudiHandle.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_GAUDIHANDLE_H
2 #define GAUDIKERNEL_GAUDIHANDLE_H
3 
4 // Includes
7 #include "GaudiKernel/Property.h"
8 #include "GaudiKernel/System.h"
9 
10 #include <algorithm>
11 #include <iostream>
12 #include <stdexcept>
13 #include <string>
14 #include <type_traits>
15 #include <vector>
16 
17 namespace details {
19  template <class T>
20  std::remove_const_t<T>* nonConst( T* p ) {
21  return const_cast<std::remove_const_t<T>*>( p );
22  }
23 } // namespace details
24 
26 protected:
35  GaudiHandleInfo( std::string myComponentType, std::string myParentName )
36  : m_componentType( std::move( myComponentType ) ), m_parentName( std::move( myParentName ) ) {}
37 
38 public:
40  virtual ~GaudiHandleInfo() = default;
41  //
42  // Public member functions
43  //
44  const std::string& componentType() const { return m_componentType; }
45 
47  const std::string& propertyName() const { return m_propertyName; }
48 
50  void setPropertyName( std::string propName ) { m_propertyName = std::move( propName ); }
51 
53  const std::string& parentName() const { return m_parentName; }
54 
58  virtual std::string pythonPropertyClassName() const = 0;
59 
64  virtual std::string pythonRepr() const = 0;
65 
66 protected:
68  void setComponentType( const std::string& componentType ) { m_componentType = componentType; }
69 
71  void setParentName( const std::string& parent ) { m_parentName = parent; }
72 
73 private:
74  //
75  // Data members
76  //
77  std::string m_componentType; // e.g.: "PublicTool","PrivateTool","Service"
78  std::string m_propertyName; // name as used in declareProperty(name,gaudiHandle)
79  std::string m_parentName; // name of the parent having this handle as a member
80 };
81 
90  //
91  // Ctors etc
92  //
93 protected:
105  GaudiHandleBase( std::string myTypeAndName, std::string myComponentType, std::string myParentName )
106  : GaudiHandleInfo( std::move( myComponentType ), std::move( myParentName ) ) {
107  setTypeAndName( std::move( myTypeAndName ) );
108  }
109 
110 public:
111  //
112  // Public member functions
113  //
115  std::string typeAndName() const { return m_typeAndName; }
116 
118  std::string type() const;
119 
121  std::string name() const;
122 
124  bool empty() const { return m_typeAndName.empty(); }
125 
127  void setTypeAndName( std::string myTypeAndName );
128 
130  void setName( const std::string& myName );
131 
135  std::string pythonPropertyClassName() const override;
136 
138  std::string messageName() const;
139 
143  std::string pythonRepr() const override;
144 
146 
147 private:
148  //
149  // Data member
150  //
151  std::string m_typeAndName; // the full type and name: "type/name"
152 };
153 
162 template <class T>
164  //
165  // Constructors etc.
166  //
167 protected:
168  GaudiHandle( std::string myTypeAndName, std::string myComponentType, std::string myParentName )
169  : GaudiHandleBase( std::move( myTypeAndName ), std::move( myComponentType ), std::move( myParentName ) ) {}
170 
171 public:
173  template <typename CT = T, typename NCT = std::remove_const_t<T>>
175  std::enable_if_t<std::is_const_v<CT> && !std::is_same_v<CT, NCT>>* = nullptr )
176  : GaudiHandleBase( other ) {
177  m_pObject = other.get();
178  if ( m_pObject ) ::details::nonConst( m_pObject )->addRef();
179  }
180 
182  GaudiHandle( const GaudiHandle& other ) : GaudiHandleBase( other ) {
183  m_pObject = other.m_pObject;
184  if ( m_pObject ) ::details::nonConst( m_pObject )->addRef();
185  }
186 
188  template <typename CT = T, typename NCT = std::remove_const_t<T>>
189  std::enable_if_t<std::is_const_v<CT> && !std::is_same_v<CT, NCT>, GaudiHandle&>
190  operator=( const GaudiHandle<NCT>& other ) {
191  GaudiHandleBase::operator=( other );
192  // release any current tool
193  release().ignore();
194  m_pObject = other.get();
195  // update ref-counting
196  if ( m_pObject ) ::details::nonConst( m_pObject )->addRef();
197  return *this;
198  }
199 
201  GaudiHandle& operator=( const GaudiHandle& other ) {
202  GaudiHandleBase::operator=( other );
203  // release any current tool
204  release().ignore();
205  m_pObject = other.m_pObject;
206  // update ref-counting
207  if ( m_pObject ) ::details::nonConst( m_pObject )->addRef();
208  return *this;
209  }
210 
213  // not really const, because it updates m_pObject
215  if ( m_pObject && release().isFailure() ) { sc = StatusCode::FAILURE; }
216  if ( sc && retrieve( m_pObject ).isFailure() ) {
217  m_pObject = nullptr;
218  sc = StatusCode::FAILURE;
219  }
220  return sc;
221  }
222 
224  StatusCode release() const {
225  // not really const, because it updates m_pObject
227  if ( m_pObject ) {
228  sc = release( m_pObject );
229  m_pObject = nullptr;
230  }
231  return sc;
232  }
233 
235  bool isValid() const {
236  // not really const, because it may update m_pObject
237  return m_pObject || retrieve().isSuccess();
238  }
239 
242  operator bool() const {
243  // not really const, because it may update m_pObject
244  return isValid();
245  }
246 
248  T* get() { return m_pObject; }
249 
251  std::add_const_t<T>* get() const { return m_pObject; }
252 
254  bool isSet() const { return get(); }
255 
256  T& operator*() {
257  assertObject();
258  return *m_pObject;
259  }
260 
261  T* operator->() {
262  assertObject();
263  return m_pObject;
264  }
265 
266  std::add_const_t<T>& operator*() const {
267  // not really const, because it may update m_pObject
268  assertObject();
269  return *m_pObject;
270  }
271 
272  std::add_const_t<T>* operator->() const {
273  // not really const, because it may update m_pObject
274  assertObject();
275  return m_pObject;
276  }
277 
279  std::string getDefaultType() { return System::typeinfoName( typeid( T ) ); }
280 
282  const auto defName = GaudiHandleBase::type();
283  return ( defName.empty() ? getDefaultType() : defName );
284  }
285 
286 protected:
288  virtual StatusCode retrieve( T*& ) const = 0; // not really const, because it updates m_pObject
289 
292  virtual StatusCode release( T* comp ) const { // not really const, because it updates m_pObject
293  // const cast to support T being a const type
294  ::details::nonConst( comp )->release();
295  return StatusCode::SUCCESS;
296  }
297 
298 private:
301  const std::string& myType = getDefaultType();
302  GaudiHandleBase::setTypeAndName( myType + '/' + myType );
303  }
304 
306  void setDefaultType() { GaudiHandleBase::setTypeAndName( getDefaultType() ); }
307 
310  void assertObject() const { // not really const, because it may update m_pObject
311  if ( UNLIKELY( !isValid() ) ) {
312  throw GaudiException( "Failed to retrieve " + componentType() + ": " + typeAndName(),
313  componentType() + " retrieve", StatusCode::FAILURE );
314  }
315  }
316 
317 private:
318  //
319  // Data members
320  //
321  mutable T* m_pObject = nullptr;
322 };
323 
331 protected:
332  GaudiHandleArrayBase( std::string myComponentType, std::string myParentName )
333  : GaudiHandleInfo( std::move( myComponentType ), std::move( myParentName ) ) {}
334 
335 public:
339 
342  bool setTypesAndNames( const std::vector<std::string>& myTypesAndNamesList );
343 
346  const std::vector<std::string> typesAndNames() const;
347 
349  const std::vector<std::string> types() const;
350 
352  const std::vector<std::string> names() const;
353 
356  const std::vector<std::string> getBaseInfos( std::string ( GaudiHandleBase::*pMemFunc )() const ) const;
357 
361  std::string pythonPropertyClassName() const override;
362 
366  std::string pythonRepr() const override;
367 
371  virtual bool push_back( const std::string& myHandleTypeAndName ) = 0;
372 
374  virtual void clear() = 0;
375 
377  virtual bool empty() const = 0;
378 
381  virtual ConstBaseHandleArray getBaseArray() const = 0;
382 
385  virtual BaseHandleArray getBaseArray() = 0;
386 
388  virtual bool retrieved() const = 0;
389 };
390 
392 template <class T>
394 public:
395  //
396  // public nested types
397  //
399  typedef typename HandleVector::value_type value_type;
400  typedef typename HandleVector::size_type size_type;
401  typedef typename HandleVector::reference reference;
402  typedef typename HandleVector::const_reference const_reference;
403  typedef typename HandleVector::iterator iterator;
404  typedef typename HandleVector::const_iterator const_iterator;
405  typedef typename HandleVector::reverse_iterator reverse_iterator;
406  typedef typename HandleVector::const_reverse_iterator const_reverse_iterator;
407 
408 protected:
409  //
410  // Constructors
411  //
416  GaudiHandleArray( const std::vector<std::string>& myTypesAndNamesList, std::string myComponentType,
417  std::string myParentName )
418  : GaudiHandleArrayBase( std::move( myComponentType ), std::move( myParentName ) ) {
419  setTypesAndNames( myTypesAndNamesList );
420  }
421 
426  GaudiHandleArray( const std::string& myComponentType, const std::string& myParentName )
427  : GaudiHandleArrayBase( myComponentType, myParentName ) {}
428 
429 public:
431  GaudiHandleArray& operator=( const std::vector<std::string>& myTypesAndNamesList ) {
432  setTypesAndNames( myTypesAndNamesList );
433  return *this;
434  }
435 
438  for ( auto& h : m_handleArray ) baseArray.push_back( &h );
439  return baseArray;
440  }
441 
444  for ( auto& h : m_handleArray ) baseArray.push_back( &h );
445  return baseArray;
446  }
447 
448  //
449  // Simulate (part of) an std::vector
450  //
451  iterator begin() { return m_handleArray.begin(); }
452 
453  iterator end() { return m_handleArray.end(); }
454 
455  const_iterator begin() const { return m_handleArray.begin(); }
456 
457  const_iterator end() const { return m_handleArray.end(); }
458 
459  const_iterator rbegin() const { return m_handleArray.rbegin(); }
460 
461  const_iterator rend() const { return m_handleArray.rend(); }
462 
463  size_type size() const { return m_handleArray.size(); }
464 
465  void clear() override { m_handleArray.clear(); }
466 
467  bool empty() const override { return m_handleArray.empty(); }
468 
469  T& operator[]( int index ) { return m_handleArray[index]; }
470 
471  const T& operator[]( int index ) const { return m_handleArray[index]; }
472 
474  T* operator[]( const std::string& name ) {
475  auto it = std::find_if( begin(), end(), [&]( const_reference r ) { return r.name() == name; } );
476  return it != end() ? &*it : nullptr;
477  }
478 
480  const T* operator[]( const std::string& name ) const {
481  auto it = std::find_if( begin(), end(), [&]( const_reference r ) { return r.name() == name; } );
482  return it != end() ? &*it : nullptr;
483  }
484 
487  using GaudiHandleArrayBase::push_back; // avoid compiler warning
488  virtual bool push_back( const T& myHandle ) {
489  m_handleArray.push_back( myHandle );
490  return true;
491  }
492 
496  for ( auto& i : *this ) {
497  // stop at first failure
498  if ( i.retrieve().isFailure() ) {
499  sc = StatusCode::FAILURE;
500  break;
501  }
502  }
503  if ( sc ) { m_retrieved = true; }
504  return sc;
505  }
506 
510  for ( auto& i : *this ) {
511  // continue trying to release other tools even if we fail...
512  if ( i.release().isFailure() ) sc = StatusCode::FAILURE;
513  }
514  return sc;
515  }
516 
518  virtual bool retrieved() const override { return m_retrieved; }
519 
520 private:
521  //
522  // Private data members
523  //
525  bool m_retrieved{false};
526 };
527 
528 // Easy printing out of Handles and HandleArrays
529 // It prints <propertyName> = <HandleType>( <HandleType(s)AndName(s)> )
530 std::ostream& operator<<( std::ostream& os, const GaudiHandleInfo& handle );
531 
532 #endif // ! GAUDIKERNEL_GAUDIHANDLE_H
GaudiHandle & operator=(const GaudiHandle &other)
Assignment operator for correct ref-counting.
Definition: GaudiHandle.h:201
HandleVector::const_reference const_reference
Definition: GaudiHandle.h:402
#define UNLIKELY(x)
Definition: Kernel.h:96
const T * operator[](const std::string &name) const
Get const pointer (!) to ToolHandle by instance name.
Definition: GaudiHandle.h:480
HandleVector::value_type value_type
Definition: GaudiHandle.h:399
Handle to be used in lieu of naked pointers to gaudis.
Definition: GaudiHandle.h:163
StatusCode release() const
Release the component.
Definition: GaudiHandle.h:224
void clear() override
Clear the list of handles.
Definition: GaudiHandle.h:465
std::string getDefaultType()
Helper function to get default type string from the class type.
Definition: GaudiHandle.h:279
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:251
bool empty() const
Check if the handle has been set to empty string (i.e.
Definition: GaudiHandle.h:124
HandleVector::iterator iterator
Definition: GaudiHandle.h:403
GaudiHandleArrayBase::BaseHandleArray getBaseArray() override
Get a read-write vector of GaudiHandleBase* pointing to the real handles.
Definition: GaudiHandle.h:436
void setTypeAndName(std::string myTypeAndName)
The component "type/name" string.
Definition: GaudiHandle.cpp:9
const std::string & propertyName() const
name as used in declareProperty(name,gaudiHandle)
Definition: GaudiHandle.h:47
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:174
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
std::vector< T > HandleVector
Definition: GaudiHandle.h:398
std::string typeAndName() const
The full type and name: "type/name".
Definition: GaudiHandle.h:115
HandleVector::const_reverse_iterator const_reverse_iterator
Definition: GaudiHandle.h:406
void setComponentType(const std::string &componentType)
The component type.
Definition: GaudiHandle.h:68
std::string getDefaultName()
Definition: GaudiHandle.h:281
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
size_type size() const
Definition: GaudiHandle.h:463
STL namespace.
StatusCode retrieve() const
Retrieve the component.
Definition: GaudiHandle.h:212
GaudiHandle(std::string myTypeAndName, std::string myComponentType, std::string myParentName)
Definition: GaudiHandle.h:168
void setDefaultType()
Helper function to set default type from the class type T.
Definition: GaudiHandle.h:306
std::string m_componentType
Definition: GaudiHandle.h:77
GaudiHandleArray(const std::vector< std::string > &myTypesAndNamesList, std::string myComponentType, std::string myParentName)
Generic constructor.
Definition: GaudiHandle.h:416
HandleVector::size_type size_type
Definition: GaudiHandle.h:400
GaudiHandleArray & operator=(const std::vector< std::string > &myTypesAndNamesList)
Set the array of GaudiHandles from typeAndNames given in vector of strings.
Definition: GaudiHandle.h:431
bool empty() const override
Return whether the list of tools is empty.
Definition: GaudiHandle.h:467
HandleVector::reference reference
Definition: GaudiHandle.h:401
virtual bool push_back(const T &myHandle)
Definition: GaudiHandle.h:488
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:190
void setParentName(const std::string &parent)
The name of the parent.
Definition: GaudiHandle.h:71
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
const T & operator[](int index) const
Definition: GaudiHandle.h:471
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:34
std::add_const_t< T > * operator->() const
Definition: GaudiHandle.h:272
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:300
virtual std::string pythonRepr() const =0
Python representation of handle, i.e.
HandleVector m_handleArray
Definition: GaudiHandle.h:524
StatusCode retrieve()
Retrieve all tools.
Definition: GaudiHandle.h:494
const_iterator rend() const
Definition: GaudiHandle.h:461
iterator begin()
Definition: GaudiHandle.h:451
std::remove_const_t< T > * nonConst(T *p)
Cast a pointer to a non const type.
Definition: GaudiHandle.h:20
bool setTypesAndNames(const std::vector< std::string > &myTypesAndNamesList)
Set the array of handles from list of "type/name" strings in <myTypesAndNamesList>.
Definition: GaudiHandle.cpp:53
const_iterator end() const
Definition: GaudiHandle.h:457
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
const std::string & parentName() const
The name of the parent.
Definition: GaudiHandle.h:53
virtual bool retrieved() const override
has Array been retreived?
Definition: GaudiHandle.h:518
T * get()
Return the wrapped pointer, not calling retrieve() if null.
Definition: GaudiHandle.h:248
GaudiHandleArrayBase::ConstBaseHandleArray getBaseArray() const override
Get a read-only vector of const GaudiHandleBase* pointing to the real handles.
Definition: GaudiHandle.h:442
std::string m_typeAndName
Definition: GaudiHandle.h:151
def end
Definition: IOTest.py:113
const_iterator rbegin() const
Definition: GaudiHandle.h:459
std::vector< const GaudiHandleBase * > ConstBaseHandleArray
Definition: GaudiHandle.h:338
T move(T... args)
T * operator->()
Definition: GaudiHandle.h:261
void assertObject() const
Load the pointer to the component.
Definition: GaudiHandle.h:310
const std::string & componentType() const
Definition: GaudiHandle.h:44
T find_if(T... args)
HandleVector::const_iterator const_iterator
Definition: GaudiHandle.h:404
Base class of array's of various gaudihandles.
Definition: GaudiHandle.h:330
virtual StatusCode release(T *comp) const
Release the component.
Definition: GaudiHandle.h:292
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:254
std::string type() const
The concrete component class name: the part before the '/'.
Definition: GaudiHandle.cpp:11
GaudiHandleInfo(std::string myComponentType, std::string myParentName)
Some basic information and helper functions shared between various handles/arrays.
Definition: GaudiHandle.h:35
void setPropertyName(std::string propName)
set name as used in declareProperty(name,gaudiHandle).
Definition: GaudiHandle.h:50
HandleVector::reverse_iterator reverse_iterator
Definition: GaudiHandle.h:405
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:337
constexpr static const auto FAILURE
Definition: StatusCode.h:86
std::ostream & operator<<(std::ostream &os, const GaudiHandleInfo &handle)
Definition: GaudiHandle.cpp:95
iterator end()
Definition: GaudiHandle.h:453
T & operator[](int index)
Definition: GaudiHandle.h:469
const_iterator begin() const
Definition: GaudiHandle.h:455
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
Definition: GaudiHandle.h:89
AttribStringParser::Iterator begin(const AttribStringParser &parser)
GaudiHandleArrayBase(std::string myComponentType, std::string myParentName)
Definition: GaudiHandle.h:332
T * operator[](const std::string &name)
Get pointer (!) to ToolHandle by instance name.
Definition: GaudiHandle.h:474
#define GAUDI_API
Definition: Kernel.h:71
STL class.
GaudiHandleBase(std::string myTypeAndName, std::string myComponentType, std::string myParentName)
Create a handle ('smart pointer') to a gaudi component.
Definition: GaudiHandle.h:105
std::string m_propertyName
Definition: GaudiHandle.h:78
GaudiHandle(const GaudiHandle &other)
Copy constructor needed for correct ref-counting.
Definition: GaudiHandle.h:182
bool isValid() const
Check if the handle is valid (try to retrive the object is not done yet).
Definition: GaudiHandle.h:235
T is the concrete handle type, e.g.
Definition: GaudiHandle.h:393
std::string m_parentName
Definition: GaudiHandle.h:79
StatusCode release()
Release all tools.
Definition: GaudiHandle.h:508
GaudiHandleArray(const std::string &myComponentType, const std::string &myParentName)
Constructor creating an empty array.
Definition: GaudiHandle.h:426