The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
DataObjectHandle.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#pragma once
12
20#include <type_traits>
21
22//---------------------------------------------------------------------------
23//
24namespace details {
25 template <typename T>
26 using Converter_t = T ( * )( const DataObject* );
27
28 template <typename Range, typename StorageType>
29 Range make_range( const DataObject* obj ) {
30 auto c = static_cast<const StorageType*>( obj );
31 if ( !c ) return Range();
32 using std::begin;
33 using std::end;
34 auto first = begin( *c );
35 auto last = end( *c );
36 auto _first = reinterpret_cast<typename Range::const_iterator*>( &first );
37 auto _last = reinterpret_cast<typename Range::const_iterator*>( &last );
38 return Range( *_first, *_last );
39 }
40
41 template <typename ValueType, typename Range = Gaudi::Range_<typename ValueType::ConstVector>>
43 using Selection = typename ValueType::Selection;
44 auto sel = dynamic_cast<const Selection*>( obj );
46 auto con = dynamic_cast<std::add_const_t<typename ValueType::Container>*>( obj );
48 return nullptr;
49 }
50
51 template <typename T>
52 bool verifyType( const DataObject* dataObj ) {
53 using Type = std::add_const_t<T>;
54 assert( dataObj != nullptr );
55 auto obj = dynamic_cast<Type*>( dataObj );
56 bool ok = ( obj != nullptr );
57 if ( !ok ) {
58 const auto* registry = dataObj->registry();
59 throw GaudiException( "The type expected for " + registry->identifier() + " is " +
60 System::typeinfoName( typeid( Type ) ) +
61 " and is different from the one of the object in the store which is " +
62 System::typeinfoName( typeid( *dataObj ) ) + ".",
63 "Wrong DataObjectType", StatusCode::FAILURE );
64 }
65 assert( obj == static_cast<Type*>( dataObj ) );
66 return ok;
67 }
68
69 template <Gaudi::DataHandle::Mode, typename T, typename U>
71 using type =
72 std::conditional_t<std::is_base_of_v<DataObject, T> && std::is_same_v<T, U>, T,
73 std::conditional_t<std::is_same_v<T, U>, AnyDataWrapper<std::remove_const_t<T>>,
74 AnyDataWithViewWrapper<std::remove_const_t<T>, std::remove_const_t<U>>>>;
75 };
76 template <typename T, typename U>
77 struct Payload_helper<Gaudi::DataHandle::Reader, Gaudi::Range_<T>, U> {
79 };
80 template <typename T, typename U>
81 struct Payload_helper<Gaudi::DataHandle::Reader, Gaudi::NamedRange_<T>, U> {
83 };
84 template <typename T, typename U>
85 struct Payload_helper<Gaudi::DataHandle::Reader, std::optional<Gaudi::NamedRange_<T>>, U> {
86 using type = std::optional<Gaudi::NamedRange_<T>>;
87 };
88
89 template <Gaudi::DataHandle::Mode mode, typename T, typename U = T>
91
92 std::string replace_all( std::string str, std::string_view from, std::string_view to );
93} // namespace details
94
95//---------------------------------------------------------------------------
96
106
107//---------------------------------------------------------------------------
108
109template <typename T>
111public:
113
117 T* get() const { return get( true ); }
118
123 T* getIfExists() const { return get( false ); }
124
128 bool exist() const { return get( false ) != nullptr; }
129
133 T* getOrCreate() const;
134
138 T* put( std::unique_ptr<T> object ) const;
139
140 std::string pythonRepr() const override {
141 return ::details::replace_all( DataObjectHandleBase::pythonRepr(), default_type,
142 System::typeinfoName( typeid( T ) ) );
143 }
144
145private:
146 T* get( bool mustExist ) const;
147 mutable bool m_goodType = false;
148};
149
150//---------------------------------------------------------------------------
151//
159template <typename T>
160T* DataObjectHandle<T>::get( bool mustExist ) const {
161 auto dataObj = fetch();
162 if ( !dataObj ) {
163 if ( mustExist ) { // Problems in getting from the store
164 throw GaudiException( "Cannot retrieve \'" + objKey() + "\' from transient store.",
165 m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
166 }
167 return nullptr;
168 }
170 return static_cast<T*>( dataObj );
171}
172
173//---------------------------------------------------------------------------
174template <typename T>
175T* DataObjectHandle<T>::put( std::unique_ptr<T> objectp ) const {
176 assert( m_init );
177 StatusCode sc = m_EDS->registerObject( objKey(), objectp.get() );
178 if ( !sc.isSuccess() ) { throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", sc ); }
179 return objectp.release();
180}
181
182//---------------------------------------------------------------------------
183template <typename T>
185 T* obj = get( false );
186 return obj ? obj : put( std::make_unique<T>() );
187}
188
189//---------------------------------------------------------------------------
191
192template <typename T>
193class DataObjectHandle<Gaudi::Range_<T>> : public DataObjectHandleBase {
194public:
195 using ValueType = std::remove_cv_t<std::remove_pointer_t<typename T::value_type>>;
197
199
203 Range get() const;
204
205 std::string pythonRepr() const override {
206 return ::details::replace_all( DataObjectHandleBase::pythonRepr(), default_type,
208 }
209
210private:
211 mutable ::details::Converter_t<Range> m_converter = nullptr;
212};
213
214template <typename ValueType>
215auto DataObjectHandle<Gaudi::Range_<ValueType>>::get() const -> Range {
216 auto dataObj = fetch();
217 if ( !dataObj ) {
218 throw GaudiException( "Cannot retrieve \'" + objKey() + "\' from transient store.",
219 m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
220 }
221 if ( !m_converter ) {
222 m_converter = ::details::select_range_converter<ValueType>( dataObj );
223 if ( !m_converter ) {
224 throw GaudiException( "The type requested for " + objKey() + " (" + System::typeinfoName( typeid( ValueType ) ) +
225 ")" + " cannot be obtained from object in event store" + " (" +
226 System::typeinfoName( typeid( *dataObj ) ) + ").",
227 "Wrong DataObjectType", StatusCode::FAILURE );
228 }
229 }
230 return ( *m_converter )( dataObj );
231}
232
233//---------------------------------------------------------------------------
235
236template <typename T>
237class DataObjectHandle<Gaudi::NamedRange_<T>> : public DataObjectHandleBase {
238public:
239 using ValueType = std::remove_cv_t<std::remove_pointer_t<typename T::value_type>>;
241
243
247 Range get() const;
248
249 std::string pythonRepr() const override {
250 return ::details::replace_all( DataObjectHandleBase::pythonRepr(), default_type,
252 }
253
254private:
255 mutable ::details::Converter_t<Range> m_converter = nullptr;
256};
257
258template <typename ValueType>
259auto DataObjectHandle<Gaudi::NamedRange_<ValueType>>::get() const -> Range {
260 auto dataObj = fetch();
261 if ( !dataObj ) {
262 throw GaudiException( "Cannot retrieve \'" + objKey() + "\' from transient store.",
263 m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
264 }
265 if ( !m_converter ) {
267 if ( !m_converter ) {
268 throw GaudiException( "The type requested for " + objKey() + " (" + System::typeinfoName( typeid( ValueType ) ) +
269 ")" + " cannot be obtained from object in event store" + " (" +
270 System::typeinfoName( typeid( *dataObj ) ) + ").",
271 "Wrong DataObjectType", StatusCode::FAILURE );
272 }
273 }
274 return ( *m_converter )( dataObj );
275}
276
277//
278//---------------------------------------------------------------------------
280
281template <typename T>
282class DataObjectHandle<std::optional<Gaudi::NamedRange_<T>>> : public DataObjectHandleBase {
283public:
284 using ValueType = std::remove_cv_t<std::remove_pointer_t<typename T::value_type>>;
286
288
292 std::optional<Range> get() const;
293
294 std::string pythonRepr() const override {
295 return ::details::replace_all( DataObjectHandleBase::pythonRepr(), default_type,
296 System::typeinfoName( typeid( std::optional<Gaudi::NamedRange_<T>> ) ) );
297 }
298
299private:
300 mutable ::details::Converter_t<Range> m_converter = nullptr;
301};
302
303template <typename ValueType>
304auto DataObjectHandle<std::optional<Gaudi::NamedRange_<ValueType>>>::get() const -> std::optional<Range> {
305 auto dataObj = fetch();
306 if ( !dataObj ) return std::nullopt;
307 if ( !m_converter ) {
309 if ( !m_converter ) {
310 throw GaudiException( "The type requested for " + objKey() + " (" + System::typeinfoName( typeid( ValueType ) ) +
311 ")" + " cannot be obtained from object in event store" + " (" +
312 System::typeinfoName( typeid( *dataObj ) ) + ").",
313 "Wrong DataObjectType", StatusCode::FAILURE );
314 }
315 }
316 return ( *m_converter )( dataObj );
317}
318
319//---------------------------------------------------------------------------
321template <typename T>
323public:
325
329 T* get() const { return &_get( true )->getData(); }
330 T* getIfExists() const {
331 auto data = _get( false );
332 return data ? &data->getData() : nullptr;
333 }
334
338 const T* put( T&& obj ) const {
339 assert( m_init );
340 auto objectp = std::make_unique<AnyDataWrapper<T>>( std::move( obj ) );
341 if ( auto sc = m_EDS->registerObject( objKey(), objectp.get() ); sc.isFailure() ) {
342 throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<AnyDataWrapper<T>>::put", sc );
343 }
344 return &objectp.release()->getData();
345 }
346
350 std::optional<std::size_t> size() const { return _get()->size(); }
351
352 std::string pythonRepr() const override {
353 return ::details::replace_all( DataObjectHandleBase::pythonRepr(), default_type,
354 System::typeinfoName( typeid( T ) ) );
355 }
356
357private:
358 AnyDataWrapper<T>* _get( bool mustExist ) const {
359 auto obj = fetch();
360 if ( !obj ) {
361 if ( mustExist ) {
362 throw GaudiException( "Cannot retrieve \'" + objKey() + "\' from transient store.",
363 m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
364
365 } else {
366 return nullptr;
367 }
368 }
370 return static_cast<AnyDataWrapper<T>*>( obj );
371 }
372 mutable bool m_goodType = false;
373};
374
375//---------------------------------------------------------------------------
377template <typename View, typename Owned>
379public:
381
385 View* get() const { return &_get( true )->getData(); }
386 View* getIfExists() const {
387 auto data = _get( false );
388 return data ? &data->getData() : nullptr;
389 }
390
394 const View* put( std::unique_ptr<AnyDataWithViewWrapper<View, Owned>> objectp ) const {
395 assert( m_init );
396 if ( auto sc = m_EDS->registerObject( objKey(), objectp.get() ); sc.isFailure() ) {
397 throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<AnyDataWithViewWrapper<T>::put", sc );
398 }
399 return &objectp.release()->getData();
400 }
401 const View* put( Owned&& obj ) const {
402 return put( std::make_unique<AnyDataWithViewWrapper<View, Owned>>( std::move( obj ) ) );
403 }
404
408 std::optional<std::size_t> size() const { return _get()->size(); }
409
410 std::string pythonRepr() const override {
411 return ::details::replace_all( DataObjectHandleBase::pythonRepr(), default_type,
412 System::typeinfoName( typeid( View ) ) );
413 }
414
415private:
416 AnyDataWithViewWrapper<View, Owned>* _get( bool mustExist ) const {
417 auto obj = fetch();
418 if ( !obj ) {
419 if ( mustExist ) {
420 throw GaudiException( "Cannot retrieve \'" + objKey() + "\' from transient store.",
421 m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
422
423 } else {
424 return nullptr;
425 }
426 }
428 return static_cast<AnyDataWithViewWrapper<View, Owned>*>( obj );
429 }
430 mutable bool m_goodType = false;
431};
432
433//---------------------------- user-facing interface ----------
434namespace details {
435 template <typename T, typename U = T>
437 template <typename T, typename U = T>
439} // namespace details
440
441template <typename T>
443 template <typename... Args, std::size_t... Is>
444 DataObjectReadHandle( std::tuple<Args...>&& args, std::index_sequence<Is...> )
445 : DataObjectReadHandle( std::get<Is>( std::move( args ) )... ) {}
446
447public:
450
453 template <std::derived_from<IProperty> OWNER, typename K>
454 DataObjectReadHandle( OWNER* owner, std::string propertyName, K key = {}, std::string doc = "" )
455 : ::details::ReadHandle<T>( owner, Gaudi::DataHandle::Reader, std::move( propertyName ), std::move( key ),
456 std::move( doc ) ) {}
457
458 template <typename... Args>
459 DataObjectReadHandle( std::tuple<Args...>&& args )
460 : DataObjectReadHandle( std::move( args ), std::index_sequence_for<Args...>{} ) {}
461};
462
463template <typename T, typename U = T>
465 template <typename... Args, std::size_t... Is>
466 DataObjectWriteHandle( std::tuple<Args...>&& args, std::index_sequence<Is...> )
467 : DataObjectWriteHandle( std::get<Is>( std::move( args ) )... ) {}
468
469public:
472
475 template <std::derived_from<IProperty> OWNER, typename K>
476 DataObjectWriteHandle( OWNER* owner, std::string propertyName, K key = {}, std::string doc = "" )
477 : ::details::WriteHandle<T, U>( owner, Gaudi::DataHandle::Writer, std::move( propertyName ), std::move( key ),
478 std::move( doc ) ) {}
479
480 template <typename... Args>
481 DataObjectWriteHandle( std::tuple<Args...>&& args )
482 : DataObjectWriteHandle( std::move( args ), std::index_sequence_for<Args...>{} ) {}
483};
This file has been imported from LoKi project "C++ ToolKit for Smart and Friendly Physics Analysis"
SmartIF< IDataProviderSvc > m_EDS
DataObjectHandleBase(DataObjID k, Gaudi::DataHandle::Mode a, IDataHandleHolder *owner)
DataObject * fetch() const
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
T * get() const
Retrieve object from transient data store.
mutable ::details::Converter_t< Range > m_converter
std::remove_cv_t< std::remove_pointer_t< typename T::value_type > > ValueType
std::string pythonRepr() const override
std::remove_cv_t< std::remove_pointer_t< typename T::value_type > > ValueType
T * get() const
Retrieve object from transient data store.
std::string pythonRepr() const override
AnyDataWithViewWrapper< View, Owned > * _get(bool mustExist) const
T * getIfExists() const
Bypass check of existence of object in transient store Only uses main location of the.
std::string pythonRepr() const override
T * put(std::unique_ptr< T > object) const
Register object in transient store.
Range get() const
Retrieve object from transient data store.
View * get() const
Retrieve object from transient data store.
std::optional< std::size_t > size() const
Size of boxed item, if boxed item has a 'size' method.
mutable ::details::Converter_t< Range > m_converter
const T * put(T &&obj) const
Register object in transient store.
std::optional< std::size_t > size() const
Size of boxed item, if boxed item has a 'size' method.
Gaudi::Range_< typename ValueType::ConstVector > Range
T * get(bool mustExist) const
Try to retrieve from the transient store.
Gaudi::NamedRange_< typename ValueType::ConstVector > Range
AnyDataWrapper< T > * _get(bool mustExist) const
Range get() const
Retrieve object from transient data store.
std::optional< Range > get() const
Retrieve object from transient data store.
Gaudi::NamedRange_< typename ValueType::ConstVector > Range
T * getOrCreate() const
Get object from store or create a new one if it doesn't exist.
DataObjectHandleBase(DataObjID k, Gaudi::DataHandle::Mode a, IDataHandleHolder *owner)
bool exist() const
Check the existence of the object in the transient store.
std::remove_cv_t< std::remove_pointer_t< typename T::value_type > > ValueType
const View * put(std::unique_ptr< AnyDataWithViewWrapper< View, Owned > > objectp) const
Register object in transient store.
A DataObject is the base class of any identifiable object on any data store.
Definition DataObject.h:37
IRegistry * registry() const
Get pointer to Registry.
Definition DataObject.h:79
DataObjectReadHandle(std::tuple< Args... > &&args)
DataObjectReadHandle(OWNER *owner, std::string propertyName, K key={}, std::string doc="")
Autodeclaring constructor with property name, mode, key and documentation.
DataObjectReadHandle(const DataObjID &k, IDataHandleHolder *owner)
DataObjectReadHandle(std::tuple< Args... > &&args, std::index_sequence< Is... >)
DataObjectWriteHandle(const DataObjID &k, IDataHandleHolder *owner)
DataObjectWriteHandle(std::tuple< Args... > &&args)
DataObjectWriteHandle(std::tuple< Args... > &&args, std::index_sequence< Is... >)
DataObjectWriteHandle(OWNER *owner, std::string propertyName, K key={}, std::string doc="")
Autodeclaring constructor with property name, mode, key and documentation.
static const std::string default_type
Definition DataHandle.h:82
virtual std::string pythonRepr() const
IDataHandleHolder * m_owner
Definition DataHandle.h:80
virtual IDataHandleHolder * owner() const
Definition DataHandle.h:52
virtual const std::string & objKey() const
Definition DataHandle.h:59
DataHandle(DataObjID k, Mode a=Reader, IDataHandleHolder *owner=nullptr)
Definition DataHandle.h:41
Useful class for representation of "sequence" of the objects through the range of valid iterators.
Definition Range.h:81
Define general base for Gaudi exception.
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto FAILURE
Definition StatusCode.h:100
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:260
Converter_t< Range > select_range_converter(const DataObject *obj)
DataObjectHandle< Payload_t< Gaudi::DataHandle::Reader, T, U > > ReadHandle
T(*)(const DataObject *) Converter_t
DataObjectHandle< Payload_t< Gaudi::DataHandle::Writer, T, U > > WriteHandle
Range make_range(const DataObject *obj)
bool verifyType(const DataObject *dataObj)
std::string replace_all(std::string str, std::string_view from, std::string_view to)
auto begin(reverse_wrapper< T > &w)
Definition reverse.h:46
auto end(reverse_wrapper< T > &w)
Definition reverse.h:51
typename Payload_helper< mode, T, U >::type Payload_t
STL namespace.
std::conditional_t< std::is_base_of_v< DataObject, T > &&std::is_same_v< T, U >, T, std::conditional_t< std::is_same_v< T, U >, AnyDataWrapper< std::remove_const_t< T > >, AnyDataWithViewWrapper< std::remove_const_t< T >, std::remove_const_t< U > > > > type