1 // Dear emacs, this is -*- c++ -*-
3 // Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 #ifndef XAODROOTACCESS_TEVENT_ICC
6 #define XAODROOTACCESS_TEVENT_ICC
12 #include "AthContainers/normalizedTypeinfoName.h"
16 /// This function works pretty much like StoreGateSvc::contains. It can be
17 /// used to check if an object with a given type having a given key can be
18 /// retrieved from the event.
20 /// @param key The key (branch name) of the object
21 /// @returns <code>kTRUE</code> if the object is available,
22 /// <code>kFALSE</code> otherwise
24 template< typename T >
25 ::Bool_t TEvent::contains( const std::string& key ) {
27 return contains( key, typeid( T ), kFALSE );
30 /// This function works pretty much like StoreGateSvc::transientContains.
31 /// It doesn't try to do any I/O operations, it just checks if an object
32 /// of a given type, with a given key, is already in memory.
34 /// @param key The key (branch name) of the object
35 /// @returns <code>kTRUE</code> if the object is already in memory,
36 /// <code>kFALSE</code> otherwise
38 template< typename T >
39 ::Bool_t TEvent::transientContains( const std::string& key ) const {
41 // Simply forward the call:
42 return transientContains( key, typeid( T ), kFALSE );
45 /// This function needs to be used when retrieving an object either from
46 /// the input or the output object list. The returned object can not be
49 /// @param obj The pointer that will be set to the object requested
50 /// @param key The key (branch name) of the object
51 /// @returns <code>kTRUE</code> if the operation was successful,
52 /// <code>kFALSE</code> if it wasn't
54 template< typename T >
55 StatusCode TEvent::retrieve( const T*& obj, const std::string& key ) {
57 // Look among the output objects first:
58 const void* result = getOutputObject( key, typeid( T ) );
59 // Check if it succeeded:
61 // Try the input then:
62 result = getInputObject( key, typeid( T ) );
64 ::Warning( "xAOD::TEvent::retrieve",
65 "Couldn't (const) retrieve \"%s/%s\"",
66 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
68 return StatusCode::RECOVERABLE;
71 // Even if there is an output object with this key, it may
72 // be an input object that was copied to the output. So let's
73 // try to silently retrieve an input object as well. This makes
74 // sure that the input/output object is updated for the current
76 getInputObject( key, typeid( T ), kTRUE );
79 // If we were successful:
80 obj = reinterpret_cast< const T* >( result );
81 return StatusCode::SUCCESS;
84 /// This function can be used to retrieve an object from the output list.
85 /// Since only output objects are considered, the function returns a
86 /// non-const object, allowing downstream code to modify an object that
87 /// was put into the event somewhere upstream.
89 /// @param obj The pointer that will be set to the object requested
90 /// @param key The key (branch name) of the object
91 /// @returns <code>kTRUE</code> if the operation was successful,
92 /// <code>kFALSE</code> if it wasn't
94 template< typename T >
95 StatusCode TEvent::retrieve( T*& obj, const std::string& key ) {
97 // Only look among the output objects in this case:
98 void* result = getOutputObject( key, typeid( T ) );
99 // Check if we found the object:
101 ::Warning( "xAOD::TEvent::retrieve",
102 "Couldn't (non-const) retrieve \"%s/%s\"",
103 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
105 return StatusCode::RECOVERABLE;
108 // If we were successful:
109 obj = reinterpret_cast< T* >( result );
110 return StatusCode::SUCCESS;
113 /// This function can be used to add an object to the output. The function
114 /// takes posession of the object, so the user code must not delete an
115 /// object that was added to an event.
117 /// @param obj Pointer to the object to be added to the event
118 /// @param key The key (branch name) to give the object
119 /// @param basketSize Basket size for the branch created from the object
120 /// @param splitLevel The split level of the branch to create
121 /// @returns <code>kTRUE</code> if the operation was successful,
122 /// <code>kFALSE</code> if it wasn't
124 template< typename T >
125 StatusCode TEvent::record( T* obj, const std::string& key,
126 ::Int_t basketSize, ::Int_t splitLevel ) {
128 // Just call the non-templated implementation:
129 return record( obj, SG::normalizedTypeinfoName( typeid( T ) ), key,
130 basketSize, splitLevel );
133 /// This function is used to add an object to the output. As the interface
134 /// clearly states, the function takes posession of the object given to it.
135 /// Since the user must give up ownership of the object in order to call this
136 /// function, it doesn't even need to be said that the user must not delete
137 /// the object by hand after calling this function.
139 /// @param obj Smart pointer to the object to tbe added to the event
140 /// @param key The key (branch name) to give the object
141 /// @param basketSize Basket size for the branch created from the object
142 /// @param splitLevel The split level of the branch to create
143 /// @returns <code>kTRUE</code> if the operation was successful,
144 /// <code>kFALSE</code> if it wasn't
146 template< typename T >
147 StatusCode TEvent::record( std::unique_ptr< T > obj, const std::string& key,
148 ::Int_t basketSize, ::Int_t splitLevel ) {
150 // Just call the non-templated implementation:
151 const StatusCode rc =
152 record( obj.get(), SG::normalizedTypeinfoName( typeid( T ) ), key,
153 basketSize, splitLevel );
154 if( ! rc.isSuccess() ) {
158 // If the record was successful, let's release the object from the unique
161 return StatusCode::SUCCESS;
164 /// This function works pretty much like StoreGateSvc::contains for metadata
165 /// objects. It can be used to check if a metadata object with a given type
166 /// having a given key can be (const) retrieved.
168 /// @param key The key (branch name) of the metadata object
169 /// @returns <code>kTRUE</code> if the object is available,
170 /// <code>kFALSE</code> otherwise
172 template< typename T >
173 ::Bool_t TEvent::containsMeta( const std::string& key ) {
175 return contains( key, typeid( T ), kTRUE );
178 /// This function works pretty much like StoreGateSvc::transientContains for
179 /// metadata objects. It doesn't try to do any I/O operations, it just checks
180 /// if an object of a given type, with a given key, can be retrieved in
183 /// @param key The key (branch name) of the metadata object
184 /// @returns <code>kTRUE</code> if the object is available for modifications,
185 /// <code>kFALSE</code> otherwise
187 template< typename T >
188 ::Bool_t TEvent::transientContainsMeta( const std::string& key ) const {
190 // Simply forward the call:
191 return transientContains( key, typeid( T ), kTRUE );
194 /// This function can be used to retrieve an object from the input metadata
197 /// @param obj The pointer that will be set to the object requested
198 /// @param key The key (branch name) of the object
199 /// @returns The usual StatusCode values
201 template< typename T >
202 StatusCode TEvent::retrieveMetaInput( const T*& obj,
203 const std::string& key ) {
205 // Only look among the output objects in this case:
206 const void* result = getInputObject( key, typeid( T ), kFALSE, kTRUE );
207 // Check if we found the object:
209 ::Warning( "xAOD::TEvent::retrieveMetaInput",
210 "Couldn't (const) retrieve \"%s/%s\"",
211 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
213 return StatusCode::RECOVERABLE;
216 // If we were successful:
217 obj = reinterpret_cast< const T* >( result );
218 return StatusCode::SUCCESS;
221 /// This function can be used to retrieve an object from the output metadata
224 /// @param obj The pointer that will be set to the object requested
225 /// @param key The key (branch name) of the object
226 /// @returns The usual StatusCode values
228 template< typename T >
229 StatusCode TEvent::retrieveMetaOutput( const T*& obj,
230 const std::string& key ) {
232 // Only look among the output objects in this case:
233 const void* result = getOutputObject( key, typeid( T ), kTRUE );
234 // Check if we found the object:
236 ::Warning( "xAOD::TEvent::retrieveMetaOutput",
237 "Couldn't (const) retrieve \"%s/%s\"",
238 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
240 return StatusCode::RECOVERABLE;
243 // If we were successful:
244 obj = reinterpret_cast< const T* >( result );
245 return StatusCode::SUCCESS;
248 /// This function can be used to retrieve an object from the output metadata
251 /// @param obj The pointer that will be set to the object requested
252 /// @param key The key (branch name) of the object
253 /// @returns The usual StatusCode values
255 template< typename T >
256 StatusCode TEvent::retrieveMetaOutput( T*& obj, const std::string& key ) {
258 // Only look among the output objects in this case:
259 void* result = getOutputObject( key, typeid( T ), kTRUE );
260 // Check if we found the object:
262 ::Warning( "xAOD::TEvent::retrieveMetaOutput",
263 "Couldn't (non-const) retrieve \"%s/%s\"",
264 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
266 return StatusCode::RECOVERABLE;
269 // If we were successful:
270 obj = reinterpret_cast< T* >( result );
271 return StatusCode::SUCCESS;
274 /// This function can be used to add a metadata object to the output.
275 /// The function takes posession of the object, so the user code must not
276 /// delete an object that was added to the output.
278 /// @param obj Pointer to the object to be added to the output metadata
279 /// @param key The key (branch name) to give the object
280 /// @param basketSize Basket size for the branch created from the object
281 /// @param splitLevel The split level of the branch to create
282 /// @returns <code>kTRUE</code> if the operation was successful,
283 /// <code>kFALSE</code> if it wasn't
285 template< typename T >
286 StatusCode TEvent::recordMeta( T* obj, const std::string& key,
287 ::Int_t basketSize, ::Int_t splitLevel ) {
289 // Just call the non-templated implementation:
290 return record( obj, SG::normalizedTypeinfoName( typeid( T ) ), key,
291 basketSize, splitLevel, kFALSE, kTRUE );
294 /// This function can be used to add a metadata object to the output. As the
295 /// interface clearly states, the function takes posession of the object
296 /// given to it. So it's not even worth mentioning that the user must not
297 /// delete the object after giving it to this function.
299 /// @param obj Smart pointer to the object to be added to the output metadata
300 /// @param key The key (branch name) to give the object
301 /// @param basketSize Basket size for the branch created from the object
302 /// @param splitLevel The split level of the branch to create
303 /// @returns <code>kTRUE</code> if the operation was successful,
304 /// <code>kFALSE</code> if it wasn't
306 template< typename T >
307 StatusCode TEvent::recordMeta( std::unique_ptr< T > obj,
308 const std::string& key,
309 ::Int_t basketSize, ::Int_t splitLevel ) {
311 // Just call the non-templated implementation:
312 const StatusCode rc =
313 record( obj.get(), SG::normalizedTypeinfoName( typeid( T ) ), key,
314 basketSize, splitLevel, kFALSE, kTRUE );
315 if( ! rc.isSuccess() ) {
319 // If the record was successful, let's release the object from the unique
322 return StatusCode::SUCCESS;
327 #endif // XAODROOTACCESS_TEVENT_ICC