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
00013
00014
00015 #include "GaudiKernel/Range.h"
00016 #include "GaudiKernel/NamedRange.h"
00017
00018
00019
00020 template <class BASE> class GaudiCommon ;
00021
00022 namespace Gaudi
00023 {
00024 namespace Utils
00025 {
00026
00033 template <class TYPE>
00034 struct _GetType
00035 { typedef TYPE* return_type ; };
00036
00038 template <class TYPE>
00039 struct _GetType<TYPE*>
00040 { typedef TYPE* return_type ; };
00041
00043 template <class TYPE>
00044 struct _GetType<TYPE&>
00045 { typedef TYPE* return_type ; };
00046
00048 template <class CONTAINER>
00049 struct _GetType<Gaudi::Range_<CONTAINER> >
00050 { typedef Gaudi::Range_<CONTAINER> return_type ; };
00051
00053 template <class CONTAINER>
00054 struct _GetType<Gaudi::NamedRange_<CONTAINER> >
00055 { typedef Gaudi::NamedRange_<CONTAINER> return_type ; };
00056
00065 template <class TYPE>
00066 struct GetData
00067 {
00068 public:
00069
00070 typedef TYPE Type ;
00072 typedef typename _GetType<Type>::return_type return_type ;
00073
00074 public:
00075
00082 template <class COMMON>
00083 inline return_type operator()
00084 ( const COMMON& common ,
00085 IDataProviderSvc* service ,
00086 const std::string& location ) const
00087 {
00089 SmartDataPtr<TYPE> obj ( service , location ) ;
00090 return_type aux = obj ;
00092 common.Assert ( !(!aux) , "get():: No valid data at '" + location + "'" ) ;
00094 if ( common.msgLevel ( MSG::DEBUG ) )
00095 { common.debug() << "The object of type '"
00096 << System::typeinfoName(typeid(aux))
00097 << "' has been retrieved from TS at address '"
00098 << location << "'" << endmsg ; }
00099
00100 return aux ;
00101
00102 }
00103 };
00104
00106 template <class TYPE>
00107 struct GetData<Gaudi::Range_<std::vector<const TYPE*> > >
00108 {
00109 public:
00110
00112 typedef Gaudi::Range_<std::vector<const TYPE*> > Type ;
00113 typedef typename _GetType<Type>::return_type return_type ;
00114
00115 public:
00116
00123 template <class COMMON>
00124 inline return_type operator()
00125 ( const COMMON& common ,
00126 IDataProviderSvc* service ,
00127 const std::string& location ) const
00128 {
00131 DataObject* object = this -> getData ( service , location ) ;
00132 if ( 0 != object )
00133 {
00135 typedef typename TYPE::Selection Selection_;
00136 const Selection_* sel = dynamic_cast<Selection_*> ( object ) ;
00137 if ( 0 != sel )
00138 {
00139 if ( common.msgLevel ( MSG::DEBUG ) )
00140 { common.debug() << "The object of type '"
00141 << System::typeinfoName(typeid(*object))
00142 << "' has been retrieved from TS at address '"
00143 << location << "'" << endmsg ; }
00144 return make_range ( sel ) ;
00145 }
00147 typedef typename TYPE::Container Container_ ;
00148 const Container_* cnt = dynamic_cast<Container_*> ( object ) ;
00149 if ( 0 != cnt )
00150 {
00151 if ( common.msgLevel ( MSG::DEBUG ) )
00152 { common.debug() << "The object of type '"
00153 << System::typeinfoName(typeid(*object))
00154 << "' has been retrieved from TS at address '"
00155 << location << "'" << endmsg ; }
00156 return make_range ( cnt ) ;
00157 }
00158
00159 common.Assert ( false , "get():: No valid data at '" + location + "'" ) ;
00160 }
00161
00162 common.Assert ( false , "get():: No data at '" + location + "'" ) ;
00163
00164 return return_type () ;
00165 }
00166
00167 public:
00168
00169 template <class TYPE3>
00170 return_type make_range ( const TYPE3* obj ) const
00171 { return this->make_range ( obj->begin() , obj->end() ) ; }
00172
00178 DataObject* getData ( IDataProviderSvc* service ,
00179 const std::string& location ) const
00180 {
00182 SmartDataObjectPtr getter
00183 ( SmartDataObjectPtr::ObjectLoader::access() ,
00184 service , 0 , location ) ;
00185 return getter.accessData () ;
00186 }
00187
00188 private:
00189
00190 template <class ITERATOR>
00191 return_type make_range
00192 ( ITERATOR first ,
00193 ITERATOR last ) const
00194 {
00195 typename return_type::const_iterator* _begin = reinterpret_cast<typename return_type::const_iterator*>(&first);
00196 typename return_type::const_iterator* _end = reinterpret_cast<typename return_type::const_iterator*>(&last);
00197 return return_type(*_begin, *_end);
00198 }
00199
00200 } ;
00201
00203 template <class TYPE>
00204 struct GetData<Gaudi::NamedRange_<std::vector<const TYPE*> > >
00205 {
00206 public:
00207
00209 typedef Gaudi::NamedRange_<std::vector<const TYPE*> > Type ;
00210 typedef typename _GetType<Type>::return_type return_type ;
00211
00212 public:
00213
00220 template <class COMMON>
00221 inline return_type operator()
00222 ( const COMMON& common ,
00223 IDataProviderSvc* service ,
00224 const std::string& location ) const
00225 {
00226 return return_type ( m_range( common , service , location ) , location ) ;
00227 }
00228
00229 public:
00230
00231 template <class TYPE3>
00232 return_type make_range ( const TYPE3* obj ) const
00233 { return m_range.make_range ( obj->begin() , obj->end() ) ; }
00239 DataObject* getData ( IDataProviderSvc* service ,
00240 const std::string& location ) const
00241 { return m_range.getData ( service , location ) ; }
00242
00243 private:
00246 GetData<Gaudi::Range_<std::vector<const TYPE*> > > m_range ;
00247
00248 } ;
00249
00251 template <class TYPE>
00252 struct GetData<const TYPE> : public GetData<TYPE> {} ;
00253
00255 template <class TYPE>
00256 struct GetData<TYPE*> : public GetData<TYPE> {} ;
00257
00259 template <class TYPE>
00260 struct GetData<TYPE&> : public GetData<TYPE> {} ;
00261
00270 template <class TYPE>
00271 struct CheckData
00272 {
00273 public:
00274
00281 inline bool operator()
00282 ( IDataProviderSvc* service ,
00283 const std::string& location ) const
00284 {
00286 SmartDataPtr<TYPE> obj ( service , location ) ;
00287 return !(!obj) ;
00288 }
00289
00290 };
00291
00293 template <class TYPE>
00294 struct CheckData<Gaudi::Range_<std::vector<const TYPE*> > >
00295 {
00296 public:
00297
00304 inline bool operator()
00305 ( IDataProviderSvc* service ,
00306 const std::string& location ) const
00307 {
00308 DataObject* object = this->getData( service , location ) ;
00309 if ( 0 == object ) { return false ; }
00310 return
00311 0 != dynamic_cast<typename TYPE::Selection*> ( object ) ||
00312 0 != dynamic_cast<typename TYPE::Container*> ( object ) ;
00313 }
00314
00315 protected:
00316
00322 DataObject* getData ( IDataProviderSvc* service ,
00323 const std::string& location ) const
00324 {
00326 SmartDataObjectPtr getter
00327 ( SmartDataObjectPtr::ObjectLoader::access() ,
00328 service , 0 , location ) ;
00329 return getter.accessData () ;
00330 }
00331
00332 } ;
00333
00335 template <class TYPE>
00336 struct CheckData<Gaudi::NamedRange_<std::vector<const TYPE*> > >
00337 : public CheckData<Gaudi::Range_<std::vector<const TYPE*> > > {} ;
00338
00340 template <class TYPE>
00341 struct CheckData<TYPE*> : public CheckData<TYPE> {} ;
00342
00344 template <class TYPE>
00345 struct CheckData<TYPE&> : public CheckData<TYPE> {} ;
00346
00348 template <class TYPE>
00349 struct CheckData<const TYPE> : public CheckData<TYPE> {} ;
00350
00359 template <class TYPE, class TYPE2>
00360 struct GetOrCreateData
00361 {
00362 private:
00363
00365 typedef GetData<TYPE> Getter ;
00366
00367 public:
00368
00369 typedef typename Getter::Type Type ;
00371 typedef typename Getter::return_type return_type ;
00372
00373 public:
00374
00381 template <class COMMON>
00382 inline return_type operator()
00383 ( const COMMON& common ,
00384 IDataProviderSvc* service ,
00385 const std::string& location ,
00386 const std::string& location2 ) const
00387 {
00388 SmartDataPtr<TYPE> obj ( service , location ) ;
00389 if ( !obj )
00390 {
00391 TYPE2* o = new TYPE2() ;
00392 common.put ( service , o , location2 ) ;
00393 if ( common.msgLevel ( MSG::DEBUG ) )
00394 { common.debug() << "The object of type '"
00395 << System::typeinfoName(typeid(*o))
00396 << "' has been created from TS at address '"
00397 << location2 << "'" << endmsg ; }
00398 return_type _o = o ;
00399 return _o ;
00400 }
00401 return_type ret = obj ;
00403 common.Assert ( !(!ret) , "get():: No valid data at '" + location + "'" ) ;
00404 if ( common.msgLevel ( MSG::DEBUG ) )
00405 { common.debug() << "The object of type '"
00406 << System::typeinfoName(typeid(*ret))
00407 << "' has been retrieved from TS at address '"
00408 << location << "'" << endmsg ; }
00409
00410 return ret ;
00411
00412 }
00413 };
00414
00415 template <class TYPE, class TYPE2>
00416 struct GetOrCreateData<Gaudi::Range_<std::vector<const TYPE*> >,TYPE2>
00417 {
00418 private:
00419
00420 typedef Gaudi::Range_<std::vector<const TYPE*> > Range ;
00422 typedef GetData<Range> Getter ;
00424 typedef CheckData<Range> Checker ;
00425
00426 public:
00427
00428 typedef typename Getter::Type Type ;
00430 typedef typename Getter::return_type return_type ;
00431
00432 public:
00433
00440 template <class COMMON>
00441 inline return_type operator()
00442 ( const COMMON& common ,
00443 IDataProviderSvc* service ,
00444 const std::string& location ,
00445 const std::string& location2 ) const
00446 {
00447 DataObject* obj = m_getter.getData ( service , location ) ;
00448 if ( 0 == obj )
00449 {
00450 TYPE2* o = new TYPE2() ;
00451 common.put ( service , o , location2 ) ;
00452 if ( common.msgLevel ( MSG::DEBUG ) )
00453 { common.debug() << "The object of type '"
00454 << System::typeinfoName(typeid(*o))
00455 << "' has been created from TS at address '"
00456 << location2 << "'" << endmsg ; }
00457 }
00458 return m_getter ( common , service , location ) ;
00459
00460 }
00461
00462 private:
00463
00465 Getter m_getter ;
00466
00467 };
00468
00469 template <class TYPE, class TYPE2>
00470 struct GetOrCreateData<Gaudi::NamedRange_<std::vector<const TYPE*> >,TYPE2>
00471 {
00472 private:
00473
00474 typedef Gaudi::NamedRange_<std::vector<const TYPE*> > Range ;
00475 typedef Gaudi::Range_<std::vector<const TYPE*> > Range_ ;
00476 typedef GetOrCreateData<Range_,TYPE2> Helper ;
00478 typedef GetData<Range> Getter ;
00479
00480 public:
00481
00482 typedef typename Getter::Type Type ;
00484 typedef typename Getter::return_type return_type ;
00485
00486 public:
00487
00494 template <class COMMON>
00495 inline return_type operator()
00496 ( const COMMON& common ,
00497 IDataProviderSvc* service ,
00498 const std::string& location ,
00499 const std::string& location2 ) const
00500 {
00501 return return_type ( m_range ( common ,
00502 service ,
00503 location ,
00504 location2 ) , location ) ;
00505 }
00506
00507 private:
00508
00510 Helper m_range ;
00511
00512 };
00513
00514 template <class TYPE, class TYPE2>
00515 struct GetOrCreateData<TYPE,TYPE2*>
00516 : public GetOrCreateData<TYPE,TYPE2> {} ;
00517 template <class TYPE, class TYPE2>
00518 struct GetOrCreateData<TYPE*,TYPE2>
00519 : public GetOrCreateData<TYPE,TYPE2> {} ;
00520 template <class TYPE, class TYPE2>
00521 struct GetOrCreateData<TYPE*,TYPE2*>
00522 : public GetOrCreateData<TYPE,TYPE2> {} ;
00523
00524 template <class TYPE, class TYPE2>
00525 struct GetOrCreateData< TYPE,const TYPE2>
00526 : public GetOrCreateData<TYPE,TYPE2> {} ;
00527 template <class TYPE, class TYPE2>
00528 struct GetOrCreateData<const TYPE, TYPE2>
00529 : public GetOrCreateData<TYPE,TYPE2> {} ;
00530 template <class TYPE, class TYPE2>
00531 struct GetOrCreateData<const TYPE,const TYPE2>
00532 : public GetOrCreateData<TYPE,TYPE2> {} ;
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 }
00545
00546 }
00547
00548
00549
00550 #endif // GAUDIUTILS_GETDATA_H
00551