ATLAS Offline Software
Loading...
Searching...
No Matches
StoreGate/StoreGate/ReadDecorHandle.icc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
3 */
4/**
5 * @file StoreGate/ReadDecorHandle.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Apr, 2017
8 * @brief Handle class for reading a decoration on an object.
9 */
10
11
12namespace SG {
13
14
15/**
16 * @brief Constructor from a ReadDecorHandleKey.
17 * @param key The key object holding the clid/key/store/attr.
18 *
19 * This will raise an exception if the StoreGate key is blank,
20 * or if the event store cannot be found.
21 */
22template <class T, class D>
23ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key)
24 : Base (key.contHandleKey()),
25 m_decorKey (key.key()),
26 m_acc (SG::decorKeyFromKey (key.key()))
27{
28}
29
30
31/**
32 * @brief Constructor from a ReadDecorHandleKey and an explicit event context.
33 * @param key The key object holding the clid/key.
34 * @param ctx The event context.
35 *
36 * This will raise an exception if the StoreGate key is blank,
37 * or if the event store cannot be found.
38 *
39 * If the default event store has been requested, then the thread-specific
40 * store from the event context will be used.
41 */
42template <class T, class D>
43ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key,
44 const EventContext& ctx)
45 : Base (key.contHandleKey(), ctx),
46 m_decorKey (key.key()),
47 m_acc (SG::decorKeyFromKey (key.key()))
48{
49}
50
51
52/**
53 * @brief Copy constructor.
54 */
55template <class T, class D>
56ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandle& rhs)
57 : Base (rhs),
58 m_decorKey (rhs.m_decorKey),
59 m_acc (rhs.m_acc)
60{
61}
62
63
64/**
65 * @brief Move constructor.
66 */
67template <class T, class D>
68ReadDecorHandle<T, D>::ReadDecorHandle (ReadDecorHandle&& rhs)
69 : Base (std::move (rhs)),
70 m_decorKey (std::move (rhs.m_decorKey)),
71 m_acc (std::move (rhs.m_acc))
72{
73}
74
75
76/**
77 * @brief Assignment operator.
78 */
79template <class T, class D>
80ReadDecorHandle<T, D>& ReadDecorHandle<T, D>::operator= (const ReadDecorHandle& rhs)
81{
82 if (this != &rhs) {
83 *static_cast<Base*>(this) = rhs;
84 m_decorKey = rhs.m_decorKey;
85 m_acc = rhs.m_acc;
86 }
87 return *this;
88}
89
90
91/**
92 * @brief Move operator.
93 */
94template <class T, class D>
95ReadDecorHandle<T, D>& ReadDecorHandle<T, D>::operator= (ReadDecorHandle&& rhs)
96{
97 if (this != &rhs) {
98 *static_cast<Base*>(this) = std::move (rhs);
99 m_decorKey = std::move (rhs.m_decorKey);
100 m_acc = std::move (rhs.m_acc);
101 }
102 return *this;
103}
104
105
106/**
107 * @brief Is the referenced container present in SG?
108 *
109 * Note that this tests for the presence of the _container_,
110 * not for the decoration.
111 *
112 * Const method; the handle does not change as a result of this.
113 */
114template <class T, class D>
115inline
116bool ReadDecorHandle<T, D>::isPresent() const
117{
118 return Base::isPresent();
119}
120
121
122/**
123 * @brief Fetch the variable for one element, as a const reference.
124 * @param e The element for which to fetch the variable.
125 */
126template <class T, class D>
127inline
128typename ReadDecorHandle<T, D>::const_reference_type
129ReadDecorHandle<T, D>::operator() (const AuxElement& e) const
130{
131 // FIXME? In principle, should check here that E is actually an element
132 // of our declared container. But that would force a SG lookup here
133 // which we otherwise wouldn't need to do.
134 return m_acc (e);
135}
136
137
138/**
139 * @brief Fetch the variable for one element, as a const reference.
140 * @param index The index of the desired element.
141 *
142 * This looks up the variable in the object referenced by this handle.
143 * For a standalone object, pass an index of 0.
144 */
145template <class T, class D>
146inline
147typename ReadDecorHandle<T, D>::const_reference_type
148ReadDecorHandle<T, D>::operator() (size_t i)
149{
150 return m_acc (*this->vectorData(), i);
151}
152
153
154/**
155 * @brief Fetch the variable for one element, as a const reference.
156 * @param e The element for which to fetch the variable.
157 * @param deflt Default value.
158 *
159 * If this variable is not available, then return @c deflt instead.
160 */
161template <class T, class D>
162inline
163typename ReadDecorHandle<T, D>::const_reference_type
164ReadDecorHandle<T, D>::withDefault (const AuxElement& e, const D& deflt) const
165{
166 // FIXME? In principle, should check here that E is actually an element
167 // of our declared container. But that would force a SG lookup here
168 // which we otherwise wouldn't need to do.
169 return m_acc.withDefault (e, deflt);
170}
171
172
173/**
174 * @brief Fetch the variable for one element, as a const reference.
175 * @param index The index of the desired element.
176 * @param deflt Default value.
177 *
178 * This looks up the variable in the object referenced by this handle.
179 * For a standalone object, pass an index of 0.
180 * If this variable is not available, then return @c deflt instead.
181 */
182template <class T, class D>
183inline
184typename ReadDecorHandle<T, D>::const_reference_type
185ReadDecorHandle<T, D>::withDefault (size_t i, const D& deflt)
186{
187 return m_acc.withDefault (*this->vectorData(), i, deflt);
188}
189
190
191/**
192 * @brief Get a pointer to the start of the auxiliary data array.
193 * for the referenced object.
194 */
195template <class T, class D>
196template <class POINTER_TYPE /*= const_container_pointer_type*/>
197requires (!std::is_void_v<POINTER_TYPE>)
198POINTER_TYPE
199ReadDecorHandle<T, D>::getDataArray()
200{
201 return m_acc.getDataArray (*this->vectorData());
202}
203
204
205/**
206 * @brief Get a span over the auxilary data array,
207 * for the referenced object.
208 */
209template <class T, class D>
210auto
211ReadDecorHandle<T, D>::getDataSpan() -> const_span
212{
213 return m_acc.getDataSpan (*this->vectorData());
214}
215
216
217/**
218 * @brief Test to see if this variable exists in the store,
219 * for the referenced object.
220 */
221template <class T, class D>
222inline
223bool ReadDecorHandle<T, D>::isAvailable()
224{
225 const SG::AuxVectorData* vec = this->vectorData();
226 return vec && vec->isAvailable (m_acc.auxid());
227}
228
229
230/**
231 * @brief Return the aux id for this variable.
232 */
233template <class T, class D>
234inline
235SG::auxid_t ReadDecorHandle<T, D>::auxid() const
236{
237 return m_acc.auxid();
238}
239
240
241/**
242 * @brief Return the name of the decoration alias (CONT.DECOR).
243 */
244template <class T, class D>
245inline
246const std::string& ReadDecorHandle<T, D>::decorKey() const
247{
248 return m_decorKey;
249}
250
251
252/**
253 * @brief Return the referenced object as a @c SG::AuxVectorData.
254 * Specialization for the case of a standalone object
255 * (@c T derives from @c SG::AuxElement).
256 */
257template <class T, class D>
258inline
259const SG::AuxVectorData* ReadDecorHandle<T, D>::vectorData (std::true_type)
260{
261 return (*this)->container();
262}
263
264
265/**
266 * @brief Return the referenced object as a @c SG::AuxVectorData.
267 * Specialization for the case of a container
268 * (@c T does not derive from @c SG::AuxElement).
269 */
270template <class T, class D>
271inline
272const SG::AuxVectorData* ReadDecorHandle<T, D>::vectorData (std::false_type)
273{
274 return this->cptr();
275}
276
277
278/**
279 * @brief Return the referenced object as a @c SG::AuxVectorData.
280 *
281 * If @c T is a container object, then this should be the object itself.
282 * But if it is a standalone object, deriving from @c SG::AuxElement,
283 * then we need to call container() on the object.
284 */
285template <class T, class D>
286inline
287const SG::AuxVectorData* ReadDecorHandle<T, D>::vectorData()
288{
289 // Dispatch to the appropriate specialization, depending on whether or not
290 // @c T derives from @c SG::AuxElement.
291 return vectorData (typename std::is_base_of<SG::AuxElement, T>::type());
292}
293
294
295/**
296 * @brief Return a @c ReadDecorHandle referencing @c key.
297 * @param key The key object holding the clid/key/store.
298 *
299 * This will raise an exception if the StoreGate key is blank,
300 * or if the event store cannot be found.
301 *
302 * The type of the decoration must be included as an explicit template parameter:
303 *
304 *@code
305 * auto handle = SG::makeHandle<float> (key);
306 @endcode
307 *
308 * Note that @c D comes first in the argument list. It's given explicitly,
309 * while @c T is inferred from @c key.
310 */
311template <class D, class T>
312ReadDecorHandle<T, D> makeHandle (const ReadDecorHandleKey<T>& key)
313{
314 return ReadDecorHandle<T, D> (key);
315}
316
317
318/**
319 * @brief Return a @c ReadDecorHandle referencing @c key for an explicit context.
320 * @param key The key object holding the clid/key/store.
321 * @param ctx The event context.
322 *
323 * This will raise an exception if the StoreGate key is blank,
324 * or if the event store cannot be found.
325 *
326 * If the default event store has been requested, then the thread-specific
327 * store from the event context will be used.
328 *
329 * The type of the decoration must be included as an explicit template parameter:
330 *
331 *@code
332 * auto handle = SG::makeHandle<float> (key, ctx);
333 @endcode
334 *
335 * Note that @c D comes first in the argument list. It's given explicitly,
336 * while @c T is inferred from @c key.
337 */
338template <class D, class T>
339ReadDecorHandle<T, D> makeHandle (const ReadDecorHandleKey<T>& key,
340 const EventContext& ctx)
341{
342 return ReadDecorHandle<T, D> (key, ctx);
343}
344
345
346/**
347 * @brief These two signatures are to catch cases where the explicit
348 * template argument is omitted from the @c makeHandle call
349 * and give an error tailored to that. Otherwise, the @c makeHandle
350 * call for @c ReadHandle would match, potentially giving a much
351 * more confusing error.
352 */
353template <class T>
354void makeHandle (const ReadDecorHandleKey<T>& /*key*/)
355{
356 // If you see an error from here, you've forgotten the explicit template
357 // argument to @c makeHandle giving the decoration type.
358 // See the examples of @c makeHandle above.
359 return T::makeHandleForDecorationsRequiresExplicitTemplateArgument();
360}
361template <class T>
362void makeHandle (const ReadDecorHandleKey<T>& /*key*/,
363 const EventContext& /*ctx*/)
364{
365 // If you see an error from here, you've forgotten the explicit template
366 // argument to @c makeHandle giving the decoration type.
367 // See the examples of @c makeHandle above.
368 return T::makeHandleForDecorationsRequiresExplicitTemplateArgument();
369}
370
371
372} // namespace SG