File indexing completed on 2025-01-18 09:57:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef GAUDIUTILS_GETDATA_H
0012 #define GAUDIUTILS_GETDATA_H 1
0013
0014
0015
0016
0017
0018 #include "GaudiKernel/IDataProviderSvc.h"
0019 #include "GaudiKernel/IMessageSvc.h"
0020 #include "GaudiKernel/IRegistry.h"
0021 #include "GaudiKernel/MsgStream.h"
0022 #include "GaudiKernel/SmartDataPtr.h"
0023 #include "GaudiKernel/StatusCode.h"
0024
0025
0026
0027 #include "GaudiKernel/AnyDataWrapper.h"
0028 #include "GaudiKernel/NamedRange.h"
0029 #include "GaudiKernel/Range.h"
0030
0031
0032
0033 template <class BASE>
0034 class GaudiCommon;
0035
0036 namespace Gaudi {
0037 namespace Utils {
0038
0039
0040
0041
0042
0043
0044
0045 template <class TYPE>
0046 struct _GetType {
0047 typedef TYPE* return_type;
0048 };
0049
0050
0051 template <class TYPE>
0052 struct _GetType<TYPE*> {
0053 typedef TYPE* return_type;
0054 };
0055
0056
0057 template <class TYPE>
0058 struct _GetType<TYPE&> {
0059 typedef TYPE* return_type;
0060 };
0061
0062
0063 template <class CONTAINER>
0064 struct _GetType<Gaudi::Range_<CONTAINER>> {
0065 typedef Gaudi::Range_<CONTAINER> return_type;
0066 };
0067
0068
0069 template <class CONTAINER>
0070 struct _GetType<Gaudi::NamedRange_<CONTAINER>> {
0071 typedef Gaudi::NamedRange_<CONTAINER> return_type;
0072 };
0073
0074
0075
0076
0077
0078 template <class TYPE, std::enable_if_t<!std::is_constructible_v<TYPE>, void*> = nullptr>
0079 typename _GetType<TYPE>::return_type getFromTS( IDataProviderSvc* service, std::string_view location ) {
0080 DataObject* obj = nullptr;
0081
0082 return service->retrieveObject( location, obj ).isSuccess()
0083 ? dynamic_cast<typename _GetType<TYPE>::return_type>( obj )
0084 : nullptr;
0085 }
0086
0087
0088
0089
0090
0091
0092 template <class TYPE, std::enable_if_t<std::is_constructible_v<TYPE>, void*> = nullptr>
0093 typename _GetType<TYPE>::return_type getFromTS( IDataProviderSvc* service, std::string_view location ) {
0094 DataObject* obj = nullptr;
0095
0096 StatusCode sc = service->retrieveObject( location, obj );
0097 if ( sc.isFailure() ) return nullptr;
0098 auto tobj = dynamic_cast<typename _GetType<TYPE>::return_type>( obj );
0099 if ( !tobj ) {
0100
0101 if ( auto tobj2 = dynamic_cast<AnyDataWrapper<TYPE>*>( obj ); tobj2 ) { tobj = &( tobj2->getData() ); }
0102 }
0103 return tobj;
0104 }
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 template <class TYPE>
0115 struct GetData {
0116 public:
0117
0118 typedef TYPE Type;
0119
0120 typedef typename _GetType<Type>::return_type return_type;
0121
0122 public:
0123
0124
0125
0126
0127
0128
0129
0130
0131 template <class COMMON>
0132 return_type operator()( const COMMON& common, IDataProviderSvc* service, std::string_view location,
0133 const bool checkData = true ) const {
0134
0135 return_type obj = getFromTS<Type>( service, location );
0136 if ( checkData ) {
0137 common.Assert( obj, std::string{ "get():: No valid data at '" }.append( location ).append( "'" ) );
0138 }
0139
0140 if ( common.msgLevel( MSG::DEBUG ) ) {
0141 common.debug() << "The object of type '" << System::typeinfoName( typeid( obj ) ) << "' "
0142 << ( obj ? "has been" : "could not be" ) << " retrieved from TS at address '" << location
0143 << "'" << endmsg;
0144 }
0145
0146 return obj;
0147
0148 }
0149 };
0150
0151
0152 template <class TYPE>
0153 struct GetData<Gaudi::Range_<std::vector<const TYPE*>>> {
0154 public:
0155
0156
0157 typedef Gaudi::Range_<std::vector<const TYPE*>> Type;
0158 typedef typename _GetType<Type>::return_type return_type;
0159
0160 public:
0161
0162
0163
0164
0165
0166
0167
0168
0169 template <class COMMON>
0170 return_type operator()( const COMMON& common, IDataProviderSvc* service, std::string_view location,
0171 const bool checkData = true ) const {
0172
0173
0174 DataObject* object = this->getData( service, std::string{ location } );
0175 if ( object ) {
0176
0177 typedef typename TYPE::Selection Selection_;
0178 const Selection_* sel = dynamic_cast<Selection_*>( object );
0179 if ( sel ) {
0180 if ( common.msgLevel( MSG::DEBUG ) ) {
0181 common.debug() << "The object of type '" << System::typeinfoName( typeid( *object ) )
0182 << "' has been retrieved from TS at address '" << location << "'" << endmsg;
0183 }
0184 return make_range( sel );
0185 }
0186
0187 typedef typename TYPE::Container Container_;
0188 const Container_* cnt = dynamic_cast<Container_*>( object );
0189 if ( cnt ) {
0190 if ( common.msgLevel( MSG::DEBUG ) ) {
0191 common.debug() << "The object of type '" << System::typeinfoName( typeid( *object ) )
0192 << "' has been retrieved from TS at address '" << location << "'" << endmsg;
0193 }
0194 return make_range( cnt );
0195 }
0196
0197 if ( checkData )
0198 common.Assert( false, std::string{ "get():: No valid data at '" }.append( location ).append( "'" ) );
0199 }
0200
0201 if ( checkData ) common.Assert( false, std::string{ "get():: No data at '" }.append( location ).append( "'" ) );
0202
0203 return return_type();
0204 }
0205
0206 public:
0207
0208
0209 return_type make_range( const typename TYPE::Container* cnt ) const {
0210 return 0 == cnt ? return_type() : make_range( cnt->begin(), cnt->end() );
0211 }
0212
0213 return_type make_range( const typename TYPE::Selection* cnt ) const {
0214 return 0 == cnt ? return_type() : return_type( cnt->begin(), cnt->end() );
0215 }
0216
0217
0218
0219
0220
0221
0222 DataObject* getData( IDataProviderSvc* service, std::string location ) const {
0223
0224 SmartDataObjectPtr getter( SmartDataObjectPtr::ObjectLoader::access(), service, nullptr,
0225 std::move( location ) );
0226 return getter.accessData();
0227 }
0228
0229 private:
0230
0231 template <class ITERATOR>
0232 return_type make_range( ITERATOR first, ITERATOR last ) const {
0233 auto _begin = reinterpret_cast<typename return_type::const_iterator*>( &first );
0234 auto _end = reinterpret_cast<typename return_type::const_iterator*>( &last );
0235 return return_type( *_begin, *_end );
0236 }
0237
0238 };
0239
0240
0241 template <class TYPE>
0242 struct GetData<Gaudi::NamedRange_<std::vector<const TYPE*>>> {
0243 public:
0244
0245
0246 typedef Gaudi::NamedRange_<std::vector<const TYPE*>> Type;
0247 typedef typename _GetType<Type>::return_type return_type;
0248
0249 public:
0250
0251
0252
0253
0254
0255
0256
0257
0258 template <class COMMON>
0259 return_type operator()( const COMMON& common, IDataProviderSvc* service, std::string_view location,
0260 const bool checkData = true ) const {
0261 return return_type( m_range( common, service, location, checkData ), std::string{ location } );
0262 }
0263
0264 public:
0265
0266
0267 return_type make_range( const typename TYPE::Container* cnt ) const {
0268 if ( !cnt ) { return return_type(); }
0269 static const std::string s_empty = "";
0270 const IRegistry* reg = cnt->registry();
0271 return return_type( m_range.make_range( cnt ), reg ? reg->identifier() : s_empty );
0272 }
0273
0274 return_type make_range( const typename TYPE::Selection* cnt ) const {
0275 if ( !cnt ) { return return_type(); }
0276 static const std::string s_empty = "";
0277 const IRegistry* reg = cnt->registry();
0278 return return_type( m_range.make_range( cnt ), reg ? reg->identifier() : s_empty );
0279 }
0280
0281
0282
0283
0284
0285
0286 DataObject* getData( IDataProviderSvc* service, std::string location ) const {
0287 return m_range.getData( service, std::move( location ) );
0288 }
0289
0290 private:
0291
0292
0293 GetData<Gaudi::Range_<std::vector<const TYPE*>>> m_range;
0294
0295 };
0296
0297
0298 template <class TYPE>
0299 struct GetData<const TYPE> : public GetData<TYPE> {};
0300
0301
0302 template <class TYPE>
0303 struct GetData<TYPE*> : public GetData<TYPE> {};
0304
0305
0306 template <class TYPE>
0307 struct GetData<TYPE&> : public GetData<TYPE> {};
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 template <class TYPE>
0318 struct CheckData {
0319 public:
0320
0321
0322
0323
0324
0325
0326
0327 bool operator()( IDataProviderSvc* service, std::string_view location ) const {
0328
0329 return getFromTS<TYPE>( service, location );
0330 }
0331
0332 };
0333
0334
0335 template <class TYPE>
0336 struct CheckData<Gaudi::Range_<std::vector<const TYPE*>>> {
0337 public:
0338
0339
0340
0341
0342
0343
0344
0345 bool operator()( IDataProviderSvc* service, std::string location ) const {
0346 DataObject* object = this->getData( service, std::move( location ) );
0347 return object && ( dynamic_cast<typename TYPE::Selection*>( object ) ||
0348 dynamic_cast<typename TYPE::Container*>( object ) );
0349 }
0350
0351 protected:
0352
0353
0354
0355
0356
0357
0358 DataObject* getData( IDataProviderSvc* service, std::string location ) const {
0359
0360 SmartDataObjectPtr getter( SmartDataObjectPtr::ObjectLoader::access(), service, nullptr,
0361 std::move( location ) );
0362 return getter.accessData();
0363 }
0364
0365 };
0366
0367
0368 template <class TYPE>
0369 struct CheckData<Gaudi::NamedRange_<std::vector<const TYPE*>>>
0370 : public CheckData<Gaudi::Range_<std::vector<const TYPE*>>> {};
0371
0372
0373 template <class TYPE>
0374 struct CheckData<TYPE*> : public CheckData<TYPE> {};
0375
0376
0377 template <class TYPE>
0378 struct CheckData<TYPE&> : public CheckData<TYPE> {};
0379
0380
0381 template <class TYPE>
0382 struct CheckData<const TYPE> : public CheckData<TYPE> {};
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 template <class TYPE, class TYPE2>
0393 struct GetOrCreateData {
0394 private:
0395
0396
0397 typedef GetData<TYPE> Getter;
0398
0399 public:
0400
0401 typedef typename Getter::Type Type;
0402
0403 typedef typename Getter::return_type return_type;
0404
0405 public:
0406
0407
0408
0409
0410
0411
0412
0413 template <class COMMON>
0414 return_type operator()( const COMMON& common, IDataProviderSvc* service, std::string_view location,
0415 std::string_view location2 ) const {
0416 SmartDataPtr<TYPE> obj( service, std::string{ location } );
0417 if ( !obj ) {
0418 auto o = std::make_unique<TYPE2>();
0419 auto r = o.get();
0420 common.put( service, std::move( o ), location2 );
0421 if ( common.msgLevel( MSG::DEBUG ) ) {
0422 common.debug() << "The object of type '" << System::typeinfoName( typeid( *r ) )
0423 << "' has been created from TS at address '" << location2 << "'" << endmsg;
0424 }
0425 return r;
0426 }
0427 auto ret = obj.ptr();
0428
0429 common.Assert( !( !ret ), std::string{ "get():: No valid data at '" }.append( location ).append( "\'" ) );
0430 if ( common.msgLevel( MSG::DEBUG ) ) {
0431 common.debug() << "The object of type '" << System::typeinfoName( typeid( *ret ) )
0432 << "' has been retrieved from TS at address '" << location << "'" << endmsg;
0433 }
0434
0435 return ret;
0436
0437 }
0438 };
0439
0440 template <class TYPE, class TYPE2>
0441 struct GetOrCreateData<Gaudi::Range_<std::vector<const TYPE*>>, TYPE2> {
0442 private:
0443
0444 typedef Gaudi::Range_<std::vector<const TYPE*>> Range;
0445
0446 typedef GetData<Range> Getter;
0447
0448 typedef CheckData<Range> Checker;
0449
0450 public:
0451
0452 typedef typename Getter::Type Type;
0453
0454 typedef typename Getter::return_type return_type;
0455
0456 public:
0457
0458
0459
0460
0461
0462
0463
0464 template <class COMMON>
0465 return_type operator()( const COMMON& common, IDataProviderSvc* service, std::string_view location,
0466 std::string_view location2 ) const {
0467 DataObject* obj = m_getter.getData( service, std::string{ location } );
0468 if ( !obj ) {
0469 common.put( service, std::make_unique<TYPE2>(), location2 );
0470 if ( common.msgLevel( MSG::DEBUG ) ) {
0471 common.debug() << "The object of type '" << System::typeinfoName( typeid( TYPE2 ) )
0472 << "' has been created from TS at address '" << location2 << "'" << endmsg;
0473 }
0474 }
0475 return m_getter( common, service, location );
0476
0477 }
0478
0479 private:
0480
0481
0482 Getter m_getter;
0483
0484 };
0485
0486 template <class TYPE, class TYPE2>
0487 struct GetOrCreateData<Gaudi::NamedRange_<std::vector<const TYPE*>>, TYPE2> {
0488 private:
0489
0490 typedef Gaudi::NamedRange_<std::vector<const TYPE*>> Range;
0491 typedef Gaudi::Range_<std::vector<const TYPE*>> Range_;
0492 typedef GetOrCreateData<Range_, TYPE2> Helper;
0493
0494 typedef GetData<Range> Getter;
0495
0496 public:
0497
0498 typedef typename Getter::Type Type;
0499
0500 typedef typename Getter::return_type return_type;
0501
0502 public:
0503
0504
0505
0506
0507
0508
0509
0510 template <class COMMON>
0511 return_type operator()( const COMMON& common, IDataProviderSvc* service, std::string location,
0512 std::string_view location2 ) const {
0513 auto range = m_range( common, service, location, location2 );
0514 return return_type( std::move( range ), std::move( location ) );
0515 }
0516
0517 private:
0518
0519
0520 Helper m_range;
0521
0522 };
0523
0524 template <class TYPE, class TYPE2>
0525 struct GetOrCreateData<TYPE, TYPE2*> : public GetOrCreateData<TYPE, TYPE2> {};
0526 template <class TYPE, class TYPE2>
0527 struct GetOrCreateData<TYPE*, TYPE2> : public GetOrCreateData<TYPE, TYPE2> {};
0528 template <class TYPE, class TYPE2>
0529 struct GetOrCreateData<TYPE*, TYPE2*> : public GetOrCreateData<TYPE, TYPE2> {};
0530
0531 template <class TYPE, class TYPE2>
0532 struct GetOrCreateData<TYPE, const TYPE2> : public GetOrCreateData<TYPE, TYPE2> {};
0533 template <class TYPE, class TYPE2>
0534 struct GetOrCreateData<const TYPE, TYPE2> : public GetOrCreateData<TYPE, TYPE2> {};
0535 template <class TYPE, class TYPE2>
0536 struct GetOrCreateData<const TYPE, const TYPE2> : public GetOrCreateData<TYPE, TYPE2> {};
0537
0538 template <class TYPE, class TYPE2>
0539 struct GetOrCreateData<TYPE, TYPE2&> : public GetOrCreateData<TYPE, TYPE2> {};
0540 template <class TYPE, class TYPE2>
0541 struct GetOrCreateData<TYPE&, TYPE2> : public GetOrCreateData<TYPE, TYPE2> {};
0542 template <class TYPE, class TYPE2>
0543 struct GetOrCreateData<TYPE&, TYPE2&> : public GetOrCreateData<TYPE, TYPE2> {};
0544
0545 }
0546
0547 }
0548
0549
0550
0551 #endif