00001 #ifndef GAUDIKERNEL_GAUDIHANDLE_H
00002 #define GAUDIKERNEL_GAUDIHANDLE_H
00003
00004
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
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
00066
00067 std::string m_componentType;
00068 std::string m_propertyName;
00069 std::string m_parentName;
00070 };
00071
00072
00080 class GaudiHandleBase : public GaudiHandleInfo {
00081
00082
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
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
00144
00145 std::string m_typeAndName;
00146 };
00147
00148
00157 template< class T >
00158 class GaudiHandle : public GaudiHandleBase {
00159
00160
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
00180 release().ignore();
00181 m_pObject = other.m_pObject;
00182
00183 if ( m_pObject ) m_pObject->addRef();
00184 return *this;
00185 }
00186
00188 StatusCode retrieve() const {
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 {
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 {
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 {
00224 assertObject();
00225 return *m_pObject;
00226 }
00227
00228 T* operator->() const {
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;
00247
00250 virtual StatusCode release( T* comp ) const {
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 {
00269 return m_pObject || retrieve().isSuccess();
00270 }
00271
00274 void assertObject() const {
00275 if ( !getObject() ) {
00276 throw GaudiException("Failed to retrieve " + componentType() + ": " + typeAndName(),
00277 componentType() + " retrieve", StatusCode::FAILURE);
00278 }
00279 }
00280
00281
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
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
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
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
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
00478 return 0;
00479 }
00480
00483 using GaudiHandleArrayBase::push_back;
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
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
00508 sc = StatusCode::FAILURE;
00509 }
00510 }
00511 return sc;
00512 }
00513
00514 private:
00515
00516
00517
00518 HandleVector m_handleArray;
00519 };
00520
00521
00522
00523 std::ostream& operator<<( std::ostream& os, const GaudiHandleInfo& handle );
00524
00525 #endif // ! GAUDIKERNEL_GAUDIHANDLE_H