ATLAS Offline Software
PackedLinkConstAccessor.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 AthContainers/PackedLinkConstAccessor.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Oct, 2023
8  * @brief Helper class to provide constant type-safe access to aux data,
9  * specialized for @c PackedLink.
10  */
11 
12 
13 #include "AthContainers/AuxElement.h"
14 #include "AthContainers/AuxTypeRegistry.h"
15 #include "AthContainers/exceptions.h"
16 
17 
18 namespace SG {
19 
20 
21 /**
22  * @brief Constructor.
23  * @param name Name of this aux variable.
24  *
25  * The name -> auxid lookup is done here.
26  */
27 template <class CONT, class ALLOC>
28 inline
29 ConstAccessor<PackedLink<CONT>, ALLOC>::ConstAccessor (const std::string& name)
30  : ConstAccessor (name, "", AuxVarFlags::None)
31 {
32 }
33 
34 
35 /**
36  * @brief Constructor.
37  * @param name Name of this aux variable.
38  * @param clsname The name of its associated class. May be blank.
39  *
40  * The name -> auxid lookup is done here.
41  */
42 template <class CONT, class ALLOC>
43 inline
44 ConstAccessor<PackedLink<CONT>, ALLOC>::ConstAccessor
45  (const std::string& name, const std::string& clsname)
46  : ConstAccessor (name, clsname, AuxVarFlags::None)
47 {
48  // cppcheck-suppress missingReturn; false positive
49 }
50 
51 
52 /**
53  * @brief Constructor taking an auxid directly.
54  * @param auxid ID for this auxiliary variable.
55  *
56  * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
57  */
58 template <class CONT, class ALLOC>
59 inline
60 ConstAccessor<PackedLink<CONT>, ALLOC>::ConstAccessor (const SG::auxid_t auxid)
61 {
62  AuxTypeRegistry& r = AuxTypeRegistry::instance();
63  m_auxid = auxid;
64  r.checkAuxID<PLink_t, ALLOC> (m_auxid);
65  m_linkedAuxid = r.linkedVariable (m_auxid);
66  if (m_linkedAuxid == static_cast<uint32_t>(null_auxid)) {
67  throw SG::ExcNoLinkedVar (auxid, typeid (CONT));
68  // cppcheck-suppress missingReturn; false positive
69  }
70 }
71 
72 
73 /**
74  * @brief Constructor.
75  * @param name Name of this aux variable.
76  * @param clsname The name of its associated class. May be blank.
77  * @param flags Optional flags qualifying the type. See AuxTypeRegsitry.
78  *
79  * The name -> auxid lookup is done here.
80  */
81 template <class CONT, class ALLOC>
82 inline
83 ConstAccessor<PackedLink<CONT>, ALLOC>::ConstAccessor
84  (const std::string& name,
85  const std::string& clsname,
86  const AuxVarFlags flags)
87 {
88  AuxTypeRegistry& r = AuxTypeRegistry::instance();
89  m_linkedAuxid = r.getAuxID<DLink_t, DLinkAlloc_t> (AuxTypeRegistry::linkedName (name),
90  clsname,
91  flags | AuxVarFlags::Linked);
92  m_auxid = r.getAuxID<PLink_t, ALLOC> (name, clsname, flags, m_linkedAuxid);
93 }
94 
95 
96 /**
97  * @brief Fetch the variable for one element.
98  * @param e The element for which to fetch the variable.
99  */
100 template <class CONT, class ALLOC>
101 template <IsConstAuxElement ELT>
102 inline
103 auto
104 ConstAccessor<PackedLink<CONT>, ALLOC>::operator()
105  (const ELT& e) const -> const Link_t
106 {
107  assert (e.container() != nullptr);
108  return resolveLink (*e.container(), e.index());
109 
110 }
111 
112 
113 /**
114  * @brief Fetch the variable for one element.
115  * @param container The container from which to fetch the variable.
116  * @param index The index of the desired element.
117  *
118  * This allows retrieving aux data by container / index.
119  */
120 template <class CONT, class ALLOC>
121 inline
122 auto
123 ConstAccessor<PackedLink<CONT>, ALLOC>::operator()
124  (const AuxVectorData& container, size_t index) const -> const Link_t
125 {
126  return resolveLink (container, index);
127 }
128 
129 
130 /**
131  * @brief Get a pointer to the start of the array of @c PackedLinks
132  * @param container The container from which to fetch the variable.
133  */
134 template <class CONT, class ALLOC>
135 inline
136 auto
137 ConstAccessor<PackedLink<CONT>, ALLOC>::getPackedLinkArray (const AuxVectorData& container) const
138  -> const PLink_t*
139 {
140  return reinterpret_cast<const PLink_t*>
141  (container.getDataArray (m_auxid));
142 }
143 
144 
145 /**
146  * @brief Get a pointer to the start of the linked array of @c DataLinks.
147  * @param container The container from which to fetch the variable.
148  */
149 template <class CONT, class ALLOC>
150 inline
151 auto
152 ConstAccessor<PackedLink<CONT>, ALLOC>::getDataLinkArray (const AuxVectorData& container) const
153  -> const DLink_t*
154 {
155  return reinterpret_cast<const DLink_t*>
156  (container.getDataArray (m_linkedAuxid));
157 }
158 
159 
160 /**
161  * @brief Get a span over the array of @c PackedLinks.
162  * @param container The container from which to fetch the variable.
163  */
164 template <class CONT, class ALLOC>
165 inline
166 auto
167 ConstAccessor<PackedLink<CONT>, ALLOC>::getPackedLinkSpan (const AuxVectorData& container) const
168  -> const_PackedLink_span
169 {
170  auto beg = reinterpret_cast<const PLink_t*>(container.getDataArray (m_auxid));
171  return const_PackedLink_span (beg, container.size_v());
172 }
173 
174 
175 /**
176  * @brief Get a span over the array of @c DataLinks.
177  * @param container The container from which to fetch the variable.
178  */
179 template <class CONT, class ALLOC>
180 inline
181 auto
182 ConstAccessor<PackedLink<CONT>, ALLOC>::getDataLinkSpan (const AuxVectorData& container) const
183  -> const_DataLink_span
184 {
185  const SG::AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
186  return const_DataLink_span (reinterpret_cast<const DLink_t*>(sp->beg),
187  sp->size);
188 }
189 
190 
191 /**
192  * @brief Get a span of @c ElementLinks.
193  * @param container The container from which to fetch the variable.
194  */
195 template <class CONT, class ALLOC>
196 inline
197 auto
198 ConstAccessor<PackedLink<CONT>, ALLOC>::getDataSpan (const AuxVectorData& container) const
199  -> const_span
200 {
201  const_PackedLink_span pspan = getPackedLinkSpan(container);
202  typename ConstConverter_t::const_DataLink_span dlinks
203  (*container.getDataSpan (m_linkedAuxid));
204  return const_span (pspan, dlinks);
205 }
206 
207 
208 /**
209  * @brief Helper to resolve a @c PackedLink to an @c ElementLink.
210  * @param container The container from which to fetch the variable.
211  * @param index The index of the desired element.
212  */
213 template <class CONT, class ALLOC>
214 inline
215 auto
216 ConstAccessor<PackedLink<CONT>, ALLOC>::resolveLink (const AuxVectorData& container,
217  size_t index) const
218  -> Link_t
219 {
220  const auto& l = container.template getData<PLink_t> (m_auxid, index);
221  return ConstConverter_t (*container.getDataSpan (m_linkedAuxid)) (l);
222 }
223 
224 
225 //************************************************************************
226 
227 
228 // To make the declarations a bit more readable.
229 #define CONSTACCESSOR ConstAccessor<std::vector<PackedLink<CONT>, VALLOC>, ALLOC>
230 
231 
232 /**
233  * @brief Constructor.
234  * @param name Name of this aux variable.
235  *
236  * The name -> auxid lookup is done here.
237  */
238 template <class CONT, class ALLOC, class VALLOC>
239 inline
240 CONSTACCESSOR::ConstAccessor (const std::string& name)
241  : ConstAccessor (name, "", AuxVarFlags::None)
242 {
243 }
244 
245 
246 /**
247  * @brief Constructor.
248  * @param name Name of this aux variable.
249  * @param clsname The name of its associated class. May be blank.
250  *
251  * The name -> auxid lookup is done here.
252  */
253 template <class CONT, class ALLOC, class VALLOC>
254 inline
255 CONSTACCESSOR::ConstAccessor
256  (const std::string& name, const std::string& clsname)
257  : ConstAccessor (name, clsname, AuxVarFlags::None)
258 {
259 }
260 
261 
262 /**
263  * @brief Constructor taking an auxid directly.
264  * @param auxid ID for this auxiliary variable.
265  *
266  * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
267  */
268 template <class CONT, class ALLOC, class VALLOC>
269 inline
270 CONSTACCESSOR::ConstAccessor (const SG::auxid_t auxid)
271 {
272  AuxTypeRegistry& r = AuxTypeRegistry::instance();
273  m_auxid = auxid;
274  r.checkAuxID<VElt_t, ALLOC> (m_auxid);
275  m_linkedAuxid = r.linkedVariable (m_auxid);
276  if (m_linkedAuxid == static_cast<uint32_t>(null_auxid)) {
277  throw SG::ExcNoLinkedVar (auxid, typeid (CONT));
278  }
279 }
280 
281 
282 /**
283  * @brief Constructor.
284  * @param name Name of this aux variable.
285  * @param clsname The name of its associated class. May be blank.
286  * @param flags Optional flags qualifying the type. See AuxTypeRegsitry.
287  *
288  * The name -> auxid lookup is done here.
289  */
290 template <class CONT, class ALLOC, class VALLOC>
291 inline
292 CONSTACCESSOR::ConstAccessor
293  (const std::string& name,
294  const std::string& clsname,
295  const AuxVarFlags flags)
296 {
297  AuxTypeRegistry& r = AuxTypeRegistry::instance();
298  m_linkedAuxid = r.getAuxID<DLink_t, DLinkAlloc_t> (AuxTypeRegistry::linkedName (name),
299  clsname,
300  flags | AuxVarFlags::Linked);
301  m_auxid = r.getAuxID<VElt_t, ALLOC> (name, clsname, flags, m_linkedAuxid);
302 }
303 
304 
305 /**
306  * @brief Fetch the variable for one element.
307  * @param e The element for which to fetch the variable.
308  *
309  * This will return a range of @c ElementLinks.
310  */
311 template <class CONT, class ALLOC, class VALLOC>
312 template <IsConstAuxElement ELT>
313 inline
314 auto
315 CONSTACCESSOR::operator() (const ELT& e) const -> const_elt_span
316 {
317  const_PackedLink_span pspan = getPackedLinkSpan(e);
318  typename ConstVectorTransform_t::const_DataLink_span xform
319  (*e.container()->getDataSpan (m_linkedAuxid));
320  return const_elt_span (pspan, xform);
321 }
322 
323 /**
324  * @brief Fetch the variable for one element.
325  * @param container The container from which to fetch the variable.
326  * @param index The index of the desired element.
327  *
328  * This allows retrieving aux data by container / index.
329  *
330  * This will return a range of @c ElementLinks.
331  */
332 template <class CONT, class ALLOC, class VALLOC>
333 inline
334 auto
335 CONSTACCESSOR::operator()
336  (const AuxVectorData& container, size_t index) const -> const_elt_span
337 {
338  const_PackedLink_span pspan = getPackedLinkSpan(container, index);
339  typename ConstVectorTransform_t::const_DataLink_span xform
340  (*container.getDataSpan (m_linkedAuxid));
341  return const_elt_span (pspan, xform);
342 }
343 
344 
345 /**
346  * @brief Get a pointer to the start of the array of vectors of @c PackedLinks.
347  * @param container The container from which to fetch the variable.
348  */
349 template <class CONT, class ALLOC, class VALLOC>
350 inline
351 auto
352 CONSTACCESSOR::getPackedLinkVectorArray (const AuxVectorData& container) const
353  -> const VElt_t*
354 {
355  return reinterpret_cast<const VElt_t*>
356  (container.getDataArray (m_auxid));
357 }
358 
359 
360 /**
361  * @brief Get a pointer to the start of the linked array of @c DataLinks.
362  * @param container The container from which to fetch the variable.
363  */
364 template <class CONT, class ALLOC, class VALLOC>
365 inline
366 auto
367 CONSTACCESSOR::getDataLinkArray (const AuxVectorData& container) const
368  -> const DLink_t*
369 {
370  return reinterpret_cast<const DLink_t*>
371  (container.getDataArray (this->m_linkedAuxid));
372 }
373 
374 
375 /**
376  * @brief Get a span over the vector of @c PackedLinks for a given element.
377  * @param e The element for which to fetch the variable.
378  */
379 template <class CONT, class ALLOC, class VALLOC>
380 template <IsConstAuxElement ELT>
381 inline
382 auto CONSTACCESSOR::getPackedLinkSpan (const ELT& e) const
383  -> const_PackedLink_span
384 {
385  auto elt = reinterpret_cast<const VElt_t*>
386  (e.container()->getDataArray (m_auxid)) + e.index();
387  return const_PackedLink_span (elt->data(), elt->size());
388 }
389 
390 
391 /**
392  * @brief Get a span over the vector of @c PackedLinks for a given element.
393  * @param container The container from which to fetch the variable.
394  * @param index The index of the desired element.
395  */
396 template <class CONT, class ALLOC, class VALLOC>
397 inline
398 auto
399 CONSTACCESSOR::getPackedLinkSpan (const AuxVectorData& container,
400  size_t index) const
401  -> const_PackedLink_span
402 {
403  auto elt = reinterpret_cast<const VElt_t*>
404  (container.getDataArray (this->m_auxid)) + index;
405  return const_PackedLink_span (elt->data(), elt->size());
406 }
407 
408 
409 /**
410  * @brief Get a span over the vectors of @c PackedLinks.
411  * @param container The container from which to fetch the variable.
412  */
413 template <class CONT, class ALLOC, class VALLOC>
414 inline
415 auto
416 CONSTACCESSOR::getPackedLinkVectorSpan (const AuxVectorData& container) const
417  -> const_PackedLinkVector_span
418 {
419  auto beg = reinterpret_cast<const VElt_t*>
420  (container.getDataArray (m_auxid));
421  return const_PackedLinkVector_span (beg, container.size_v());
422 }
423 
424 
425 /**
426  * @brief Get a span over the array of @c DataLinks.
427  * @param container The container from which to fetch the variable.
428  */
429 template <class CONT, class ALLOC, class VALLOC>
430 auto
431 CONSTACCESSOR::getDataLinkSpan (const AuxVectorData& container) const
432  -> const_DataLink_span
433 {
434  const SG::AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
435  return const_DataLink_span (reinterpret_cast<const DLink_t*>(sp->beg),
436  sp->size);
437 }
438 
439 
440 /**
441  * @brief Get a span over spans of @c ElementLinks.
442  * @param container The container from which to fetch the variable.
443  */
444 template <class CONT, class ALLOC, class VALLOC>
445 inline
446 auto
447 CONSTACCESSOR::getDataSpan (const AuxVectorData& container) const
448  -> const_span
449 {
450  const_PackedLinkVector_span pspan = getPackedLinkVectorSpan(container);
451  typename ConstVectorTransform_t::const_DataLink_span xform
452  (*container.getDataSpan (m_linkedAuxid));
453  return const_span (pspan, xform);
454 }
455 
456 
457 #undef CONSTACCESSOR
458 
459 
460 } // namespace SG