GaudiHandle.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_GAUDIHANDLE_H
2 #define GAUDIKERNEL_GAUDIHANDLE_H
3 
4 //Includes
5 #include "GaudiKernel/IInterface.h"
6 #include "GaudiKernel/System.h"
7 #include "GaudiKernel/GaudiException.h"
8 
9 #include <string>
10 #include <algorithm>
11 #include <vector>
12 #include <stdexcept>
13 #include <iostream>
14 
16 protected:
25  GaudiHandleInfo( std::string myComponentType, std::string myParentName )
26  : m_componentType(std::move(myComponentType)), m_parentName(std::move(myParentName))
27  {}
28 public:
30  virtual ~GaudiHandleInfo() = default;
31  //
32  // Public member functions
33  //
34  const std::string& componentType() const {
35  return m_componentType;
36  }
37 
39  const std::string& propertyName() const {
40  return m_propertyName;
41  }
42 
44  void setPropertyName( std::string propName ) {
45  m_propertyName = std::move(propName);
46  }
47 
49  const std::string& parentName() const {
50  return m_parentName;
51  }
52 
56  virtual std::string pythonPropertyClassName() const = 0;
57 
62  virtual std::string pythonRepr() const = 0;
63 
64 private:
65  //
66  // Data members
67  //
68  std::string m_componentType; // e.g.: "PublicTool","PrivateTool","Service"
69  std::string m_propertyName; // name as used in declareProperty(name,gaudiHandle)
70  std::string m_parentName; // name of the parent having this handle as a member
71 };
72 
73 
82  //
83  // Ctors etc
84  //
85 protected:
97  GaudiHandleBase( std::string myTypeAndName, std::string myComponentType,
98  std::string myParentName )
99  : GaudiHandleInfo(std::move(myComponentType),std::move(myParentName))
100  {
101  setTypeAndName(std::move(myTypeAndName));
102  }
103 public:
104  //
105  // Public member functions
106  //
108  std::string typeAndName() const {
109  return m_typeAndName;
110  }
111 
113  std::string type() const;
114 
116  std::string name() const;
117 
119  bool empty() const {
120  return m_typeAndName.empty();
121  }
122 
124  void setTypeAndName( std::string myTypeAndName );
125 
127  void setName( const std::string& myName );
128 
132  std::string pythonPropertyClassName() const;
133 
135  std::string messageName() const;
136 
140  virtual std::string pythonRepr() const;
141 
142 private:
143  //
144  // Data member
145  //
146  std::string m_typeAndName; // the full type and name: "type/name"
147 };
148 
149 
158 template< class T >
159 class GAUDI_API GaudiHandle: public GaudiHandleBase {
160  //
161  // Constructors etc.
162  //
163 protected:
164  GaudiHandle( std::string myTypeAndName, std::string myComponentType,
165  std::string myParentName )
166  : GaudiHandleBase(std::move(myTypeAndName), std::move(myComponentType), std::move(myParentName))
167  {}
168 
169 public:
171  GaudiHandle( const GaudiHandle& other )
172  : GaudiHandleBase( other ) {
173  m_pObject = other.m_pObject;
174  if ( m_pObject ) m_pObject->addRef();
175  }
176 
178  GaudiHandle& operator=( const GaudiHandle& other ) {
179  GaudiHandleBase::operator=( other );
180  // release any current tool
181  release().ignore();
182  m_pObject = other.m_pObject;
183  // update ref-counting
184  if ( m_pObject ) m_pObject->addRef();
185  return *this;
186  }
187 
189  StatusCode retrieve() const { // not really const, because it updates m_pObject
190  if ( m_pObject && release().isFailure() ) return StatusCode::FAILURE;
191  if ( retrieve( m_pObject ).isFailure() ) {
192  m_pObject = nullptr;
193  return StatusCode::FAILURE;
194  }
195  return StatusCode::SUCCESS;
196  }
197 
199  StatusCode release() const { // not really const, because it updates m_pObject
200  if ( m_pObject ) {
201  StatusCode sc = release( m_pObject );
202  m_pObject = nullptr;
203  return sc;
204  }
205  return StatusCode::SUCCESS;
206  }
207 
209  bool isValid() const { // not really const, because it may update m_pObject
210  return m_pObject || retrieve().isSuccess();
211  }
212 
215  operator bool() const { // not really const, because it may update m_pObject
216  return isValid();
217  }
218 
220  T* get() const {
221  return m_pObject;
222  }
223 
225  bool isSet() const {
226  return get();
227  }
228 
229  T& operator*() {
230  assertObject();
231  return *m_pObject;
232  }
233 
234  T* operator->() {
235  assertObject();
236  return m_pObject;
237  }
238 
239  T& operator*() const { // not really const, because it may update m_pObject
240  assertObject();
241  return *m_pObject;
242  }
243 
244  T* operator->() const { // not really const, because it may update m_pObject
245  assertObject();
246  return m_pObject;
247  }
248 
250  std::string getDefaultType() {
251  return System::typeinfoName( typeid(T) );
252  }
253 
254  std::string getDefaultName() {
255  std::string defName = GaudiHandleBase::type();
256  if ( defName.empty() ) defName = getDefaultType();
257  return defName;
258  }
259 
260 protected:
262  virtual StatusCode retrieve( T*& ) const = 0; // not really const, because it updates m_pObject
263 
266  virtual StatusCode release( T* comp ) const { // not really const, because it updates m_pObject
267  comp->release();
268  return StatusCode::SUCCESS;
269  }
270 
271 private:
273  void setDefaultTypeAndName() {
274  const std::string& myType = getDefaultType();
275  GaudiHandleBase::setTypeAndName(myType+'/'+myType);
276  }
277 
279  void setDefaultType() {
280  GaudiHandleBase::setTypeAndName( getDefaultType() );
281  }
282 
285  void assertObject() const { // not really const, because it may update m_pObject
286  if ( !isValid() ) {
287  throw GaudiException("Failed to retrieve " + componentType() + ": " + typeAndName(),
288  componentType() + " retrieve", StatusCode::FAILURE);
289  }
290  }
291  //
292  // Data members
293  //
294  mutable T* m_pObject = nullptr;
295 };
296 
297 
305 protected:
306  GaudiHandleArrayBase( std::string myComponentType, std::string myParentName )
307  : GaudiHandleInfo(std::move(myComponentType),std::move(myParentName))
308  {}
309 public:
310  typedef std::vector< GaudiHandleBase* > BaseHandleArray;
311  typedef std::vector< const GaudiHandleBase* > ConstBaseHandleArray;
312 
315  bool setTypesAndNames( const std::vector< std::string >& myTypesAndNamesList );
316 
319  const std::vector< std::string > typesAndNames() const;
320 
322  const std::vector< std::string > types() const;
323 
325  const std::vector< std::string > names() const;
326 
329  const std::vector< std::string > getBaseInfos( std::string (GaudiHandleBase::*pMemFunc)() const ) const;
330 
334  std::string pythonPropertyClassName() const override;
335 
339  std::string pythonRepr() const override;
340 
344  virtual bool push_back( const std::string& myHandleTypeAndName ) = 0;
345 
347  virtual void clear() = 0;
348 
350  virtual bool empty() const = 0;
351 
354  virtual ConstBaseHandleArray getBaseArray() const = 0;
355 
358  virtual BaseHandleArray getBaseArray() = 0;
359 };
360 
361 
363 template <class T>
365 public:
366  //
367  // public nested types
368  //
369  typedef std::vector< T > HandleVector;
370  typedef typename HandleVector::value_type value_type;
371  typedef typename HandleVector::size_type size_type;
372  typedef typename HandleVector::reference reference;
373  typedef typename HandleVector::const_reference const_reference;
374  typedef typename HandleVector::iterator iterator;
375  typedef typename HandleVector::const_iterator const_iterator;
376  typedef typename HandleVector::reverse_iterator reverse_iterator;
377  typedef typename HandleVector::const_reverse_iterator const_reverse_iterator;
378 
379 protected:
380  //
381  // Constructors
382  //
387  GaudiHandleArray( const std::vector< std::string >& myTypesAndNamesList,
388  std::string myComponentType, std::string myParentName )
389  : GaudiHandleArrayBase(std::move(myComponentType),std::move(myParentName))
390  {
391  setTypesAndNames( myTypesAndNamesList );
392  }
393 
398  GaudiHandleArray( const std::string& myComponentType, const std::string& myParentName )
399  : GaudiHandleArrayBase(myComponentType,myParentName)
400  {}
401 
402 public:
403  virtual ~GaudiHandleArray() = default;
404 
406  GaudiHandleArray& operator=( const std::vector< std::string >& myTypesAndNamesList ) {
407  setTypesAndNames( myTypesAndNamesList );
408  return *this;
409  }
410 
413  iterator it = begin(), itEnd = end();
414  for ( ; it != itEnd; ++it ) baseArray.push_back( &*it );
415  return baseArray;
416  }
417 
420  const_iterator it = begin(), itEnd = end();
421  for ( ; it != itEnd; ++it ) baseArray.push_back( &*it );
422  return baseArray;
423  }
424 
425  //
426  // Simulate (part of) an std::vector
427  //
428  iterator begin() {
429  return m_handleArray.begin();
430  }
431 
432  iterator end() {
433  return m_handleArray.end();
434  }
435 
436  const_iterator begin() const {
437  return m_handleArray.begin();
438  }
439 
440  const_iterator end() const {
441  return m_handleArray.end();
442  }
443 
444  const_iterator rbegin() const {
445  return m_handleArray.rbegin();
446  }
447 
448  const_iterator rend() const {
449  return m_handleArray.rend();
450  }
451 
452  size_type size() const {
453  return m_handleArray.size();
454  }
455 
456  void clear() override {
457  m_handleArray.clear();
458  }
459 
460  bool empty() const override {
461  return m_handleArray.empty();
462  }
463 
464  T& operator[]( int index ) {
465  return m_handleArray[index];
466  }
467 
468  const T& operator[]( int index ) const {
469  return m_handleArray[index];
470  }
471 
473  T* operator[]( const std::string& name ) {
474  auto it = std::find_if(begin(),end(),[&](const_reference r) {
475  return r.name() == name;
476  } );
477  return it != end() ? &*it : nullptr;
478  }
479 
481  const T* operator[]( const std::string& name ) const {
482  auto it = std::find_if(begin(),end(),[&](const_reference r) {
483  return r.name() == name;
484  } );
485  return it != end() ? &*it : nullptr;
486  }
487 
490  using GaudiHandleArrayBase::push_back; // avoid compiler warning
491  virtual bool push_back( const T& myHandle ) {
492  m_handleArray.push_back( myHandle );
493  return true;
494  }
495 
497  StatusCode retrieve() {
498  for (auto& i : *this) {
499  // stop at first failure
500  if ( i.retrieve().isFailure() ) return StatusCode::FAILURE;
501  }
502  return StatusCode::SUCCESS;
503  }
504 
506  StatusCode release() {
508  for (auto& i : *this ) {
509  // continue trying to release other tools even if we fail...
510  if ( i.release().isFailure() ) sc = StatusCode::FAILURE;
511  }
512  return sc;
513  }
514 
515 private:
516  //
517  // Private data members
518  //
519  HandleVector m_handleArray;
520 };
521 
522 // Easy printing out of Handles and HandleArrays
523 // It prints <propertyName> = <HandleType>( <HandleType(s)AndName(s)> )
524 std::ostream& operator<<( std::ostream& os, const GaudiHandleInfo& handle );
525 
526 #endif // ! GAUDIKERNEL_GAUDIHANDLE_H
Handle to be used in lieu of naked pointers to gaudis.
Definition: GaudiHandle.h:159
Define general base for Gaudi exception.
void setTypeAndName(std::string myTypeAndName)
The component "type/name" string.
Definition: GaudiHandle.cpp:9
std::vector< const GaudiHandleBase * > ConstBaseHandleArray
Definition: GaudiHandle.h:311
#define GAUDI_API
Definition: Kernel.h:107
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:299
virtual ConstBaseHandleArray getBaseArray() const =0
Get a read-only vector of const GaudiHandleBase* pointing to the real handles.
STL namespace.
virtual std::string pythonRepr() const =0
Python representation of handle, i.e.
std::vector< GaudiHandleBase * > BaseHandleArray
Definition: GaudiHandle.h:310
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
bool setTypesAndNames(const std::vector< std::string > &myTypesAndNamesList)
Set the array of handles from list of "type/name" strings in .
Definition: GaudiHandle.cpp:63
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
virtual void clear()=0
Clear the list of handles.
Base class of array's of various gaudihandles.
Definition: GaudiHandle.h:304
virtual std::string pythonPropertyClassName() const =0
The python class name for the property in the genconf-generated configurables.
virtual bool push_back(const std::string &myHandleTypeAndName)=0
Add a handle to the array with "type/name" given in .
virtual bool empty() const =0
Return whether the list of tools is empty.
std::string type() const
The concrete component class name: the part before the '/'.
Definition: GaudiHandle.cpp:13
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
Definition: GaudiHandle.h:81
std::string typeAndName() const
The full type and name: "type/name".
Definition: GaudiHandle.h:108
std::ostream & operator<<(std::ostream &os, const GaudiHandleInfo &handle)
list i
Definition: ana.py:128
const std::string & componentType() const
Definition: GaudiHandle.h:34
TO * reference(FROM *from)
Definition: KeyedObject.cpp:20
string type
Definition: gaudirun.py:151
T is the concrete handle type, e.g.
Definition: GaudiHandle.h:364