The Gaudi Framework  v32r2 (46d42edc)
DataObjectHandle.h
Go to the documentation of this file.
1 #ifndef GAUDIHIVE_DATAOBJECTHANDLE_H
2 #define GAUDIHIVE_DATAOBJECTHANDLE_H
3 
10 #include "GaudiKernel/NamedRange.h"
11 
12 #include "boost/algorithm/string.hpp"
13 #include <type_traits>
14 
15 //---------------------------------------------------------------------------
16 //
17 namespace details {
18  template <typename T>
19  using Converter_t = T ( * )( const DataObject* );
20 
21  template <typename Range, typename StorageType>
22  Range make_range( const DataObject* obj ) {
23  auto c = static_cast<const StorageType*>( obj );
24  if ( UNLIKELY( !c ) ) return Range();
25  using std::begin;
26  using std::end;
27  auto first = begin( *c );
28  auto last = end( *c );
29  // return Range( first, last );
30  auto _first = reinterpret_cast<typename Range::const_iterator*>( &first );
31  auto _last = reinterpret_cast<typename Range::const_iterator*>( &last );
32  return Range( *_first, *_last );
33  }
34 
35  template <typename ValueType, typename Range = Gaudi::Range_<typename ValueType::ConstVector>>
37  using Selection = typename ValueType::Selection;
38  auto sel = dynamic_cast<const Selection*>( obj );
39  if ( sel ) return &make_range<Range, typename ValueType::Selection>;
40  auto con = dynamic_cast<std::add_const_t<typename ValueType::Container>*>( obj );
41  if ( con ) return &make_range<Range, typename ValueType::Container>;
42  return nullptr;
43  }
44 
45  template <typename T>
46  bool verifyType( const DataObject* dataObj ) {
47  using Type = std::add_const_t<T>;
48  assert( dataObj != nullptr );
49  auto obj = dynamic_cast<Type*>( dataObj );
50  bool ok = ( obj != nullptr );
51  if ( !ok ) {
52  const auto* registry = dataObj->registry();
53  throw GaudiException( "The type expected for " + registry->identifier() + " is " +
54  System::typeinfoName( typeid( Type ) ) +
55  " and is different from the one of the object in the store which is " +
56  System::typeinfoName( typeid( *dataObj ) ) + ".",
57  "Wrong DataObjectType", StatusCode::FAILURE );
58  }
59  assert( obj == static_cast<Type*>( dataObj ) );
60  return ok;
61  }
62 
63  template <typename T>
64  struct Payload_helper {
65  using type = std::conditional_t<std::is_base_of_v<DataObject, T>, T, AnyDataWrapper<T>>;
66  };
67  template <typename T>
68  struct Payload_helper<Gaudi::Range_<T>> {
70  };
71 
72  template <typename T>
74 } // namespace details
75 
76 //---------------------------------------------------------------------------
77 
88 //---------------------------------------------------------------------------
89 
90 template <typename T>
92 public:
94 
98  T* get() const { return get( true ); }
99 
104  T* getIfExists() const { return get( false ); }
105 
109  bool exist() const { return get( false ) != nullptr; }
110 
114  T* getOrCreate() const;
115 
119  T* put( std::unique_ptr<T> object ) const;
120 
121  // [[deprecated("please pass a std::unique_ptr instead of a raw pointer")]]
122  T* put( T* object ) const { return put( std::unique_ptr<T>( object ) ); }
123 
124  std::string pythonRepr() const override {
125  auto repr = DataObjectHandleBase::pythonRepr();
126  boost::replace_all( repr, default_type, System::typeinfoName( typeid( T ) ) );
127  return repr;
128  }
129 
130 private:
131  T* get( bool mustExist ) const;
132  mutable bool m_goodType = false;
133 };
134 
135 //---------------------------------------------------------------------------
136 //
144 template <typename T>
145 T* DataObjectHandle<T>::get( bool mustExist ) const {
146  auto dataObj = fetch();
147  if ( UNLIKELY( !dataObj ) ) {
148  if ( mustExist ) { // Problems in getting from the store
149  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
150  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
151  }
152  return nullptr;
153  }
154  if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<T>( dataObj );
155  return static_cast<T*>( dataObj );
156 }
157 
158 //---------------------------------------------------------------------------
159 template <typename T>
161  assert( m_init );
162  StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() );
163  if ( !rc.isSuccess() ) {
164  throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE );
165  }
166  return objectp.release();
167 }
168 
169 //---------------------------------------------------------------------------
170 template <typename T>
172  T* obj = get( false );
173  return obj ? obj : put( std::make_unique<T>() );
174 }
175 
176 //---------------------------------------------------------------------------
178 
179 template <typename T>
180 class DataObjectHandle<Gaudi::Range_<T>> : public DataObjectHandleBase {
181 public:
182  using ValueType = std::remove_cv_t<std::remove_pointer_t<typename T::value_type>>;
184 
186 
190  Range get() const;
191 
192  std::string pythonRepr() const override {
193  auto repr = DataObjectHandleBase::pythonRepr();
194  boost::replace_all( repr, default_type, System::typeinfoName( typeid( Gaudi::Range_<T> ) ) );
195  return repr;
196  }
197 
198 private:
199  mutable ::details::Converter_t<Range> m_converter = nullptr;
200 };
201 
202 template <typename ValueType>
203 auto DataObjectHandle<Gaudi::Range_<ValueType>>::get() const -> Range {
204  auto dataObj = fetch();
205  if ( UNLIKELY( !dataObj ) ) {
206  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
207  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
208  }
209  if ( UNLIKELY( !m_converter ) ) {
210  m_converter = ::details::select_range_converter<ValueType>( dataObj );
211  if ( !m_converter ) {
212  throw GaudiException( "The type requested for " + objKey() + " (" + System::typeinfoName( typeid( ValueType ) ) +
213  ")" + " cannot be obtained from object in event store" + " (" +
214  System::typeinfoName( typeid( *dataObj ) ) + ").",
215  "Wrong DataObjectType", StatusCode::FAILURE );
216  }
217  }
218  return ( *m_converter )( dataObj );
219 }
220 
221 //---------------------------------------------------------------------------
223 template <typename T>
225 public:
227 
231  T* get() const { return &_get( true )->getData(); }
232  T* getIfExists() const {
233  auto data = _get( false );
234  if ( data ) {
235  return &data->getData();
236  } else {
237  return nullptr;
238  }
239  }
240 
244  const T* put( T&& object ) const;
245 
249  std::optional<std::size_t> size() const { return _get()->size(); }
250 
251  std::string pythonRepr() const override {
252  auto repr = DataObjectHandleBase::pythonRepr();
253  boost::replace_all( repr, default_type, System::typeinfoName( typeid( T ) ) );
254  return repr;
255  }
256 
257 private:
258  AnyDataWrapper<T>* _get( bool mustExist ) const;
259  mutable bool m_goodType = false;
260 };
261 
262 //---------------------------------------------------------------------------
263 
264 template <typename T>
266  auto obj = fetch();
267  if ( UNLIKELY( !obj ) ) {
268  if ( mustExist ) {
269  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
270  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
271 
272  } else {
273  return nullptr;
274  }
275  }
276  if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<AnyDataWrapper<T>>( obj );
277  return static_cast<AnyDataWrapper<T>*>( obj );
278 }
279 
280 //---------------------------------------------------------------------------
281 
282 template <typename T>
283 const T* DataObjectHandle<AnyDataWrapper<T>>::put( T&& obj ) const {
284  assert( m_init );
285  auto objectp = std::make_unique<AnyDataWrapper<T>>( std::move( obj ) );
286  StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() );
287  if ( rc.isFailure() ) {
288  throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE );
289  }
290  return &objectp.release()->getData();
291 }
292 
293 //---------------------------- user-facing interface ----------
294 
295 template <typename T>
296 class DataObjectReadHandle : public DataObjectHandle<::details::Payload_t<T>> {
297  template <typename... Args, std::size_t... Is>
298  DataObjectReadHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
299  : DataObjectReadHandle( std::get<Is>( args )... ) {}
300 
301 public:
304 
307  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of_v<IProperty, OWNER>>>
308  DataObjectReadHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
310  std::move( doc ) ) {}
311 
312  template <typename... Args>
314  : DataObjectReadHandle( args, std::index_sequence_for<Args...>{} ) {}
315 };
316 
317 template <typename T>
318 class DataObjectWriteHandle : public DataObjectHandle<::details::Payload_t<T>> {
319  template <typename... Args, std::size_t... Is>
320  DataObjectWriteHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
321  : DataObjectWriteHandle( std::get<Is>( args )... ) {}
322 
323 public:
326 
329  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of_v<IProperty, OWNER>>>
330  DataObjectWriteHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
332  std::move( doc ) ) {}
333 
334  template <typename... Args>
336  : DataObjectWriteHandle( args, std::index_sequence_for<Args...>{} ) {}
337 };
338 
339 #endif
DataObjectWriteHandle(OWNER *owner, std::string propertyName, const K &key={}, std::string doc="")
Autodeclaring constructor with property name, mode, key and documentation.
#define UNLIKELY(x)
Definition: Kernel.h:96
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
bool exist() const
Check the existence of the object in the transient store.
Define general base for Gaudi exception.
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
Gaudi::Range_< typename ValueType::ConstVector > Range
T * get() const
Retrieve object from transient data store.
static const std::string default_type
DataObjectReadHandle(const DataObjID &k, IDataHandleHolder *owner)
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:42
virtual IDataHandleHolder * owner() const
Definition: DataHandle.h:40
DataObjectReadHandle(OWNER *owner, std::string propertyName, const K &key={}, std::string doc="")
Autodeclaring constructor with property name, mode, key and documentation.
std::string pythonRepr() const override
T * put(std::unique_ptr< T > object) const
Register object in transient store.
sel
Definition: IOTest.py:94
STL namespace.
T end(T... args)
bool verifyType(const DataObject *dataObj)
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
T * getIfExists() const
Bypass check of existence of object in transient store Only uses main location of the.
T release(T... args)
std::string pythonRepr() const override
STL class.
std::string pythonRepr() const override
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
Definition: AlgTool.h:26
T * put(T *object) const
std::optional< std::size_t > size() const
Size of boxed item, if boxed item has a 'size' method.
Range make_range(const DataObject *obj)
typename Payload_helper< T >::type Payload_t
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
This file has been imported from LoKi project "C++ ToolKit for Smart and Friendly Physics Analysis"
def _get(self, location)
Definition: GaudiAlgs.py:407
DataObjectReadHandle(const std::tuple< Args... > &args, std::index_sequence< Is... >)
T move(T... args)
T * getOrCreate() const
Get object from store or create a new one if it doesn't exist.
T * get() const
Retrieve object from transient data store.
T get(T... args)
std::conditional_t< std::is_base_of_v< DataObject, T >, T, AnyDataWrapper< T > > type
T(*)(const DataObject *) Converter_t
STL class.
DataObjectHandleBase GaudiKernel/DataObjectHandleBase.h.
T begin(T... args)
std::string pythonRepr() const override
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:37
Useful class for representation of "sequence" of the objects through the range of valid iterators.
Definition: Range.h:85
constexpr static const auto FAILURE
Definition: StatusCode.h:86
Converter_t< Range > select_range_converter(const DataObject *obj)
DataObjectWriteHandle(const DataObjID &k, IDataHandleHolder *owner)
DataObjectWriteHandle(const std::tuple< Args... > &args)
std::remove_cv_t< std::remove_pointer_t< typename T::value_type > > ValueType
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
Type
the list of available types for ntuples
Definition: TupleObj.h:79
DataObjectReadHandle(const std::tuple< Args... > &args)
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
DataObjectHandleBase(const DataObjID &k, Gaudi::DataHandle::Mode a, IDataHandleHolder *owner)
DataObjectWriteHandle(const std::tuple< Args... > &args, std::index_sequence< Is... >)