ATLAS Offline Software
StoreGate/StoreGate/ReadDecorHandle.icc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2024 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 
12 namespace 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  */
22 template <class T, class D>
23 ReadDecorHandle<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  */
42 template <class T, class D>
43 ReadDecorHandle<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  */
55 template <class T, class D>
56 ReadDecorHandle<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  */
67 template <class T, class D>
68 ReadDecorHandle<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  */
79 template <class T, class D>
80 ReadDecorHandle<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  */
94 template <class T, class D>
95 ReadDecorHandle<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  */
114 template <class T, class D>
115 inline
116 bool 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  */
126 template <class T, class D>
127 inline
128 typename ReadDecorHandle<T, D>::const_reference_type
129 ReadDecorHandle<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  */
145 template <class T, class D>
146 inline
147 typename ReadDecorHandle<T, D>::const_reference_type
148 ReadDecorHandle<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  */
161 template <class T, class D>
162 inline
163 typename ReadDecorHandle<T, D>::const_reference_type
164 ReadDecorHandle<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  */
182 template <class T, class D>
183 inline
184 typename ReadDecorHandle<T, D>::const_reference_type
185 ReadDecorHandle<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  */
195 template <class T, class D>
196 template <class POINTER_TYPE /*= const_container_pointer_type*/,
197  typename /*= std::enable_if_t<!std::is_void_v<POINTER_TYPE> >*/ >
198 POINTER_TYPE
199 ReadDecorHandle<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  */
209 template <class T, class D>
210 auto
211 ReadDecorHandle<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  */
221 template <class T, class D>
222 inline
223 bool 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  */
233 template <class T, class D>
234 inline
235 SG::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  */
244 template <class T, class D>
245 inline
246 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  */
257 template <class T, class D>
258 inline
259 const 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  */
270 template <class T, class D>
271 inline
272 const 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  */
285 template <class T, class D>
286 inline
287 const 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  */
311 template <class D, class T>
312 ReadDecorHandle<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  */
338 template <class D, class T>
339 ReadDecorHandle<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  */
353 template <class T>
354 void 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 }
361 template <class T>
362 void 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