1 // Dear emacs, this is -*- c++ -*-
3 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5 #ifndef XAODROOTACCESS_REVENT_ICC
6 #define XAODROOTACCESS_REVENT_ICC
12 #include "AthContainers/normalizedTypeinfoName.h"
16 namespace Experimental {
18 /// This function works pretty much like StoreGateSvc::contains. It can be
19 /// used to check if an object with a given type having a given key can be
20 /// retrieved from the event.
22 /// @param key The key (branch name) of the object
23 /// @returns <code>kTRUE</code> if the object is available,
24 /// <code>kFALSE</code> otherwise
26 template< typename T >
27 ::Bool_t REvent::contains( const std::string& key ) {
29 return contains( key, typeid( T ), kFALSE );
32 /// This function works pretty much like StoreGateSvc::transientContains.
33 /// It doesn't try to do any I/O operations, it just checks if an object
34 /// of a given type, with a given key, is already in memory.
36 /// @param key The key (branch name) of the object
37 /// @returns <code>kTRUE</code> if the object is already in memory,
38 /// <code>kFALSE</code> otherwise
40 template< typename T >
41 ::Bool_t REvent::transientContains( const std::string& key ) const {
43 // Simply forward the call:
44 return transientContains( key, typeid( T ), kFALSE );
47 /// This function needs to be used when retrieving an object either from
48 /// the input or the output object list. The returned object can not be
51 /// @param obj The pointer that will be set to the object requested
52 /// @param key The key (branch name) of the object
53 /// @returns <code>kTRUE</code> if the operation was successful,
54 /// <code>kFALSE</code> if it wasn't
56 template< typename T >
57 StatusCode REvent::retrieve( const T*& obj, const std::string& key ) {
59 // Look among the output objects first:
60 const void* result = getOutputObject( key, typeid( T ) );
61 // Check if it succeeded:
63 // Try the input then:
64 result = getInputObject( key, typeid( T ) );
66 ::Warning( "xAOD::REvent::retrieve",
67 "Couldn't (const) retrieve \"%s/%s\"",
68 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
70 return StatusCode::RECOVERABLE;
73 // Even if there is an output object with this key, it may
74 // be an input object that was copied to the output. So let's
75 // try to silently retrieve an input object as well. This makes
76 // sure that the input/output object is updated for the current
78 getInputObject( key, typeid( T ), kTRUE );
81 // If we were successful:
82 obj = reinterpret_cast< const T* >( result );
83 return StatusCode::SUCCESS;
86 /// This function can be used to retrieve an object from the output list.
87 /// Since only output objects are considered, the function returns a
88 /// non-const object, allowing downstream code to modify an object that
89 /// was put into the event somewhere upstream.
91 /// @param obj The pointer that will be set to the object requested
92 /// @param key The key (branch name) of the object
93 /// @returns <code>kTRUE</code> if the operation was successful,
94 /// <code>kFALSE</code> if it wasn't
96 template< typename T >
97 StatusCode REvent::retrieve( T*& obj, const std::string& key ) {
99 // Only look among the output objects in this case:
100 void* result = getOutputObject( key, typeid( T ) );
101 // Check if we found the object:
103 ::Warning( "xAOD::REvent::retrieve",
104 "Couldn't (non-const) retrieve \"%s/%s\"",
105 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
107 return StatusCode::RECOVERABLE;
110 // If we were successful:
111 obj = reinterpret_cast< T* >( result );
112 return StatusCode::SUCCESS;
115 // /// This function can be used to add an object to the output. The function
116 // /// takes posession of the object, so the user code must not delete an
117 // /// object that was added to an event.
119 // /// @param obj Pointer to the object to be added to the event
120 // /// @param key The key (branch name) to give the object
121 // /// @param basketSize Basket size for the branch created from the object
122 // /// @param splitLevel The split level of the branch to create
123 // /// @returns <code>kTRUE</code> if the operation was successful,
124 // /// <code>kFALSE</code> if it wasn't
126 // template< typename T >
127 // StatusCode REvent::record( T* obj, const std::string& key,
128 // ::Int_t basketSize, ::Int_t splitLevel ) {
130 // // Just call the non-templated implementation:
131 // return record( obj, SG::normalizedTypeinfoName( typeid( T ) ), key,
132 // basketSize, splitLevel );
135 // /// This function is used to add an object to the output. As the interface
136 // /// clearly states, the function takes posession of the object given to it.
137 // /// Since the user must give up ownership of the object in order to call this
138 // /// function, it doesn't even need to be said that the user must not delete
139 // /// the object by hand after calling this function.
141 // /// @param obj Smart pointer to the object to tbe added to the event
142 // /// @param key The key (branch name) to give the object
143 // /// @param basketSize Basket size for the branch created from the object
144 // /// @param splitLevel The split level of the branch to create
145 // /// @returns <code>kTRUE</code> if the operation was successful,
146 // /// <code>kFALSE</code> if it wasn't
148 // template< typename T >
149 // StatusCode REvent::record( std::unique_ptr< T > obj, const std::string& key,
150 // ::Int_t basketSize, ::Int_t splitLevel ) {
152 // // Just call the non-templated implementation:
153 // const StatusCode rc =
154 // record( obj.get(), SG::normalizedTypeinfoName( typeid( T ) ), key,
155 // basketSize, splitLevel );
156 // if( ! rc.isSuccess() ) {
160 // // If the record was successful, let's release the object from the unique
162 // (void)obj.release();
163 // return StatusCode::SUCCESS;
166 /// This function works pretty much like StoreGateSvc::contains for metadata
167 /// objects. It can be used to check containsMetaif a metadata object with a given type
168 /// having a given key can be (const) retrieved.
170 /// @param key The key (branch name) of the metadata object
171 /// @returns <code>kTRUE</code> if the object is available,
172 /// <code>kFALSE</code> otherwise
174 template< typename T >
175 ::Bool_t REvent::containsMeta( const std::string& key ) {
177 return contains( key, typeid( T ), kTRUE );
180 /// This function works pretty much like StoreGateSvc::transientContains for
181 /// metadata objects. It doesn't try to do any I/O operations, it just checks
182 /// if an object of a given type, with a given key, can be retrieved in
185 /// @param key The key (branch name) of the metadata object
186 /// @returns <code>kTRUE</code> if the object is available for modifications,
187 /// <code>kFALSE</code> otherwise
189 template< typename T >
190 ::Bool_t REvent::transientContainsMeta( const std::string& key ) const {
192 // Simply forward the call:
193 return transientContains( key, typeid( T ), kTRUE );
196 /// This function can be used to retrieve an object from the input metadata
199 /// @param obj The pointer that will be set to the object requested
200 /// @param key The key (branch name) of the object
201 /// @returns The usual StatusCode values
203 template< typename T >
204 StatusCode REvent::retrieveMetaInput( const T*& obj,
205 const std::string& key ) {
207 // Only look among the output objects in this case:
208 const void* result = getInputObject( key, typeid( T ), kFALSE, kTRUE );
209 // Check if we found the object:
211 ::Warning( "xAOD::REvent::retrieveMetaInput",
212 "Couldn't (const) retrieve \"%s/%s\"",
213 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
215 return StatusCode::RECOVERABLE;
218 // If we were successful:
219 obj = reinterpret_cast< const T* >( result );
220 return StatusCode::SUCCESS;
223 /// This function can be used to retrieve an object from the output metadata
226 /// @param obj The pointer that will be set to the object requested
227 /// @param key The key (branch name) of the object
228 /// @returns The usual StatusCode values
230 template< typename T >
231 StatusCode REvent::retrieveMetaOutput( const T*& obj,
232 const std::string& key ) {
234 // Only look among the output objects in this case:
235 const void* result = getOutputObject( key, typeid( T ), kTRUE );
236 // Check if we found the object:
238 ::Warning( "xAOD::REvent::retrieveMetaOutput",
239 "Couldn't (const) retrieve \"%s/%s\"",
240 SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
242 return StatusCode::RECOVERABLE;
245 // If we were successful:
246 obj = reinterpret_cast< const T* >( result );
247 return StatusCode::SUCCESS;
250 // /// This function can be used to retrieve an object from the output metadata
253 // /// @param obj The pointer that will be set to the object requested
254 // /// @param key The key (branch name) of the object
255 // /// @returns The usual StatusCode values
257 // template< typename T >
258 // StatusCode REvent::retrieveMetaOutput( T*& obj, const std::string& key ) {
260 // // Only look among the output objects in this case:
261 // void* result = getOutputObject( key, typeid( T ), kTRUE );
262 // // Check if we found the object:
264 // ::Warning( "xAOD::REvent::retrieveMetaOutput",
265 // "Couldn't (non-const) retrieve \"%s/%s\"",
266 // SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
268 // return StatusCode::RECOVERABLE;
271 // // If we were successful:
272 // obj = reinterpret_cast< T* >( result );
273 // return StatusCode::SUCCESS;
276 /// This function can be used to add a metadata object to the output.
277 /// The function takes posession of the object, so the user code must not
278 /// delete an object that was added to the output.
280 /// @param obj Pointer to the object to be added to the output metadata
281 /// @param key The key (branch name) to give the object
282 /// @param basketSize Basket size for the branch created from the object
283 /// @param splitLevel The split level of the branch to create
284 /// @returns <code>kTRUE</code> if the operation was successful,
285 /// <code>kFALSE</code> if it wasn't
287 template< typename T >
288 StatusCode REvent::recordMeta( T* obj, const std::string& key,
289 ::Int_t basketSize, ::Int_t splitLevel ) {
291 // Just call the non-templated implementation:
292 return record( obj, SG::normalizedTypeinfoName( typeid( T ) ), key,
293 basketSize, splitLevel, kFALSE, kTRUE );
296 /// This function can be used to add a metadata object to the output. As the
297 /// interface clearly states, the function takes posession of the object
298 /// given to it. So it's not even worth mentioning that the user must not
299 /// delete the object after giving it to this function.
301 /// @param obj Smart pointer to the object to be added to the output metadata
302 /// @param key The key (branch name) to give the object
303 /// @param basketSize Basket size for the branch created from the object
304 /// @param splitLevel The split level of the branch to create
305 /// @returns <code>kTRUE</code> if the operation was successful,
306 /// <code>kFALSE</code> if it wasn't
308 template< typename T >
309 StatusCode REvent::recordMeta( std::unique_ptr< T > obj,
310 const std::string& key,
311 ::Int_t basketSize, ::Int_t splitLevel ) {
313 // Just call the non-templated implementation:
314 const StatusCode rc =
315 record( obj.get(), SG::normalizedTypeinfoName( typeid( T ) ), key,
316 basketSize, splitLevel, kFALSE, kTRUE );
317 if( ! rc.isSuccess() ) {
321 // If the record was successful, let's release the object from the unique
324 return StatusCode::SUCCESS;
327 } // namespace Experimental
331 #endif // XAODROOTACCESS_REVENT_ICC