The Gaudi Framework  v30r4 (9b837755)
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 which is " +
59  System::typeinfoName( typeid( *dataObj ) ) + ".",
60  "Wrong DataObjectType", StatusCode::FAILURE );
61  }
62  assert( obj == static_cast<Type*>( dataObj ) );
63  return ok;
64  }
65 
66  template <typename T>
67  struct Payload_helper {
68  using type = std::conditional_t<std::is_base_of<DataObject, T>::value, T, AnyDataWrapper<T>>;
69  };
70  template <typename T>
71  struct Payload_helper<Gaudi::Range_<T>> {
73  };
74 
75  template <typename T>
77 }
78 
79 //---------------------------------------------------------------------------
80 
91 //---------------------------------------------------------------------------
92 
93 template <typename T>
95 {
96 public:
98 
102  T* get() const { return get( true ); }
103 
108  T* getIfExists() const { return get( false ); }
109 
113  bool exist() const { return get( false ) != nullptr; }
114 
118  T* getOrCreate();
119 
123  T* put( std::unique_ptr<T> object );
124 
125  // [[deprecated("please pass a std::unique_ptr instead of a raw pointer")]]
126  T* put( T* object ) { return put( std::unique_ptr<T>( object ) ); }
127 
128 private:
129  T* get( bool mustExist ) const;
130  mutable bool m_goodType = false;
131 };
132 
133 //---------------------------------------------------------------------------
134 //
142 template <typename T>
143 T* DataObjectHandle<T>::get( bool mustExist ) const
144 {
145  auto dataObj = fetch();
146  if ( UNLIKELY( !dataObj ) ) {
147  if ( mustExist ) { // Problems in getting from the store
148  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
149  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
150  }
151  return nullptr;
152  }
153  if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<T>( dataObj );
154  return static_cast<T*>( dataObj );
155 }
156 
157 //---------------------------------------------------------------------------
158 template <typename T>
160 {
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 {
173  T* obj = get( false );
174  return obj ? obj : put( std::make_unique<T>() );
175 }
176 
177 //---------------------------------------------------------------------------
179 
180 template <typename T>
181 class DataObjectHandle<Gaudi::Range_<T>> : public DataObjectHandleBase
182 {
183 public:
184  using ValueType = std::remove_cv_t<std::remove_pointer_t<typename T::value_type>>;
186 
188 
192  Range get() const;
193 
194 private:
195  mutable ::details::Converter_t<Range> m_converter = nullptr;
196 };
197 
198 template <typename ValueType>
200 {
201  auto dataObj = fetch();
202  if ( UNLIKELY( !dataObj ) ) {
203  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
204  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
205  }
206  if ( UNLIKELY( !m_converter ) ) {
207  m_converter = ::details::select_range_converter<ValueType>( dataObj );
208  if ( !m_converter ) {
209  throw GaudiException( "The type requested for " + objKey() + " (" + System::typeinfoName( typeid( ValueType ) ) +
210  ")" + " cannot be obtained from object in event store" + " (" +
211  System::typeinfoName( typeid( *dataObj ) ) + ").",
212  "Wrong DataObjectType", StatusCode::FAILURE );
213  }
214  }
215  return ( *m_converter )( dataObj );
216 }
217 
218 //---------------------------------------------------------------------------
220 template <typename T>
222 {
223 public:
225 
229  const T* get() const { return &_get()->getData(); }
230 
234  const T* put( T&& object );
235 
239  boost::optional<std::size_t> size() const { return _get()->size(); }
240 
241 private:
242  const AnyDataWrapper<T>* _get() const;
243  mutable bool m_goodType = false;
244 };
245 
246 //---------------------------------------------------------------------------
247 
248 template <typename T>
250 {
251  auto obj = fetch();
252  if ( UNLIKELY( !obj ) ) {
253  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
254  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
255  }
256  if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<AnyDataWrapper<T>>( obj );
257  return static_cast<const AnyDataWrapper<T>*>( obj );
258 }
259 
260 //---------------------------------------------------------------------------
261 
262 template <typename T>
264 {
265  assert( m_init );
266  auto objectp = std::make_unique<AnyDataWrapper<T>>( std::move( obj ) );
267  StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() );
268  if ( rc.isFailure() ) {
269  throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE );
270  }
271  return &objectp.release()->getData();
272 }
273 
274 //---------------------------- user-facing interface ----------
275 
276 template <typename T>
277 class DataObjectReadHandle : public DataObjectHandle<::details::Payload_t<T>>
278 {
279  template <typename... Args, std::size_t... Is>
280  DataObjectReadHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
281  : DataObjectReadHandle( std::get<Is>( args )... )
282  {
283  }
284 
285 public:
288  {
289  }
290 
293  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of<IProperty, OWNER>::value>>
294  DataObjectReadHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
296  std::move( doc ) )
297  {
298  }
299 
300  template <typename... Args>
302  : DataObjectReadHandle( args, std::index_sequence_for<Args...>{} )
303  {
304  }
305 };
306 
307 template <typename T>
308 class DataObjectWriteHandle : public DataObjectHandle<::details::Payload_t<T>>
309 {
310  template <typename... Args, std::size_t... Is>
311  DataObjectWriteHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
312  : DataObjectWriteHandle( std::get<Is>( args )... )
313  {
314  }
315 
316 public:
319  {
320  }
321 
324  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of<IProperty, OWNER>::value>>
325  DataObjectWriteHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
327  std::move( doc ) )
328  {
329  }
330 
331  template <typename... Args>
333  : DataObjectWriteHandle( args, std::index_sequence_for<Args...>{} )
334  {
335  }
336 };
337 
338 #endif
#define UNLIKELY(x)
Definition: Kernel.h:89
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)
DataObjectHandleBase(const DataObjID &k, Gaudi::v1::DataHandle::Mode a, IDataHandleHolder *owner)
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
Entity which holds DataHandles and can track the associated data dependencies for the Scheduler...
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)
DataObjectWriteHandle(const std::tuple< Args... > &args, std::index_sequence< Is... >)