The Gaudi Framework  v32r0 (3325bb39)
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  template <typename T>
18  using Converter_t = T ( * )( const DataObject* );
19 
20  template <typename Range, typename StorageType>
21  Range make_range( const DataObject* obj ) {
22  auto c = static_cast<const StorageType*>( obj );
23  if ( UNLIKELY( !c ) ) return Range();
24  using std::begin;
25  using std::end;
26  auto first = begin( *c );
27  auto last = end( *c );
28  // return Range( first, last );
29  auto _first = reinterpret_cast<typename Range::const_iterator*>( &first );
30  auto _last = reinterpret_cast<typename Range::const_iterator*>( &last );
31  return Range( *_first, *_last );
32  }
33 
34  template <typename ValueType, typename Range = Gaudi::Range_<typename ValueType::ConstVector>>
36  using Selection = typename ValueType::Selection;
37  auto sel = dynamic_cast<const Selection*>( obj );
38  if ( sel ) return &make_range<Range, typename ValueType::Selection>;
39  auto con = dynamic_cast<std::add_const_t<typename ValueType::Container>*>( obj );
40  if ( con ) return &make_range<Range, typename ValueType::Container>;
41  return nullptr;
42  }
43 
44  template <typename T>
45  bool verifyType( const DataObject* dataObj ) {
46  using Type = std::add_const_t<T>;
47  assert( dataObj != nullptr );
48  auto obj = dynamic_cast<Type*>( dataObj );
49  bool ok = ( obj != nullptr );
50  if ( !ok ) {
51  const auto* registry = dataObj->registry();
52  throw GaudiException( "The type expected for " + registry->identifier() + " is " +
53  System::typeinfoName( typeid( Type ) ) +
54  " and is different from the one of the object in the store which is " +
55  System::typeinfoName( typeid( *dataObj ) ) + ".",
56  "Wrong DataObjectType", StatusCode::FAILURE );
57  }
58  assert( obj == static_cast<Type*>( dataObj ) );
59  return ok;
60  }
61 
62  template <typename T>
63  struct Payload_helper {
64  using type = std::conditional_t<std::is_base_of<DataObject, T>::value, T, AnyDataWrapper<T>>;
65  };
66  template <typename T>
67  struct Payload_helper<Gaudi::Range_<T>> {
69  };
70 
71  template <typename T>
73 } // namespace details
74 
75 //---------------------------------------------------------------------------
76 
87 //---------------------------------------------------------------------------
88 
89 template <typename T>
91 public:
93 
97  T* get() const { return get( true ); }
98 
103  T* getIfExists() const { return get( false ); }
104 
108  bool exist() const { return get( false ) != nullptr; }
109 
113  T* getOrCreate() const;
114 
118  T* put( std::unique_ptr<T> object ) const;
119 
120  // [[deprecated("please pass a std::unique_ptr instead of a raw pointer")]]
121  T* put( T* object ) const { return put( std::unique_ptr<T>( object ) ); }
122 
123 private:
124  T* get( bool mustExist ) const;
125  mutable bool m_goodType = false;
126 };
127 
128 //---------------------------------------------------------------------------
129 //
137 template <typename T>
138 T* DataObjectHandle<T>::get( bool mustExist ) const {
139  auto dataObj = fetch();
140  if ( UNLIKELY( !dataObj ) ) {
141  if ( mustExist ) { // Problems in getting from the store
142  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
143  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
144  }
145  return nullptr;
146  }
147  if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<T>( dataObj );
148  return static_cast<T*>( dataObj );
149 }
150 
151 //---------------------------------------------------------------------------
152 template <typename T>
154  assert( m_init );
155  StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() );
156  if ( !rc.isSuccess() ) {
157  throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE );
158  }
159  return objectp.release();
160 }
161 
162 //---------------------------------------------------------------------------
163 template <typename T>
165  T* obj = get( false );
166  return obj ? obj : put( std::make_unique<T>() );
167 }
168 
169 //---------------------------------------------------------------------------
171 
172 template <typename T>
173 class DataObjectHandle<Gaudi::Range_<T>> : public DataObjectHandleBase {
174 public:
175  using ValueType = std::remove_cv_t<std::remove_pointer_t<typename T::value_type>>;
177 
179 
183  Range get() const;
184 
185 private:
186  mutable ::details::Converter_t<Range> m_converter = nullptr;
187 };
188 
189 template <typename ValueType>
191  auto dataObj = fetch();
192  if ( UNLIKELY( !dataObj ) ) {
193  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
194  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
195  }
196  if ( UNLIKELY( !m_converter ) ) {
197  m_converter = ::details::select_range_converter<ValueType>( dataObj );
198  if ( !m_converter ) {
199  throw GaudiException( "The type requested for " + objKey() + " (" + System::typeinfoName( typeid( ValueType ) ) +
200  ")" + " cannot be obtained from object in event store" + " (" +
201  System::typeinfoName( typeid( *dataObj ) ) + ").",
202  "Wrong DataObjectType", StatusCode::FAILURE );
203  }
204  }
205  return ( *m_converter )( dataObj );
206 }
207 
208 //---------------------------------------------------------------------------
210 template <typename T>
212 public:
214 
218  T* get() const { return &_get( true )->getData(); }
219  T* getIfExists() const {
220  auto data = _get( false );
221  if ( data ) {
222  return &data->getData();
223  } else {
224  return nullptr;
225  }
226  }
227 
231  const T* put( T&& object ) const;
232 
236  boost::optional<std::size_t> size() const { return _get()->size(); }
237 
238 private:
239  AnyDataWrapper<T>* _get( bool mustExist ) const;
240  mutable bool m_goodType = false;
241 };
242 
243 //---------------------------------------------------------------------------
244 
245 template <typename T>
247  auto obj = fetch();
248  if ( UNLIKELY( !obj ) ) {
249  if ( mustExist ) {
250  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
251  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
252 
253  } else {
254  return nullptr;
255  }
256  }
257  if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<AnyDataWrapper<T>>( obj );
258  return static_cast<AnyDataWrapper<T>*>( obj );
259 }
260 
261 //---------------------------------------------------------------------------
262 
263 template <typename T>
264 const T* DataObjectHandle<AnyDataWrapper<T>>::put( T&& obj ) const {
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  template <typename... Args, std::size_t... Is>
279  DataObjectReadHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
280  : DataObjectReadHandle( std::get<Is>( args )... ) {}
281 
282 public:
285 
288  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of<IProperty, OWNER>::value>>
289  DataObjectReadHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
291  std::move( doc ) ) {}
292 
293  template <typename... Args>
295  : DataObjectReadHandle( args, std::index_sequence_for<Args...>{} ) {}
296 };
297 
298 template <typename T>
299 class DataObjectWriteHandle : public DataObjectHandle<::details::Payload_t<T>> {
300  template <typename... Args, std::size_t... Is>
301  DataObjectWriteHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
302  : DataObjectWriteHandle( std::get<Is>( args )... ) {}
303 
304 public:
307 
310  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of<IProperty, OWNER>::value>>
311  DataObjectWriteHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
313  std::move( doc ) ) {}
314 
315  template <typename... Args>
317  : DataObjectWriteHandle( args, std::index_sequence_for<Args...>{} ) {}
318 };
319 
320 #endif
class MergingTransformer< Out(const vector_of_const_< In > true
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
#define UNLIKELY(x)
Definition: Kernel.h:89
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:298
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:42
bool isSuccess() const
Definition: StatusCode.h:267
sel
Definition: IOTest.py:93
STL namespace.
T end(T...args)
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:72
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:50
This file has been imported from LoKi project "C++ ToolKit for Smart and Friendly Physics Analysis" ...
def _get(self, location)
Definition: GaudiAlgs.py:406
T * put(std::unique_ptr< T > object) const
Register object in transient store.
DataObjectReadHandle(const std::tuple< Args... > &args, std::index_sequence< Is... >)
T * put(T *object) const
T move(T...args)
T get(T...args)
std::conditional_t< std::is_base_of< DataObject, T >::value, T, AnyDataWrapper< T >> type
T(*)(const DataObject *) Converter_t
STL class.
DataObjectHandleBase GaudiKernel/DataObjectHandleBase.h.
T begin(T...args)
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:37
T * getOrCreate() const
Get object from store or create a new one if it doesn&#39;t exist.
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)
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)
class MergingTransformer< Out(const vector_of_const_< In > false
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
std::remove_cv_t< std::remove_pointer_t< typename T::value_type >> ValueType
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... >)