The Gaudi Framework  v30r3 (a5ef0a68)
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 <type_traits>
13 
14 //---------------------------------------------------------------------------
15 //
16 namespace details
17 {
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  {
24  auto c = static_cast<const StorageType*>( obj );
25  if ( UNLIKELY( !c ) ) return Range();
26  using std::begin;
27  using std::end;
28  auto first = begin( *c );
29  auto last = end( *c );
30  // return Range( first, last );
31  auto _first = reinterpret_cast<typename Range::const_iterator*>( &first );
32  auto _last = reinterpret_cast<typename Range::const_iterator*>( &last );
33  return Range( *_first, *_last );
34  }
35 
36  template <typename ValueType, typename Range = Gaudi::Range_<typename ValueType::ConstVector>>
38  {
39  using Selection = typename ValueType::Selection;
40  auto sel = dynamic_cast<const Selection*>( obj );
41  if ( sel ) return &make_range<Range, typename ValueType::Selection>;
42  auto con = dynamic_cast<std::add_const_t<typename ValueType::Container>*>( obj );
43  if ( con ) return &make_range<Range, typename ValueType::Container>;
44  return nullptr;
45  }
46 
47  template <typename T>
48  bool verifyType( const DataObject* dataObj )
49  {
50  using Type = std::add_const_t<T>;
51  assert( dataObj != nullptr );
52  auto obj = dynamic_cast<Type*>( dataObj );
53  bool ok = ( obj != nullptr );
54  if ( !ok ) {
55  const auto* registry = dataObj->registry();
56  throw GaudiException( "The type expected for " + registry->identifier() + " is " +
57  System::typeinfoName( typeid( Type ) ) +
58  " and is different from the one of the object in the store.",
59  "Wrong DataObjectType", StatusCode::FAILURE );
60  }
61  assert( obj == static_cast<Type*>( dataObj ) );
62  return ok;
63  }
64 
65  template <typename T>
66  struct Payload_helper {
67  using type = std::conditional_t<std::is_base_of<DataObject, T>::value, T, AnyDataWrapper<T>>;
68  };
69  template <typename T>
70  struct Payload_helper<Gaudi::Range_<T>> {
72  };
73 
74  template <typename T>
76 }
77 
78 //---------------------------------------------------------------------------
79 
90 //---------------------------------------------------------------------------
91 
92 template <typename T>
94 {
95 public:
97 
101  T* get() const { return get( true ); }
102 
107  T* getIfExists() const { return get( false ); }
108 
112  bool exist() const { return get( false ) != nullptr; }
113 
117  T* getOrCreate();
118 
122  T* put( std::unique_ptr<T> object );
123 
124  // [[deprecated("please pass a std::unique_ptr instead of a raw pointer")]]
125  T* put( T* object ) { return put( std::unique_ptr<T>( object ) ); }
126 
127 private:
128  T* get( bool mustExist ) const;
129  mutable bool m_goodType = false;
130 };
131 
132 //---------------------------------------------------------------------------
133 //
141 template <typename T>
142 T* DataObjectHandle<T>::get( bool mustExist ) const
143 {
144  auto dataObj = fetch();
145  if ( UNLIKELY( !dataObj ) ) {
146  if ( mustExist ) { // Problems in getting from the store
147  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
148  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
149  }
150  return nullptr;
151  }
152  if ( UNLIKELY( !m_goodType ) ) m_goodType = details::verifyType<T>( dataObj );
153  return static_cast<T*>( dataObj );
154 }
155 
156 //---------------------------------------------------------------------------
157 template <typename T>
159 {
160  assert( m_init );
161  StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() );
162  if ( !rc.isSuccess() ) {
163  throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE );
164  }
165  return objectp.release();
166 }
167 
168 //---------------------------------------------------------------------------
169 template <typename T>
171 {
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 {
182 public:
183  using ValueType = std::remove_cv_t<std::remove_pointer_t<typename T::value_type>>;
185 
187 
191  Range get() const;
192 
193 private:
194  mutable details::Converter_t<Range> m_converter = nullptr;
195 };
196 
197 template <typename ValueType>
199 {
200  auto dataObj = fetch();
201  if ( UNLIKELY( !dataObj ) ) {
202  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
203  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
204  }
205  if ( UNLIKELY( !m_converter ) ) {
206  m_converter = details::select_range_converter<ValueType>( dataObj );
207  if ( !m_converter ) {
208  throw GaudiException( "The type requested for " + objKey() + " cannot be obtained from object in event store",
209  "Wrong DataObjectType", StatusCode::FAILURE );
210  }
211  }
212  return ( *m_converter )( dataObj );
213 }
214 
215 //---------------------------------------------------------------------------
217 template <typename T>
219 {
220 public:
222 
226  const T* get() const { return &_get()->getData(); }
227 
231  const T* put( T&& object );
232 
236  boost::optional<std::size_t> size() const { return _get()->size(); }
237 
238 private:
239  const AnyDataWrapper<T>* _get() const;
240  mutable bool m_goodType = false;
241 };
242 
243 //---------------------------------------------------------------------------
244 
245 template <typename T>
247 {
248  auto obj = fetch();
249  if ( UNLIKELY( !obj ) ) {
250  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
251  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
252  }
253  if ( UNLIKELY( !m_goodType ) ) m_goodType = details::verifyType<AnyDataWrapper<T>>( obj );
254  return static_cast<const AnyDataWrapper<T>*>( obj );
255 }
256 
257 //---------------------------------------------------------------------------
258 
259 template <typename T>
261 {
262  assert( m_init );
263  auto objectp = std::make_unique<AnyDataWrapper<T>>( std::move( obj ) );
264  StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() );
265  if ( rc.isFailure() ) {
266  throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE );
267  }
268  return &objectp.release()->getData();
269 }
270 
271 //---------------------------- user-facing interface ----------
272 
273 template <typename T>
274 class DataObjectReadHandle : public DataObjectHandle<details::Payload_t<T>>
275 {
276  template <typename... Args, std::size_t... Is>
277  DataObjectReadHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
278  : DataObjectReadHandle( std::get<Is>( args )... )
279  {
280  }
281 
282 public:
285  {
286  }
287 
290  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of<IProperty, OWNER>::value>>
291  DataObjectReadHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
293  std::move( doc ) )
294  {
295  }
296 
297  template <typename... Args>
299  : DataObjectReadHandle( args, std::index_sequence_for<Args...>{} )
300  {
301  }
302 };
303 
304 template <typename T>
305 class DataObjectWriteHandle : public DataObjectHandle<details::Payload_t<T>>
306 {
307  template <typename... Args, std::size_t... Is>
308  DataObjectWriteHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
309  : DataObjectWriteHandle( std::get<Is>( args )... )
310  {
311  }
312 
313 public:
316  {
317  }
318 
321  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of<IProperty, OWNER>::value>>
322  DataObjectWriteHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
324  std::move( doc ) )
325  {
326  }
327 
328  template <typename... Args>
330  : DataObjectWriteHandle( args, std::index_sequence_for<Args...>{} )
331  {
332  }
333 };
334 
335 #endif
#define UNLIKELY(x)
Definition: Kernel.h:122
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Define general base for Gaudi exception.
Gaudi::Range_< typename ValueType::ConstVector > Range
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:332
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:44
bool isSuccess() const
Definition: StatusCode.h:287
sel
Definition: IOTest.py:95
STL namespace.
T end(T...args)
T * put(T *object)
bool verifyType(const DataObject *dataObj)
bool exist() const
Check the existence of the object in the transient store.
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:73
T release(T...args)
T * get() const
Retrieve object from transient data store.
STL class.
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
Definition: AlgTool.h:26
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:51
This file has been imported from LoKi project "C++ ToolKit for Smart and Friendly Physics Analysis" ...
def _get(self, location)
Definition: GaudiAlgs.py:405
DataObjectReadHandle(const std::tuple< Args... > &args, std::index_sequence< Is... >)
T move(T...args)
T get(T...args)
std::conditional_t< std::is_base_of< DataObject, T >::value, T, AnyDataWrapper< T >> type
T * put(std::unique_ptr< T > object)
Register object in transient store.
T(*)(const DataObject *) Converter_t
STL class.
DataObjectHandleBase GaudiKernel/DataObjectHandleBase.h.
T begin(T...args)
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:38
Useful class for representation of "sequence" of the objects through the range of valid iterators...
Definition: Range.h:88
Converter_t< Range > select_range_converter(const DataObject *obj)
boost::optional< std::size_t > size() const
Size of boxed item, if boxed item has a &#39;size&#39; method.
T * getIfExists() const
Bypass check of existence of object in transient store Only uses main location of the...
DataObjectWriteHandle(const DataObjID &k, IDataHandleHolder *owner)
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:83
std::remove_cv_t< std::remove_pointer_t< typename T::value_type >> ValueType
Helper functions to set/get the application return code.
Definition: __init__.py:1
T * getOrCreate()
Get object from store or create a new one if it doesn&#39;t exist.
Out1 * put(DataObjectHandle< Out1 > &out_handle, Out2 &&out)
DataObjectHandleBase(const DataObjID &k, Gaudi::DataHandle::Mode a, IDataHandleHolder *owner)
DataObjectWriteHandle(const std::tuple< Args... > &args, std::index_sequence< Is... >)