00001
00002
00003 #ifndef GAUDIUTILS_GETDATA_H
00004 #define GAUDIUTILS_GETDATA_H 1
00005
00006
00007
00008
00009
00010 #include "GaudiKernel/IDataProviderSvc.h"
00011 #include "GaudiKernel/SmartDataPtr.h"
00012 #include "GaudiKernel/IRegistry.h"
00013
00014
00015
00016 #include "GaudiKernel/Range.h"
00017 #include "GaudiKernel/NamedRange.h"
00018
00019
00020
00021 template <class BASE> class GaudiCommon ;
00022
00023 namespace Gaudi
00024 {
00025 namespace Utils
00026 {
00027
00034 template <class TYPE>
00035 struct _GetType
00036 { typedef TYPE* return_type ; };
00037
00039 template <class TYPE>
00040 struct _GetType<TYPE*>
00041 { typedef TYPE* return_type ; };
00042
00044 template <class TYPE>
00045 struct _GetType<TYPE&>
00046 { typedef TYPE* return_type ; };
00047
00049 template <class CONTAINER>
00050 struct _GetType<Gaudi::Range_<CONTAINER> >
00051 { typedef Gaudi::Range_<CONTAINER> return_type ; };
00052
00054 template <class CONTAINER>
00055 struct _GetType<Gaudi::NamedRange_<CONTAINER> >
00056 { typedef Gaudi::NamedRange_<CONTAINER> return_type ; };
00057
00061 template <class TYPE>
00062 inline
00063 typename _GetType<TYPE>::return_type getFromTS(IDataProviderSvc* service ,
00064 const std::string& location ) {
00065 DataObject *obj = NULL;
00066
00067 return service->retrieveObject(location, obj).isSuccess() ?
00068 dynamic_cast<typename _GetType<TYPE>::return_type>(obj) :
00069 NULL;
00070 }
00071
00080 template <class TYPE>
00081 struct GetData
00082 {
00083 public:
00084
00085 typedef TYPE Type ;
00087 typedef typename _GetType<Type>::return_type return_type ;
00088
00089 public:
00090
00098 template <class COMMON>
00099 inline return_type operator()
00100 ( const COMMON& common ,
00101 IDataProviderSvc* service ,
00102 const std::string& location ,
00103 const bool checkData = true) const
00104 {
00105
00106 return_type obj = getFromTS<Type>(service, location);
00107 if (checkData) {
00108 common.Assert(obj, "get():: No valid data at '" + location + "'");
00109 }
00110
00111 if ( common.msgLevel ( MSG::DEBUG ) ) {
00112 common.debug() << "The object of type '"
00113 << System::typeinfoName(typeid(obj))
00114 << "' "
00115 << (obj ? "has been" : "could not be")
00116 << " retrieved from TS at address '"
00117 << location << "'" << endmsg ;
00118 }
00119
00120 return obj ;
00121
00122 }
00123 };
00124
00126 template <class TYPE>
00127 struct GetData<Gaudi::Range_<std::vector<const TYPE*> > >
00128 {
00129 public:
00130
00132 typedef Gaudi::Range_<std::vector<const TYPE*> > Type ;
00133 typedef typename _GetType<Type>::return_type return_type ;
00134
00135 public:
00136
00144 template <class COMMON>
00145 inline return_type operator()
00146 ( const COMMON& common ,
00147 IDataProviderSvc* service ,
00148 const std::string& location ,
00149 const bool checkData = true) const
00150 {
00153 DataObject* object = this -> getData ( service , location ) ;
00154 if ( 0 != object )
00155 {
00157 typedef typename TYPE::Selection Selection_;
00158 const Selection_* sel = dynamic_cast<Selection_*> ( object ) ;
00159 if ( 0 != sel )
00160 {
00161 if ( common.msgLevel ( MSG::DEBUG ) )
00162 { common.debug() << "The object of type '"
00163 << System::typeinfoName(typeid(*object))
00164 << "' has been retrieved from TS at address '"
00165 << location << "'" << endmsg ; }
00166 return make_range ( sel ) ;
00167 }
00169 typedef typename TYPE::Container Container_ ;
00170 const Container_* cnt = dynamic_cast<Container_*> ( object ) ;
00171 if ( 0 != cnt )
00172 {
00173 if ( common.msgLevel ( MSG::DEBUG ) )
00174 { common.debug() << "The object of type '"
00175 << System::typeinfoName(typeid(*object))
00176 << "' has been retrieved from TS at address '"
00177 << location << "'" << endmsg ; }
00178 return make_range ( cnt ) ;
00179 }
00180
00181 if (checkData)
00182 common.Assert ( false , "get():: No valid data at '" + location + "'" ) ;
00183 }
00184
00185 if (checkData)
00186 common.Assert ( false , "get():: No data at '" + location + "'" ) ;
00187
00188 return return_type () ;
00189 }
00190
00191 public:
00192
00193
00194 return_type make_range ( const typename TYPE::Container* cnt ) const
00195 { return 0 == cnt ? return_type() : make_range ( cnt->begin() , cnt->end() ) ; }
00196
00197 return_type make_range ( const typename TYPE::Selection* cnt ) const
00198 { return 0 == cnt ? return_type() : return_type ( cnt->begin() , cnt->end() ) ; }
00199
00205 DataObject* getData ( IDataProviderSvc* service ,
00206 const std::string& location ) const
00207 {
00209 SmartDataObjectPtr getter
00210 ( SmartDataObjectPtr::ObjectLoader::access() ,
00211 service , 0 , location ) ;
00212 return getter.accessData () ;
00213 }
00214
00215 private:
00216
00217 template <class ITERATOR>
00218 return_type make_range
00219 ( ITERATOR first ,
00220 ITERATOR last ) const
00221 {
00222 typename return_type::const_iterator* _begin = reinterpret_cast<typename return_type::const_iterator*>(&first);
00223 typename return_type::const_iterator* _end = reinterpret_cast<typename return_type::const_iterator*>(&last);
00224 return return_type(*_begin, *_end);
00225 }
00226
00227 } ;
00228
00230 template <class TYPE>
00231 struct GetData<Gaudi::NamedRange_<std::vector<const TYPE*> > >
00232 {
00233 public:
00234
00236 typedef Gaudi::NamedRange_<std::vector<const TYPE*> > Type ;
00237 typedef typename _GetType<Type>::return_type return_type ;
00238
00239 public:
00240
00248 template <class COMMON>
00249 inline return_type operator()
00250 ( const COMMON& common ,
00251 IDataProviderSvc* service ,
00252 const std::string& location ,
00253 const bool checkData = true) const
00254 {
00255 return return_type ( m_range( common , service , location, checkData ) , location ) ;
00256 }
00257
00258 public:
00259
00260
00261 return_type make_range ( const typename TYPE::Container* cnt ) const
00262 {
00263 if ( 0 == cnt ) { return return_type() ; }
00264 static const std::string s_empty = "" ;
00265 const IRegistry* reg = cnt->registry() ;
00266 return return_type
00267 ( m_range.make_range ( cnt ) , 0 != reg ? reg->identifier() : s_empty ) ;
00268 }
00269
00270 return_type make_range ( const typename TYPE::Selection* cnt ) const
00271 {
00272 if ( 0 == cnt ) { return return_type() ; }
00273 static const std::string s_empty = "" ;
00274 const IRegistry* reg = cnt->registry() ;
00275 return return_type
00276 ( m_range.make_range ( cnt ) , 0 != reg ? reg->identifier() : s_empty ) ;
00277 }
00278
00284 DataObject* getData ( IDataProviderSvc* service ,
00285 const std::string& location ) const
00286 { return m_range.getData ( service , location ) ; }
00287
00288 private:
00291 GetData<Gaudi::Range_<std::vector<const TYPE*> > > m_range ;
00292
00293 } ;
00294
00296 template <class TYPE>
00297 struct GetData<const TYPE> : public GetData<TYPE> {} ;
00298
00300 template <class TYPE>
00301 struct GetData<TYPE*> : public GetData<TYPE> {} ;
00302
00304 template <class TYPE>
00305 struct GetData<TYPE&> : public GetData<TYPE> {} ;
00306
00315 template <class TYPE>
00316 struct CheckData
00317 {
00318 public:
00319
00326 inline bool operator()
00327 ( IDataProviderSvc* service ,
00328 const std::string& location ) const
00329 {
00331 return getFromTS<TYPE>(service, location);
00332 }
00333
00334 };
00335
00337 template <class TYPE>
00338 struct CheckData<Gaudi::Range_<std::vector<const TYPE*> > >
00339 {
00340 public:
00341
00348 inline bool operator()
00349 ( IDataProviderSvc* service ,
00350 const std::string& location ) const
00351 {
00352 DataObject* object = this->getData( service , location ) ;
00353 if ( 0 == object ) { return false ; }
00354 return
00355 0 != dynamic_cast<typename TYPE::Selection*> ( object ) ||
00356 0 != dynamic_cast<typename TYPE::Container*> ( object ) ;
00357 }
00358
00359 protected:
00360
00366 DataObject* getData ( IDataProviderSvc* service ,
00367 const std::string& location ) const
00368 {
00370 SmartDataObjectPtr getter
00371 ( SmartDataObjectPtr::ObjectLoader::access() ,
00372 service , 0 , location ) ;
00373 return getter.accessData () ;
00374 }
00375
00376 } ;
00377
00379 template <class TYPE>
00380 struct CheckData<Gaudi::NamedRange_<std::vector<const TYPE*> > >
00381 : public CheckData<Gaudi::Range_<std::vector<const TYPE*> > > {} ;
00382
00384 template <class TYPE>
00385 struct CheckData<TYPE*> : public CheckData<TYPE> {} ;
00386
00388 template <class TYPE>
00389 struct CheckData<TYPE&> : public CheckData<TYPE> {} ;
00390
00392 template <class TYPE>
00393 struct CheckData<const TYPE> : public CheckData<TYPE> {} ;
00394
00403 template <class TYPE, class TYPE2>
00404 struct GetOrCreateData
00405 {
00406 private:
00407
00409 typedef GetData<TYPE> Getter ;
00410
00411 public:
00412
00413 typedef typename Getter::Type Type ;
00415 typedef typename Getter::return_type return_type ;
00416
00417 public:
00418
00425 template <class COMMON>
00426 inline return_type operator()
00427 ( const COMMON& common ,
00428 IDataProviderSvc* service ,
00429 const std::string& location ,
00430 const std::string& location2 ) const
00431 {
00432 SmartDataPtr<TYPE> obj ( service , location ) ;
00433 if ( !obj )
00434 {
00435 TYPE2* o = new TYPE2() ;
00436 common.put ( service , o , location2 ) ;
00437 if ( common.msgLevel ( MSG::DEBUG ) )
00438 { common.debug() << "The object of type '"
00439 << System::typeinfoName(typeid(*o))
00440 << "' has been created from TS at address '"
00441 << location2 << "'" << endmsg ; }
00442 return_type _o = o ;
00443 return _o ;
00444 }
00445 return_type ret = obj ;
00447 common.Assert ( !(!ret) , "get():: No valid data at '" + location + "'" ) ;
00448 if ( common.msgLevel ( MSG::DEBUG ) )
00449 { common.debug() << "The object of type '"
00450 << System::typeinfoName(typeid(*ret))
00451 << "' has been retrieved from TS at address '"
00452 << location << "'" << endmsg ; }
00453
00454 return ret ;
00455
00456 }
00457 };
00458
00459 template <class TYPE, class TYPE2>
00460 struct GetOrCreateData<Gaudi::Range_<std::vector<const TYPE*> >,TYPE2>
00461 {
00462 private:
00463
00464 typedef Gaudi::Range_<std::vector<const TYPE*> > Range ;
00466 typedef GetData<Range> Getter ;
00468 typedef CheckData<Range> Checker ;
00469
00470 public:
00471
00472 typedef typename Getter::Type Type ;
00474 typedef typename Getter::return_type return_type ;
00475
00476 public:
00477
00484 template <class COMMON>
00485 inline return_type operator()
00486 ( const COMMON& common ,
00487 IDataProviderSvc* service ,
00488 const std::string& location ,
00489 const std::string& location2 ) const
00490 {
00491 DataObject* obj = m_getter.getData ( service , location ) ;
00492 if ( 0 == obj )
00493 {
00494 TYPE2* o = new TYPE2() ;
00495 common.put ( service , o , location2 ) ;
00496 if ( common.msgLevel ( MSG::DEBUG ) )
00497 { common.debug() << "The object of type '"
00498 << System::typeinfoName(typeid(*o))
00499 << "' has been created from TS at address '"
00500 << location2 << "'" << endmsg ; }
00501 }
00502 return m_getter ( common , service , location ) ;
00503
00504 }
00505
00506 private:
00507
00509 Getter m_getter ;
00510
00511 };
00512
00513 template <class TYPE, class TYPE2>
00514 struct GetOrCreateData<Gaudi::NamedRange_<std::vector<const TYPE*> >,TYPE2>
00515 {
00516 private:
00517
00518 typedef Gaudi::NamedRange_<std::vector<const TYPE*> > Range ;
00519 typedef Gaudi::Range_<std::vector<const TYPE*> > Range_ ;
00520 typedef GetOrCreateData<Range_,TYPE2> Helper ;
00522 typedef GetData<Range> Getter ;
00523
00524 public:
00525
00526 typedef typename Getter::Type Type ;
00528 typedef typename Getter::return_type return_type ;
00529
00530 public:
00531
00538 template <class COMMON>
00539 inline return_type operator()
00540 ( const COMMON& common ,
00541 IDataProviderSvc* service ,
00542 const std::string& location ,
00543 const std::string& location2 ) const
00544 {
00545 return return_type ( m_range ( common ,
00546 service ,
00547 location ,
00548 location2 ) , location ) ;
00549 }
00550
00551 private:
00552
00554 Helper m_range ;
00555
00556 };
00557
00558 template <class TYPE, class TYPE2>
00559 struct GetOrCreateData<TYPE,TYPE2*>
00560 : public GetOrCreateData<TYPE,TYPE2> {} ;
00561 template <class TYPE, class TYPE2>
00562 struct GetOrCreateData<TYPE*,TYPE2>
00563 : public GetOrCreateData<TYPE,TYPE2> {} ;
00564 template <class TYPE, class TYPE2>
00565 struct GetOrCreateData<TYPE*,TYPE2*>
00566 : public GetOrCreateData<TYPE,TYPE2> {} ;
00567
00568 template <class TYPE, class TYPE2>
00569 struct GetOrCreateData< TYPE,const TYPE2>
00570 : public GetOrCreateData<TYPE,TYPE2> {} ;
00571 template <class TYPE, class TYPE2>
00572 struct GetOrCreateData<const TYPE, TYPE2>
00573 : public GetOrCreateData<TYPE,TYPE2> {} ;
00574 template <class TYPE, class TYPE2>
00575 struct GetOrCreateData<const TYPE,const TYPE2>
00576 : public GetOrCreateData<TYPE,TYPE2> {} ;
00577
00578 template <class TYPE, class TYPE2>
00579 struct GetOrCreateData<TYPE,TYPE2&>
00580 : public GetOrCreateData<TYPE,TYPE2> {} ;
00581 template <class TYPE, class TYPE2>
00582 struct GetOrCreateData<TYPE&,TYPE2>
00583 : public GetOrCreateData<TYPE,TYPE2> {} ;
00584 template <class TYPE, class TYPE2>
00585 struct GetOrCreateData<TYPE&,TYPE2&>
00586 : public GetOrCreateData<TYPE,TYPE2> {} ;
00587
00588 }
00589
00590 }
00591
00592
00593
00594 #endif // GAUDIUTILS_GETDATA_H
00595