| # Gaudi Framework, version v20r3
Generated: 24 Nov 2008

# GaudiHandle.h

Go to the documentation of this file.

    00001 #ifndef GAUDIKERNEL_GAUDIHANDLE_H
    00002 #define GAUDIKERNEL_GAUDIHANDLE_H
    00003
    00004 //Includes
    00005 #include "GaudiKernel/IInterface.h"
    00006 #include "GaudiKernel/System.h"
    00007 #include "GaudiKernel/GaudiException.h"
    00008
    00009 #include <string>
    00010 #include <vector>
    00011 #include <stdexcept>
    00012 #include <iostream>
    00013
    00014 class GaudiHandleInfo {
    00015 protected:
    00024   GaudiHandleInfo( const std::string& myComponentType, const std::string& myParentName )
    00025     : m_componentType(myComponentType), m_parentName(myParentName)
    00026   {}
    00027 public:
    00029   virtual ~GaudiHandleInfo() {}
    00030   //
    00031   // Public member functions
    00032   //
    00033   const std::string& componentType() const {
    00034      return m_componentType;
    00035   }
    00036
    00038   const std::string& propertyName() const {
    00039      return m_propertyName;
    00040   }
    00041
    00043   void setPropertyName( const std::string& propName ) {
    00044     m_propertyName = propName;
    00045   }
    00046
    00048   const std::string& parentName() const {
    00049     return m_parentName;
    00050   }
    00051
    00055   virtual const std::string pythonPropertyClassName() const = 0;
    00056
    00061   virtual const std::string pythonRepr() const = 0;
    00062
    00063 private:
    00064   //
    00065   // Data members
    00066   //
    00067   std::string m_componentType; // e.g.: "PublicTool","PrivateTool","Service"
    00068   std::string m_propertyName;  // name as used in declareProperty(name,gaudiHandle)
    00069   std::string m_parentName;    // name of the parent having this handle as a member
    00070 };
    00071
    00072
    00080 class GaudiHandleBase : public GaudiHandleInfo {
    00081   //
    00082   // Ctors etc
    00083   //
    00084 protected:
    00096   GaudiHandleBase( const std::string& myTypeAndName, const std::string& myComponentType,
    00097                    const std::string& myParentName )
    00098     : GaudiHandleInfo(myComponentType,myParentName)
    00099   {
    00100     setTypeAndName(myTypeAndName);
    00101   }
    00102 public:
    00103   //
    00104   // Public member functions
    00105   //
    00107   std::string typeAndName() const {
    00108      return m_typeAndName;
    00109   }
    00110
    00112   std::string type() const;
    00113
    00115   std::string name() const;
    00116
    00118   bool empty() const {
    00119     return m_typeAndName.empty();
    00120   }
    00121
    00123   void setTypeAndName( const std::string& myTypeAndName );
    00124
    00126   void setName( const std::string& myName );
    00127
    00131   const std::string pythonPropertyClassName() const;
    00132
    00134   const std::string messageName() const;
    00135
    00139   virtual const std::string pythonRepr() const;
    00140
    00141 private:
    00142   //
    00143   // Data member
    00144   //
    00145   std::string m_typeAndName;   // the full type and name: "type/name"
    00146 };
    00147
    00148
    00157 template< class T >
    00158 class GaudiHandle : public GaudiHandleBase {
    00159   //
    00160   // Constructors etc.
    00161   //
    00162 protected:
    00163   GaudiHandle( const std::string& myTypeAndName, const std::string& myComponentType,
    00164                const std::string& myParentName )
    00165     : GaudiHandleBase(myTypeAndName, myComponentType, myParentName), m_pObject(0)
    00166   {}
    00167
    00168 public:
    00170   GaudiHandle( const GaudiHandle& other )
    00171     : GaudiHandleBase( other ) {
    00172     m_pObject = other.m_pObject;
    00173     if ( m_pObject ) m_pObject->addRef();
    00174   }
    00175
    00177   GaudiHandle& operator=( const GaudiHandle& other ) {
    00178     GaudiHandleBase::operator=( other );
    00179     // release any current tool
    00180     release().ignore();
    00181     m_pObject = other.m_pObject;
    00182     // update ref-counting
    00183     if ( m_pObject ) m_pObject->addRef();
    00184     return *this;
    00185   }
    00186
    00188   StatusCode retrieve() const { // not really const, because it updates m_pObject
    00189     if ( m_pObject && release().isFailure() ) return StatusCode::FAILURE;
    00190     if ( retrieve( m_pObject ).isFailure() ) {
    00191       m_pObject = 0;
    00192       return StatusCode::FAILURE;
    00193     }
    00194     return StatusCode::SUCCESS;
    00195   }
    00196
    00198   StatusCode release() const { // not really const, because it updates m_pObject
    00199     if ( m_pObject ) {
    00200       StatusCode sc = release( m_pObject );
    00201       m_pObject = 0;
    00202       return sc;
    00203     }
    00204     return StatusCode::SUCCESS;
    00205   }
    00206
    00209   operator bool() const { // not really const, because it may update m_pObject
    00210     return getObject();
    00211   }
    00212
    00213   T& operator*() {
    00214     assertObject();
    00215     return *m_pObject;
    00216   }
    00217
    00218   T* operator->() {
    00219     assertObject();
    00220     return m_pObject;
    00221   }
    00222
    00223   T& operator*() const { // not really const, because it may update m_pObject
    00224     assertObject();
    00225     return *m_pObject;
    00226   }
    00227
    00228   T* operator->() const { // not really const, because it may update m_pObject
    00229     assertObject();
    00230     return m_pObject;
    00231   }
    00232
    00234   std::string getDefaultType() {
    00235     return System::typeinfoName( typeid(T) );
    00236   }
    00237
    00238   std::string getDefaultName() {
    00239     std::string defName = GaudiHandleBase::type();
    00240     if ( defName.empty() ) defName = getDefaultType();
    00241     return defName;
    00242   }
    00243
    00244 protected:
    00246   virtual StatusCode retrieve( T*& ) const = 0; // not really const, because it updates m_pObject
    00247
    00250   virtual StatusCode release( T* comp ) const { // not really const, because it updates m_pObject
    00251     comp->release();
    00252     return StatusCode::SUCCESS;
    00253   }
    00254
    00255 private:
    00257   void setDefaultTypeAndName() {
    00258     const std::string& myType = getDefaultType();
    00259     GaudiHandleBase::setTypeAndName(myType+'/'+myType);
    00260   }
    00261
    00263   void setDefaultType() {
    00264     GaudiHandleBase::setTypeAndName( getDefaultType() );
    00265   }
    00266
    00268   bool getObject() const { // not really const, because it may update m_pObject
    00269     return m_pObject || retrieve().isSuccess();
    00270   }
    00271
    00274   void assertObject() const { // not really const, because it may update m_pObject
    00275     if ( !getObject() ) {
    00276       throw GaudiException("Failed to retrieve " + componentType() + ": " + typeAndName(),
    00277                            componentType() + " retrieve", StatusCode::FAILURE);
    00278     }
    00279   }
    00280   //
    00281   // Data members
    00282   //
    00283   mutable T* m_pObject;
    00284 };
    00285
    00286
    00293 class GaudiHandleArrayBase : public GaudiHandleInfo {
    00294 protected:
    00295   GaudiHandleArrayBase( const std::string& myComponentType, const std::string& myParentName )
    00296     : GaudiHandleInfo(myComponentType,myParentName)
    00297   {}
    00298 public:
    00299   typedef std::vector< GaudiHandleBase* > BaseHandleArray;
    00300   typedef std::vector< const GaudiHandleBase* > ConstBaseHandleArray;
    00301
    00304   bool setTypesAndNames( const std::vector< std::string >& myTypesAndNamesList );
    00305
    00308   const std::vector< std::string > typesAndNames() const;
    00309
    00311   const std::vector< std::string > types() const;
    00312
    00314   const std::vector< std::string > names() const;
    00315
    00318   const std::vector< std::string > getBaseInfos( std::string (GaudiHandleBase::*pMemFunc)() const ) const;
    00319
    00323   virtual const std::string pythonPropertyClassName() const;
    00324
    00328   virtual const std::string pythonRepr() const;
    00329
    00333   virtual bool push_back( const std::string& myHandleTypeAndName ) = 0;
    00334
    00336   virtual void clear() = 0;
    00337
    00339   virtual bool empty() const = 0;
    00340
    00343   virtual ConstBaseHandleArray getBaseArray() const = 0;
    00344
    00347   virtual BaseHandleArray getBaseArray() = 0;
    00348 };
    00349
    00350
    00352 template <class T>
    00353 class GaudiHandleArray : public GaudiHandleArrayBase {
    00354 public:
    00355   //
    00356   // public nested types
    00357   //
    00358   typedef std::vector< T > HandleVector;
    00359   typedef typename HandleVector::value_type value_type;
    00360   typedef typename HandleVector::size_type size_type;
    00361   typedef typename HandleVector::reference reference;
    00362   typedef typename HandleVector::const_reference const_reference;
    00363   typedef typename HandleVector::iterator iterator;
    00364   typedef typename HandleVector::const_iterator const_iterator;
    00365   typedef typename HandleVector::reverse_iterator reverse_iterator;
    00366   typedef typename HandleVector::const_reverse_iterator const_reverse_iterator;
    00367
    00368 protected:
    00369   //
    00370   // Constructors
    00371   //
    00376   GaudiHandleArray( const std::vector< std::string >& myTypesAndNamesList,
    00377                     const std::string& myComponentType, const std::string& myParentName  )
    00378     : GaudiHandleArrayBase(myComponentType,myParentName)
    00379   {
    00380     GaudiHandleArray::setTypesAndNames( myTypesAndNamesList );
    00381   }
    00382
    00387   GaudiHandleArray( const std::string& myComponentType, const std::string& myParentName  )
    00388     : GaudiHandleArrayBase(myComponentType,myParentName)
    00389   {}
    00390
    00391 public:
    00392   virtual ~GaudiHandleArray() {};
    00393
    00395   GaudiHandleArray& operator=( const std::vector< std::string >& myTypesAndNamesList ) {
    00396     setTypesAndNames( myTypesAndNamesList );
    00397     return *this;
    00398   }
    00399
    00400   virtual GaudiHandleArrayBase::BaseHandleArray getBaseArray() {
    00401     GaudiHandleArrayBase::BaseHandleArray baseArray;
    00402     iterator it = begin(), itEnd = end();
    00403     for (  ; it != itEnd; ++it ) baseArray.push_back( &*it );
    00404     return baseArray;
    00405   }
    00406
    00407   virtual GaudiHandleArrayBase::ConstBaseHandleArray getBaseArray() const {
    00408     GaudiHandleArrayBase::ConstBaseHandleArray baseArray;
    00409     const_iterator it = begin(), itEnd = end();
    00410     for (  ; it != itEnd; ++it ) baseArray.push_back( &*it );
    00411     return baseArray;
    00412   }
    00413
    00414   //
    00415   // Simulate (part of) an std::vector
    00416   //
    00417   iterator begin() {
    00418     return m_handleArray.begin();
    00419   }
    00420
    00421   iterator end() {
    00422     return m_handleArray.end();
    00423   }
    00424
    00425   const_iterator begin() const {
    00426     return m_handleArray.begin();
    00427   }
    00428
    00429   const_iterator end() const {
    00430     return m_handleArray.end();
    00431   }
    00432
    00433   const_iterator rbegin() const {
    00434     return m_handleArray.rbegin();
    00435   }
    00436
    00437   const_iterator rend() const {
    00438     return m_handleArray.rend();
    00439   }
    00440
    00441   size_type size() const {
    00442     return m_handleArray.size();
    00443   }
    00444
    00445   virtual void clear() {
    00446     m_handleArray.clear();
    00447   }
    00448
    00449   virtual bool empty() const {
    00450     return m_handleArray.empty();
    00451   }
    00452
    00453   T& operator[]( int index ) {
    00454     return m_handleArray[index];
    00455   }
    00456
    00457   const T& operator[]( int index ) const {
    00458     return m_handleArray[index];
    00459   }
    00460
    00462   T* operator[]( const std::string& name ) {
    00463     iterator it = begin(), itEnd = end();
    00464     for ( ; it != itEnd; ++it ) {
    00465       if ( it->name() == name ) return &*it;
    00466     }
    00467     // not found
    00468     return 0;
    00469   }
    00470
    00472   const T* operator[]( const std::string& name ) const {
    00473     const_iterator it = begin(), itEnd = end();
    00474     for ( ; it != itEnd; ++it ) {
    00475       if ( it->name() == name ) return &*it;
    00476     }
    00477     // not found
    00478     return 0;
    00479   }
    00480
    00483   using GaudiHandleArrayBase::push_back; // avoid compiler warning
    00484   virtual bool push_back( const T& myHandle ) {
    00485     m_handleArray.push_back( myHandle );
    00486     return true;
    00487   }
    00488
    00490   StatusCode retrieve() {
    00491     iterator it = begin(), itEnd = end();
    00492     for ( ; it != itEnd; ++it ) {
    00493       if ( it->retrieve().isFailure() ) {
    00494         // stop at first failure
    00495         return StatusCode::FAILURE;
    00496       }
    00497     }
    00498     return StatusCode::SUCCESS;
    00499   }
    00500
    00502   StatusCode release() {
    00503     StatusCode sc = StatusCode::SUCCESS;
    00504     iterator it = begin(), itEnd = end();
    00505     for ( ; it != itEnd; ++it ) {
    00506       if ( it->release().isFailure() ) {
    00507         // continue trying to release other tools
    00508         sc = StatusCode::FAILURE;
    00509       }
    00510     }
    00511     return sc;
    00512   }
    00513
    00514 private:
    00515   //
    00516   // Private data members
    00517   //
    00518   HandleVector m_handleArray;
    00519 };
    00520
    00521 // Easy printing out of Handles and HandleArrays
    00522 // It prints <propertyName> = <HandleType>( <HandleType(s)AndName(s)> )
    00523 std::ostream& operator<<( std::ostream& os, const GaudiHandleInfo& handle );
    00524
    00525 #endif // ! GAUDIKERNEL_GAUDIHANDLE_H