1 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 #ifndef XAODROOTACCESS_EVENT_ICC
3 #define XAODROOTACCESS_EVENT_ICC
6 #include "AthContainers/normalizedTypeinfoName.h"
13 /// This function works pretty much like StoreGateSvc::contains. It can be
14 /// used to check if an object with a given type having a given key can be
15 /// retrieved from the event.
17 /// @param key The key/name of the object
18 /// @returns @c true if the object is available,
19 /// @c false otherwise
22 bool Event::contains(const std::string& key) {
24 static const bool METADATA = false;
25 const std::type_info& ti = typeid(T);
26 return contains(key, ti, METADATA);
29 /// This function works pretty much like StoreGateSvc::transientContains.
30 /// It doesn't try to do any I/O operations, it just checks if an object
31 /// of a given type, with a given key, is already in memory.
33 /// @param key The key/name of the object
34 /// @returns The usual @c StatusCode types
37 bool Event::transientContains(const std::string& key) const {
39 static const bool METADATA = false;
40 const std::type_info& ti = typeid(T);
41 return transientContains(key, ti, METADATA);
44 /// This can be useful in generic client code to process all objects of a given
47 /// @param vkeys will be filled with the list of keys (may be empty)
48 /// @param metadata Whether to look for metadata or data objects
49 /// @returns The usual @c StatusCode types
52 StatusCode Event::keys(std::vector<std::string>& vkeys, bool metadata) const {
54 ATH_CHECK(getNames(SG::normalizedTypeinfoName(typeid(T)), vkeys, metadata));
55 return StatusCode::SUCCESS;
58 /// This function needs to be used when retrieving an object either from
59 /// the input or the output object list. The returned object can not be
62 /// @param obj The pointer that will be set to the object requested
63 /// @param key The key/name of the object
64 /// @returns The usual @c StatusCode types
67 StatusCode Event::retrieve(const T*& obj, const std::string& key) {
69 // The type in question.
70 const std::type_info& ti = typeid(T);
71 // Look among the output objects first.
72 static const bool METADATA = false;
73 const void* result = getOutputObject(key, ti, METADATA);
74 // Check if it succeeded.
75 if (result == nullptr) {
76 // Try the input then.
77 static const bool SILENT = false;
78 result = getInputObject(key, ti, SILENT, METADATA);
79 if (result == nullptr) {
80 ATH_MSG_WARNING("Couldn't (const) retrieve \""
81 << SG::normalizedTypeinfoName(ti) << "/" << key << "\"");
82 return StatusCode::RECOVERABLE;
85 // Even if there is an output object with this key, it may
86 // be an input object that was copied to the output. So let's
87 // try to silently retrieve an input object as well. This makes
88 // sure that the input/output object is updated for the current
90 static const bool SILENT = true;
91 getInputObject(key, ti, SILENT, METADATA);
94 // If we were successful.
95 obj = reinterpret_cast<const T*>(result);
96 return StatusCode::SUCCESS;
99 /// This function can be used to retrieve an object from the output list.
100 /// Since only output objects are considered, the function returns a
101 /// non-const object, allowing downstream code to modify an object that
102 /// was put into the event somewhere upstream.
104 /// @param obj The pointer that will be set to the object requested
105 /// @param key The key/name of the object
106 /// @returns The usual @c StatusCode types
108 template <typename T>
109 StatusCode Event::retrieve(T*& obj, const std::string& key) {
111 // The type in question.
112 const std::type_info& ti = typeid(T);
113 // Only look among the output objects in this case:
114 static const bool METADATA = false;
115 void* result = getOutputObject(key, ti, METADATA);
116 // Check if we found the object:
117 if (result == nullptr) {
118 ATH_MSG_WARNING("Couldn't (non-const) retrieve \""
119 << SG::normalizedTypeinfoName(ti) << "/" << key << "\"");
120 return StatusCode::RECOVERABLE;
123 // If we were successful.
124 obj = reinterpret_cast<T*>(result);
125 return StatusCode::SUCCESS;
128 /// This function can be used to add an object to the output. The function
129 /// takes posession of the object, so the user code must not delete an
130 /// object that was added to an event.
132 /// @param obj Pointer to the object to be added to the event
133 /// @param key The key/name to give the object
134 /// @returns The usual @c StatusCode types
136 template <typename T>
137 StatusCode Event::record(T* obj, const std::string& key) {
139 // Just call the non-templated implementation.
140 static const bool OVERWRITE = false;
141 static const bool METADATA = false;
142 static const bool ISOWNER = true;
143 ATH_CHECK(record(obj, SG::normalizedTypeinfoName(typeid(T)), key, OVERWRITE,
145 return StatusCode::SUCCESS;
148 /// This function is used to add an object to the output. As the interface
149 /// clearly states, the function takes posession of the object given to it.
150 /// Since the user must give up ownership of the object in order to call this
151 /// function, it doesn't even need to be said that the user must not delete
152 /// the object by hand after calling this function.
154 /// @param obj Smart pointer to the object to tbe added to the event
155 /// @param key The key/name to give the object
156 /// @returns The usual @c StatusCode types
158 template <typename T>
159 StatusCode Event::record(std::unique_ptr<T> obj, const std::string& key) {
161 // Just call the non-templated implementation.
162 static const bool OVERWRITE = false;
163 static const bool METADATA = false;
164 static const bool ISOWNER = true;
165 ATH_CHECK(record(obj.get(), SG::normalizedTypeinfoName(typeid(T)), key,
166 OVERWRITE, METADATA, ISOWNER));
168 // If the record was successful, let's release the object from the unique
170 //coverity[leaked_storage]
171 std::ignore = obj.release();
172 return StatusCode::SUCCESS;
175 /// This function works pretty much like StoreGateSvc::contains for metadata
176 /// objects. It can be used to check if a metadata object with a given type
177 /// having a given key can be (const) retrieved.
179 /// @param key The key/name of the metadata object
180 /// @returns @c true if the object is available,
181 /// @c false otherwise
183 template <typename T>
184 bool Event::containsMeta(const std::string& key) {
186 static const bool METADATA = true;
187 static const bool SILENT = true;
188 const std::type_info& ti = typeid(T);
189 return ((getOutputObject(key, ti, METADATA) != nullptr) ||
190 (getInputObject(key, ti, SILENT, METADATA) != nullptr));
193 /// This function works pretty much like StoreGateSvc::transientContains for
194 /// metadata objects. It doesn't try to do any I/O operations, it just checks
195 /// if an object of a given type, with a given key, can be retrieved in
198 /// @param key The key/name of the metadata object
199 /// @returns @c true if the object is available,
200 /// @c false otherwise
202 template <typename T>
203 bool Event::transientContainsMeta(const std::string& key) const {
205 static const bool METADATA = true;
206 const std::type_info& ti = typeid(T);
207 return (getOutputObject(key, ti, METADATA) != nullptr);
210 /// This can be useful in generic client code to process all metadata objects of
213 /// @param vkeys will be filled with the list of keys (may be empty)
214 /// @returns The usual @c StatusCode types
216 template <typename T>
217 StatusCode Event::metaKeys(std::vector<std::string>& vkeys) const {
219 static const bool METADATA = true;
220 ATH_CHECK(getNames(SG::normalizedTypeinfoName(typeid(T)), vkeys, METADATA));
221 return StatusCode::SUCCESS;
224 /// This function can be used to retrieve an object from the input metadata
227 /// @param obj The pointer that will be set to the object requested
228 /// @param key The key/name of the object
229 /// @returns The usual @c StatusCode values
231 template <typename T>
232 StatusCode Event::retrieveMetaInput(const T*& obj, const std::string& key) {
234 // Only look among the output objects in this case.
235 static const bool SILENT = false;
236 static const bool METADATA = true;
237 const std::type_info& ti = typeid(T);
238 const void* result = getInputObject(key, ti, SILENT, METADATA);
239 // Check if we found the object.
240 if (result == nullptr) {
241 ATH_MSG_WARNING("Couldn't (const) retrieve \""
242 << SG::normalizedTypeinfoName(ti) << "/" << key << "\"");
243 return StatusCode::RECOVERABLE;
246 // If we were successful.
247 obj = reinterpret_cast<const T*>(result);
248 return StatusCode::SUCCESS;
251 /// This function can be used to retrieve an object from the output metadata
254 /// @param obj The pointer that will be set to the object requested
255 /// @param key The key/name of the object
256 /// @returns The usual @c StatusCode values
258 template <typename T>
259 StatusCode Event::retrieveMetaOutput(const T*& obj, const std::string& key) {
261 // Only look among the output objects in this case:
262 static const bool METADATA = true;
263 const std::type_info& ti = typeid(T);
264 const void* result = getOutputObject(key, ti, METADATA);
265 // Check if we found the object.
266 if (result == nullptr) {
267 ATH_MSG_WARNING("Couldn't (const) retrieve \""
268 << SG::normalizedTypeinfoName(ti) << "/" << key << "\"");
269 return StatusCode::RECOVERABLE;
272 // If we were successful.
273 obj = reinterpret_cast<const T*>(result);
274 return StatusCode::SUCCESS;
277 /// This function can be used to retrieve an object from the output metadata
280 /// @param obj The pointer that will be set to the object requested
281 /// @param key The key/name of the object
282 /// @returns The usual @c StatusCode values
284 template <typename T>
285 StatusCode Event::retrieveMetaOutput(T*& obj, const std::string& key) {
287 // Only look among the output objects in this case.
288 static const bool METADATA = true;
289 const std::type_info& ti = typeid(T);
290 void* result = getOutputObject(key, ti, METADATA);
291 // Check if we found the object.
292 if (result == nullptr) {
293 ATH_MSG_WARNING("Couldn't (non-const) retrieve \""
294 << SG::normalizedTypeinfoName(ti) << "/" << key << "\"");
295 return StatusCode::RECOVERABLE;
298 // If we were successful.
299 obj = reinterpret_cast<T*>(result);
300 return StatusCode::SUCCESS;
303 /// This function can be used to add a metadata object to the output.
304 /// The function takes posession of the object, so the user code must not
305 /// delete an object that was added to the output.
307 /// @param obj Pointer to the object to be added to the output metadata
308 /// @param key The key/name to give the object
309 /// @returns The usual @c StatusCode values
311 template <typename T>
312 StatusCode Event::recordMeta(T* obj, const std::string& key) {
314 // Just call the non-templated implementation.
315 static const bool OVERWRITE = false;
316 static const bool METADATA = true;
317 static const bool ISOWNER = true;
318 ATH_CHECK(record(obj, SG::normalizedTypeinfoName(typeid(T)), key, OVERWRITE,
320 return StatusCode::SUCCESS;
323 /// This function can be used to add a metadata object to the output. As the
324 /// interface clearly states, the function takes posession of the object
325 /// given to it. So it's not even worth mentioning that the user must not
326 /// delete the object after giving it to this function.
328 /// @param obj Smart pointer to the object to be added to the output metadata
329 /// @param key The key/name to give the object
330 /// @returns The usual @c StatusCode values
332 template <typename T>
333 StatusCode Event::recordMeta(std::unique_ptr<T> obj, const std::string& key) {
335 // Just call the non-templated implementation.
336 static const bool OVERWRITE = false;
337 static const bool METADATA = true;
338 static const bool ISOWNER = true;
339 ATH_CHECK(record(obj.get(), SG::normalizedTypeinfoName(typeid(T)), key,
340 OVERWRITE, METADATA, ISOWNER));
342 // If the record was successful, let's release the object from the unique
344 //coverity[leaked_storage]
345 std::ignore = obj.release();
346 return StatusCode::SUCCESS;
351 #endif // XAODROOTACCESS_EVENT_ICC