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
00066 template <class TYPE>
00067 struct GetData
00068 {
00069 public:
00070
00071 typedef TYPE Type ;
00073 typedef typename _GetType<Type>::return_type return_type ;
00074
00075 public:
00076
00083 template <class COMMON>
00084 inline return_type operator()
00085 ( const COMMON& common ,
00086 IDataProviderSvc* service ,
00087 const std::string& location ) const
00088 {
00090 SmartDataPtr<TYPE> obj ( service , location ) ;
00091 return_type aux = obj ;
00093 common.Assert ( !(!aux) , "get():: No valid data at '" + location + "'" ) ;
00095 if ( common.msgLevel ( MSG::DEBUG ) )
00096 { common.debug() << "The object of type '"
00097 << System::typeinfoName(typeid(aux))
00098 << "' has been retrieved from TS at address '"
00099 << location << "'" << endmsg ; }
00100
00101 return aux ;
00102
00103 }
00104 };
00105
00107 template <class TYPE>
00108 struct GetData<Gaudi::Range_<std::vector<const TYPE*> > >
00109 {
00110 public:
00111
00113 typedef Gaudi::Range_<std::vector<const TYPE*> > Type ;
00114 typedef typename _GetType<Type>::return_type return_type ;
00115
00116 public:
00117
00124 template <class COMMON>
00125 inline return_type operator()
00126 ( const COMMON& common ,
00127 IDataProviderSvc* service ,
00128 const std::string& location ) const
00129 {
00132 DataObject* object = this -> getData ( service , location ) ;
00133 if ( 0 != object )
00134 {
00136 typedef typename TYPE::Selection Selection_;
00137 const Selection_* sel = dynamic_cast<Selection_*> ( object ) ;
00138 if ( 0 != sel )
00139 {
00140 if ( common.msgLevel ( MSG::DEBUG ) )
00141 { common.debug() << "The object of type '"
00142 << System::typeinfoName(typeid(*object))
00143 << "' has been retrieved from TS at address '"
00144 << location << "'" << endmsg ; }
00145 return make_range ( sel ) ;
00146 }
00148 typedef typename TYPE::Container Container_ ;
00149 const Container_* cnt = dynamic_cast<Container_*> ( object ) ;
00150 if ( 0 != cnt )
00151 {
00152 if ( common.msgLevel ( MSG::DEBUG ) )
00153 { common.debug() << "The object of type '"
00154 << System::typeinfoName(typeid(*object))
00155 << "' has been retrieved from TS at address '"
00156 << location << "'" << endmsg ; }
00157 return make_range ( cnt ) ;
00158 }
00159
00160 common.Assert ( false , "get():: No valid data at '" + location + "'" ) ;
00161 }
00162
00163 common.Assert ( false , "get():: No data at '" + location + "'" ) ;
00164
00165 return return_type () ;
00166 }
00167
00168 public:
00169
00170
00171 return_type make_range ( const typename TYPE::Container* cnt ) const
00172 { return 0 == cnt ? return_type() : make_range ( cnt->begin() , cnt->end() ) ; }
00173
00174 return_type make_range ( const typename TYPE::Selection* cnt ) const
00175 { return 0 == cnt ? return_type() : return_type ( cnt->begin() , cnt->end() ) ; }
00176
00182 DataObject* getData ( IDataProviderSvc* service ,
00183 const std::string& location ) const
00184 {
00186 SmartDataObjectPtr getter
00187 ( SmartDataObjectPtr::ObjectLoader::access() ,
00188 service , 0 , location ) ;
00189 return getter.accessData () ;
00190 }
00191
00192 private:
00193
00194 template <class ITERATOR>
00195 return_type make_range
00196 ( ITERATOR first ,
00197 ITERATOR last ) const
00198 {
00199 typename return_type::const_iterator* _begin = reinterpret_cast<typename return_type::const_iterator*>(&first);
00200 typename return_type::const_iterator* _end = reinterpret_cast<typename return_type::const_iterator*>(&last);
00201 return return_type(*_begin, *_end);
00202 }
00203
00204 } ;
00205
00207 template <class TYPE>
00208 struct GetData<Gaudi::NamedRange_<std::vector<const TYPE*> > >
00209 {
00210 public:
00211
00213 typedef Gaudi::NamedRange_<std::vector<const TYPE*> > Type ;
00214 typedef typename _GetType<Type>::return_type return_type ;
00215
00216 public:
00217
00224 template <class COMMON>
00225 inline return_type operator()
00226 ( const COMMON& common ,
00227 IDataProviderSvc* service ,
00228 const std::string& location ) const
00229 {
00230 return return_type ( m_range( common , service , location ) , location ) ;
00231 }
00232
00233 public:
00234
00235
00236 return_type make_range ( const typename TYPE::Container* cnt ) const
00237 {
00238 if ( 0 == cnt ) { return return_type() ; }
00239 static const std::string s_empty = "" ;
00240 const IRegistry* reg = cnt->registry() ;
00241 return return_type
00242 ( m_range.make_range ( cnt ) , 0 != reg ? reg->identifier() : s_empty ) ;
00243 }
00244
00245 return_type make_range ( const typename TYPE::Selection* cnt ) const
00246 {
00247 if ( 0 == cnt ) { return return_type() ; }
00248 static const std::string s_empty = "" ;
00249 const IRegistry* reg = cnt->registry() ;
00250 return return_type
00251 ( m_range.make_range ( cnt ) , 0 != reg ? reg->identifier() : s_empty ) ;
00252 }
00253
00259 DataObject* getData ( IDataProviderSvc* service ,
00260 const std::string& location ) const
00261 { return m_range.getData ( service , location ) ; }
00262
00263 private:
00266 GetData<Gaudi::Range_<std::vector<const TYPE*> > > m_range ;
00267
00268 } ;
00269
00271 template <class TYPE>
00272 struct GetData<const TYPE> : public GetData<TYPE> {} ;
00273
00275 template <class TYPE>
00276 struct GetData<TYPE*> : public GetData<TYPE> {} ;
00277
00279 template <class TYPE>
00280 struct GetData<TYPE&> : public GetData<TYPE> {} ;
00281
00290 template <class TYPE>
00291 struct CheckData
00292 {
00293 public:
00294
00301 inline bool operator()
00302 ( IDataProviderSvc* service ,
00303 const std::string& location ) const
00304 {
00306 SmartDataPtr<TYPE> obj ( service , location ) ;
00307 return !(!obj) ;
00308 }
00309
00310 };
00311
00313 template <class TYPE>
00314 struct CheckData<Gaudi::Range_<std::vector<const TYPE*> > >
00315 {
00316 public:
00317
00324 inline bool operator()
00325 ( IDataProviderSvc* service ,
00326 const std::string& location ) const
00327 {
00328 DataObject* object = this->getData( service , location ) ;
00329 if ( 0 == object ) { return false ; }
00330 return
00331 0 != dynamic_cast<typename TYPE::Selection*> ( object ) ||
00332 0 != dynamic_cast<typename TYPE::Container*> ( object ) ;
00333 }
00334
00335 protected:
00336
00342 DataObject* getData ( IDataProviderSvc* service ,
00343 const std::string& location ) const
00344 {
00346 SmartDataObjectPtr getter
00347 ( SmartDataObjectPtr::ObjectLoader::access() ,
00348 service , 0 , location ) ;
00349 return getter.accessData () ;
00350 }
00351
00352 } ;
00353
00355 template <class TYPE>
00356 struct CheckData<Gaudi::NamedRange_<std::vector<const TYPE*> > >
00357 : public CheckData<Gaudi::Range_<std::vector<const TYPE*> > > {} ;
00358
00360 template <class TYPE>
00361 struct CheckData<TYPE*> : public CheckData<TYPE> {} ;
00362
00364 template <class TYPE>
00365 struct CheckData<TYPE&> : public CheckData<TYPE> {} ;
00366
00368 template <class TYPE>
00369 struct CheckData<const TYPE> : public CheckData<TYPE> {} ;
00370
00379 template <class TYPE, class TYPE2>
00380 struct GetOrCreateData
00381 {
00382 private:
00383
00385 typedef GetData<TYPE> Getter ;
00386
00387 public:
00388
00389 typedef typename Getter::Type Type ;
00391 typedef typename Getter::return_type return_type ;
00392
00393 public:
00394
00401 template <class COMMON>
00402 inline return_type operator()
00403 ( const COMMON& common ,
00404 IDataProviderSvc* service ,
00405 const std::string& location ,
00406 const std::string& location2 ) const
00407 {
00408 SmartDataPtr<TYPE> obj ( service , location ) ;
00409 if ( !obj )
00410 {
00411 TYPE2* o = new TYPE2() ;
00412 common.put ( service , o , location2 ) ;
00413 if ( common.msgLevel ( MSG::DEBUG ) )
00414 { common.debug() << "The object of type '"
00415 << System::typeinfoName(typeid(*o))
00416 << "' has been created from TS at address '"
00417 << location2 << "'" << endmsg ; }
00418 return_type _o = o ;
00419 return _o ;
00420 }
00421 return_type ret = obj ;
00423 common.Assert ( !(!ret) , "get():: No valid data at '" + location + "'" ) ;
00424 if ( common.msgLevel ( MSG::DEBUG ) )
00425 { common.debug() << "The object of type '"
00426 << System::typeinfoName(typeid(*ret))
00427 << "' has been retrieved from TS at address '"
00428 << location << "'" << endmsg ; }
00429
00430 return ret ;
00431
00432 }
00433 };
00434
00435 template <class TYPE, class TYPE2>
00436 struct GetOrCreateData<Gaudi::Range_<std::vector<const TYPE*> >,TYPE2>
00437 {
00438 private:
00439
00440 typedef Gaudi::Range_<std::vector<const TYPE*> > Range ;
00442 typedef GetData<Range> Getter ;
00444 typedef CheckData<Range> Checker ;
00445
00446 public:
00447
00448 typedef typename Getter::Type Type ;
00450 typedef typename Getter::return_type return_type ;
00451
00452 public:
00453
00460 template <class COMMON>
00461 inline return_type operator()
00462 ( const COMMON& common ,
00463 IDataProviderSvc* service ,
00464 const std::string& location ,
00465 const std::string& location2 ) const
00466 {
00467 DataObject* obj = m_getter.getData ( service , location ) ;
00468 if ( 0 == obj )
00469 {
00470 TYPE2* o = new TYPE2() ;
00471 common.put ( service , o , location2 ) ;
00472 if ( common.msgLevel ( MSG::DEBUG ) )
00473 { common.debug() << "The object of type '"
00474 << System::typeinfoName(typeid(*o))
00475 << "' has been created from TS at address '"
00476 << location2 << "'" << endmsg ; }
00477 }
00478 return m_getter ( common , service , location ) ;
00479
00480 }
00481
00482 private:
00483
00485 Getter m_getter ;
00486
00487 };
00488
00489 template <class TYPE, class TYPE2>
00490 struct GetOrCreateData<Gaudi::NamedRange_<std::vector<const TYPE*> >,TYPE2>
00491 {
00492 private:
00493
00494 typedef Gaudi::NamedRange_<std::vector<const TYPE*> > Range ;
00495 typedef Gaudi::Range_<std::vector<const TYPE*> > Range_ ;
00496 typedef GetOrCreateData<Range_,TYPE2> Helper ;
00498 typedef GetData<Range> Getter ;
00499
00500 public:
00501
00502 typedef typename Getter::Type Type ;
00504 typedef typename Getter::return_type return_type ;
00505
00506 public:
00507
00514 template <class COMMON>
00515 inline return_type operator()
00516 ( const COMMON& common ,
00517 IDataProviderSvc* service ,
00518 const std::string& location ,
00519 const std::string& location2 ) const
00520 {
00521 return return_type ( m_range ( common ,
00522 service ,
00523 location ,
00524 location2 ) , location ) ;
00525 }
00526
00527 private:
00528
00530 Helper m_range ;
00531
00532 };
00533
00534 template <class TYPE, class TYPE2>
00535 struct GetOrCreateData<TYPE,TYPE2*>
00536 : public GetOrCreateData<TYPE,TYPE2> {} ;
00537 template <class TYPE, class TYPE2>
00538 struct GetOrCreateData<TYPE*,TYPE2>
00539 : public GetOrCreateData<TYPE,TYPE2> {} ;
00540 template <class TYPE, class TYPE2>
00541 struct GetOrCreateData<TYPE*,TYPE2*>
00542 : public GetOrCreateData<TYPE,TYPE2> {} ;
00543
00544 template <class TYPE, class TYPE2>
00545 struct GetOrCreateData< TYPE,const TYPE2>
00546 : public GetOrCreateData<TYPE,TYPE2> {} ;
00547 template <class TYPE, class TYPE2>
00548 struct GetOrCreateData<const TYPE, TYPE2>
00549 : public GetOrCreateData<TYPE,TYPE2> {} ;
00550 template <class TYPE, class TYPE2>
00551 struct GetOrCreateData<const TYPE,const TYPE2>
00552 : public GetOrCreateData<TYPE,TYPE2> {} ;
00553
00554 template <class TYPE, class TYPE2>
00555 struct GetOrCreateData<TYPE,TYPE2&>
00556 : public GetOrCreateData<TYPE,TYPE2> {} ;
00557 template <class TYPE, class TYPE2>
00558 struct GetOrCreateData<TYPE&,TYPE2>
00559 : public GetOrCreateData<TYPE,TYPE2> {} ;
00560 template <class TYPE, class TYPE2>
00561 struct GetOrCreateData<TYPE&,TYPE2&>
00562 : public GetOrCreateData<TYPE,TYPE2> {} ;
00563
00564 }
00565
00566 }
00567
00568
00569
00570 #endif // GAUDIUTILS_GETDATA_H
00571