Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  const T* get() const { return &_get()->getData(); }
219 
223  const T* put( T&& object ) const;
224 
228  boost::optional<std::size_t> size() const { return _get()->size(); }
229 
230 private:
231  const AnyDataWrapper<T>* _get() const;
232  mutable bool m_goodType = false;
233 };
234 
235 //---------------------------------------------------------------------------
236 
237 template <typename T>
239  auto obj = fetch();
240  if ( UNLIKELY( !obj ) ) {
241  throw GaudiException( "Cannot retrieve " + objKey() + " from transient store.",
242  m_owner ? owner()->name() : "no owner", StatusCode::FAILURE );
243  }
244  if ( UNLIKELY( !m_goodType ) ) m_goodType = ::details::verifyType<AnyDataWrapper<T>>( obj );
245  return static_cast<const AnyDataWrapper<T>*>( obj );
246 }
247 
248 //---------------------------------------------------------------------------
249 
250 template <typename T>
251 const T* DataObjectHandle<AnyDataWrapper<T>>::put( T&& obj ) const {
252  assert( m_init );
253  auto objectp = std::make_unique<AnyDataWrapper<T>>( std::move( obj ) );
254  StatusCode rc = m_EDS->registerObject( objKey(), objectp.get() );
255  if ( rc.isFailure() ) {
256  throw GaudiException( "Error in put of " + objKey(), "DataObjectHandle<T>::put", StatusCode::FAILURE );
257  }
258  return &objectp.release()->getData();
259 }
260 
261 //---------------------------- user-facing interface ----------
262 
263 template <typename T>
264 class DataObjectReadHandle : public DataObjectHandle<::details::Payload_t<T>> {
265  template <typename... Args, std::size_t... Is>
266  DataObjectReadHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
267  : DataObjectReadHandle( std::get<Is>( args )... ) {}
268 
269 public:
272 
275  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of<IProperty, OWNER>::value>>
276  DataObjectReadHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
278  std::move( doc ) ) {}
279 
280  template <typename... Args>
282  : DataObjectReadHandle( args, std::index_sequence_for<Args...>{} ) {}
283 };
284 
285 template <typename T>
286 class DataObjectWriteHandle : public DataObjectHandle<::details::Payload_t<T>> {
287  template <typename... Args, std::size_t... Is>
288  DataObjectWriteHandle( const std::tuple<Args...>& args, std::index_sequence<Is...> )
289  : DataObjectWriteHandle( std::get<Is>( args )... ) {}
290 
291 public:
294 
297  template <typename OWNER, typename K, typename = std::enable_if_t<std::is_base_of<IProperty, OWNER>::value>>
298  DataObjectWriteHandle( OWNER* owner, std::string propertyName, const K& key = {}, std::string doc = "" )
300  std::move( doc ) ) {}
301 
302  template <typename... Args>
304  : DataObjectWriteHandle( args, std::index_sequence_for<Args...>{} ) {}
305 };
306 
307 #endif
#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:309
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)
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)
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:80
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
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... >)