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 std::ignore = obj.release();
171 return StatusCode::SUCCESS;
174 /// This function works pretty much like StoreGateSvc::contains for metadata
175 /// objects. It can be used to check if a metadata object with a given type
176 /// having a given key can be (const) retrieved.
178 /// @param key The key/name of the metadata object
179 /// @returns @c true if the object is available,
180 /// @c false otherwise
182 template <typename T>
183 bool Event::containsMeta(const std::string& key) {
185 static const bool METADATA = true;
186 static const bool SILENT = true;
187 const std::type_info& ti = typeid(T);
188 return ((getOutputObject(key, ti, METADATA) != nullptr) ||
189 (getInputObject(key, ti, SILENT, METADATA) != nullptr));
192 /// This function works pretty much like StoreGateSvc::transientContains for
193 /// metadata objects. It doesn't try to do any I/O operations, it just checks
194 /// if an object of a given type, with a given key, can be retrieved in
197 /// @param key The key/name of the metadata object
198 /// @returns @c true if the object is available,
199 /// @c false otherwise
201 template <typename T>
202 bool Event::transientContainsMeta(const std::string& key) const {
204 static const bool METADATA = true;
205 const std::type_info& ti = typeid(T);
206 return (getOutputObject(key, ti, METADATA) != nullptr);
209 /// This can be useful in generic client code to process all metadata objects of
212 /// @param vkeys will be filled with the list of keys (may be empty)
213 /// @returns The usual @c StatusCode types
215 template <typename T>
216 StatusCode Event::metaKeys(std::vector<std::string>& vkeys) const {
218 static const bool METADATA = true;
219 ATH_CHECK(getNames(SG::normalizedTypeinfoName(typeid(T)), vkeys, METADATA));
220 return StatusCode::SUCCESS;
223 /// This function can be used to retrieve an object from the input metadata
226 /// @param obj The pointer that will be set to the object requested
227 /// @param key The key/name of the object
228 /// @returns The usual @c StatusCode values
230 template <typename T>
231 StatusCode Event::retrieveMetaInput(const T*& obj, const std::string& key) {
233 // Only look among the output objects in this case.
234 static const bool SILENT = false;
235 static const bool METADATA = true;
236 const std::type_info& ti = typeid(T);
237 const void* result = getInputObject(key, ti, SILENT, METADATA);
238 // Check if we found the object.
239 if (result == nullptr) {
240 ATH_MSG_WARNING("Couldn't (const) retrieve \""
241 << SG::normalizedTypeinfoName(ti) << "/" << key << "\"");
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/name of the object
255 /// @returns The usual @c StatusCode values
257 template <typename T>
258 StatusCode Event::retrieveMetaOutput(const T*& obj, const std::string& key) {
260 // Only look among the output objects in this case:
261 static const bool METADATA = true;
262 const std::type_info& ti = typeid(T);
263 const void* result = getOutputObject(key, ti, METADATA);
264 // Check if we found the object.
265 if (result == nullptr) {
266 ATH_MSG_WARNING("Couldn't (const) retrieve \""
267 << SG::normalizedTypeinfoName(ti) << "/" << key << "\"");
268 return StatusCode::RECOVERABLE;
271 // If we were successful.
272 obj = reinterpret_cast<const T*>(result);
273 return StatusCode::SUCCESS;
276 /// This function can be used to retrieve an object from the output metadata
279 /// @param obj The pointer that will be set to the object requested
280 /// @param key The key/name of the object
281 /// @returns The usual @c StatusCode values
283 template <typename T>
284 StatusCode Event::retrieveMetaOutput(T*& obj, const std::string& key) {
286 // Only look among the output objects in this case.
287 static const bool METADATA = true;
288 const std::type_info& ti = typeid(T);
289 void* result = getOutputObject(key, ti, METADATA);
290 // Check if we found the object.
291 if (result == nullptr) {
292 ATH_MSG_WARNING("Couldn't (non-const) retrieve \""
293 << SG::normalizedTypeinfoName(ti) << "/" << key << "\"");
294 return StatusCode::RECOVERABLE;
297 // If we were successful.
298 obj = reinterpret_cast<T*>(result);
299 return StatusCode::SUCCESS;
302 /// This function can be used to add a metadata object to the output.
303 /// The function takes posession of the object, so the user code must not
304 /// delete an object that was added to the output.
306 /// @param obj Pointer to the object to be added to the output metadata
307 /// @param key The key/name to give the object
308 /// @returns The usual @c StatusCode values
310 template <typename T>
311 StatusCode Event::recordMeta(T* obj, const std::string& key) {
313 // Just call the non-templated implementation.
314 static const bool OVERWRITE = false;
315 static const bool METADATA = true;
316 static const bool ISOWNER = true;
317 ATH_CHECK(record(obj, SG::normalizedTypeinfoName(typeid(T)), key, OVERWRITE,
319 return StatusCode::SUCCESS;
322 /// This function can be used to add a metadata object to the output. As the
323 /// interface clearly states, the function takes posession of the object
324 /// given to it. So it's not even worth mentioning that the user must not
325 /// delete the object after giving it to this function.
327 /// @param obj Smart pointer to the object to be added to the output metadata
328 /// @param key The key/name to give the object
329 /// @returns The usual @c StatusCode values
331 template <typename T>
332 StatusCode Event::recordMeta(std::unique_ptr<T> obj, const std::string& key) {
334 // Just call the non-templated implementation.
335 static const bool OVERWRITE = false;
336 static const bool METADATA = true;
337 static const bool ISOWNER = true;
338 ATH_CHECK(record(obj.get(), SG::normalizedTypeinfoName(typeid(T)), key,
339 OVERWRITE, METADATA, ISOWNER));
341 // If the record was successful, let's release the object from the unique
343 std::ignore = obj.release();
344 return StatusCode::SUCCESS;
349 #endif // XAODROOTACCESS_EVENT_ICC