![]() |
|
|
Generated: 8 Jan 2009 |
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