ATLAS Offline Software
PackedLinkAccessor.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/PackedLinkAccessor.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Oct, 2023
8  * @brief Helper class to provide 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 #include "CxxUtils/checker_macros.h"
17 
18 
19 namespace SG {
20 
21 
22 /**
23  * @brief Constructor.
24  * @param name Name of this aux variable.
25  *
26  * The name -> auxid lookup is done here.
27  */
28 template <class CONT, class ALLOC>
29 inline
30 Accessor<PackedLink<CONT>, ALLOC>::Accessor (const std::string& name)
31  : Base (name)
32 {
33 }
34 
35 
36 /**
37  * @brief Constructor.
38  * @param name Name of this aux variable.
39  * @param clsname The name of its associated class. May be blank.
40  *
41  * The name -> auxid lookup is done here.
42  */
43 template <class CONT, class ALLOC>
44 inline
45 Accessor<PackedLink<CONT>, ALLOC>::Accessor (const std::string& name,
46  const std::string& clsname)
47  : Base (name, clsname)
48 {
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 Accessor<PackedLink<CONT>, ALLOC>::Accessor (const SG::auxid_t auxid)
61  : Base (auxid)
62 {
63  // cppcheck-suppress missingReturn; false positive
64 }
65 
66 
67 /**
68  * @brief Fetch the variable for one element.
69  * @param e The element for which to fetch the variable.
70  *
71  * Will return an @c ElementLink proxy, which may be converted to
72  * or assigned from an @c ElementLink.
73  */
74 template <class CONT, class ALLOC>
75 template <IsAuxElement ELT>
76 inline
77 auto
78 Accessor<PackedLink<CONT>, ALLOC>::operator() (ELT& e) const -> ELProxy
79 {
80  assert (e.container() != 0);
81  return ELProxy (e.container()->template getData<PLink_t> (this->m_auxid, e.index()),
82  *e.container(),
83  this->m_auxid,
84  this->m_linkedAuxid);
85 }
86 
87 
88 /**
89  * @brief Fetch the variable for one element.
90  * @param container The container from which to fetch the variable.
91  * @param index The index of the desired element.
92  *
93  * This allows retrieving aux data by container / index.
94  *
95  * Will return an @c ElementLink proxy, which may be converted to
96  * or assigned from an @c ElementLink.
97  */
98 template <class CONT, class ALLOC>
99 inline
100 auto
101 Accessor<PackedLink<CONT>, ALLOC>::operator() (AuxVectorData& container,
102  size_t index) const -> ELProxy
103 {
104  return ELProxy (container.template getData<PLink_t> (this->m_auxid, index),
105  container,
106  this->m_auxid,
107  this->m_linkedAuxid);
108 }
109 
110 
111 /**
112  * @brief Set the variable for one element.
113  * @param e The element for which to fetch the variable.
114  * @param l The @c ElementLink to set.
115  */
116 template <class CONT, class ALLOC>
117 inline
118 void Accessor<PackedLink<CONT>, ALLOC>::set (AuxElement& e, const Link_t& l) const
119 {
120  set (*e.container(), e.index(), l);
121 }
122 
123 
124 /**
125  * @brief Set the variable for one element.
126  * @param container The container from which to fetch the variable.
127  * @param index The index of the desired element.
128  * @param l The @c ElementLink to set.
129  */
130 template <class CONT, class ALLOC>
131 void Accessor<PackedLink<CONT>, ALLOC>::set (AuxVectorData& container,
132  size_t index,
133  const Link_t& x) const
134 {
135  // Have to do this before creating the converter.
136  PLink_t& ll = container.template getData<PLink_t> (this->m_auxid, index);
137  detail::PackedLinkConverter<CONT> cnv (container,
138  this->m_auxid,
139  this->m_linkedAuxid);
140  cnv.set (ll, x);
141 }
142 
143 
144 /**
145  * @brief Get a pointer to the start of the array of @c PackedLinks.
146  * @param container The container from which to fetch the variable.
147  */
148 template <class CONT, class ALLOC>
149 inline
150 auto
151 Accessor<PackedLink<CONT>, ALLOC>::getPackedLinkArray (AuxVectorData& container) const
152  -> PLink_t*
153 {
154  return reinterpret_cast<PLink_t*> (container.getDataArray (this->m_auxid));
155 }
156 
157 
158 /**
159  * @brief Get a pointer to the start of the linked array of @c DataLinks.
160  * @param container The container from which to fetch the variable.
161  */
162 template <class CONT, class ALLOC>
163 inline
164 auto
165 Accessor<PackedLink<CONT>, ALLOC>::getDataLinkArray (AuxVectorData& container) const
166  -> DLink_t*
167 {
168  return reinterpret_cast<DLink_t*>
169  (container.getDataArray (this->m_linkedAuxid));
170 }
171 
172 
173 /**
174  * @brief Get a span over the array of @c PackedLinks.
175  * @param container The container from which to fetch the variable.
176  */
177 template <class CONT, class ALLOC>
178 inline
179 auto
180 Accessor<PackedLink<CONT>, ALLOC>::getPackedLinkSpan (AuxVectorData& container) const
181  -> PackedLink_span
182 {
183  auto beg = reinterpret_cast<PLink_t*>(container.getDataArray (this->m_auxid));
184  return PackedLink_span (beg, container.size_v());
185 }
186 
187 
188 /**
189  * @brief Get a span over the array of @c DataLinks.
190  * @param container The container from which to fetch the variable.
191  */
192 template <class CONT, class ALLOC>
193 inline
194 auto
195 Accessor<PackedLink<CONT>, ALLOC>::getDataLinkSpan (AuxVectorData& container) const
196  -> DataLink_span
197 {
198  const AuxDataSpanBase* sp = container.getDataSpan (this->m_linkedAuxid);
199  return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
200 }
201 
202 
203 
204 /**
205  * @brief Get a span of @c ElementLink proxies.
206  * @param container The container from which to fetch the variable.
207  *
208  * The proxies may be converted to or assigned from @c ElementLink.
209  */
210 template <class CONT, class ALLOC>
211 inline
212 auto
213 Accessor<PackedLink<CONT>, ALLOC>::getDataSpan (AuxVectorData& container) const
214  -> span
215 {
216  return span (getPackedLinkSpan(container),
217  detail::PackedLinkConverter<CONT> (container,
218  this->m_auxid,
219  this->m_linkedAuxid));
220 }
221 
222 
223 /**
224  * @brief Test to see if this variable exists in the store and is writable.
225  * @param e An element of the container which to test the variable.
226  */
227 template <class CONT, class ALLOC>
228 inline
229 bool
230 Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxElement& e) const
231 {
232  return e.container() &&
233  e.container()->isAvailableWritable (this->m_auxid) &&
234  e.container()->isAvailableWritable (this->m_linkedAuxid);
235 }
236 
237 
238 /**
239  * @brief Test to see if this variable exists in the store and is writable.
240  * @param c The container which to test the variable.
241  */
242 template <class CONT, class ALLOC>
243 inline
244 bool
245 Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxVectorData& c) const
246 {
247  return c.isAvailableWritable (this->m_auxid) &&
248  c.isAvailableWritable (this->m_linkedAuxid);
249 }
250 
251 
252 //************************************************************************
253 
254 
255 // To make the declarations a bit more readable.
256 #define ACCESSOR Accessor<std::vector<PackedLink<CONT>, VALLOC>, ALLOC>
257 
258 
259 /**
260  * @brief Constructor.
261  * @param name Name of this aux variable.
262  *
263  * The name -> auxid lookup is done here.
264  */
265 template <class CONT, class ALLOC, class VALLOC>
266 inline
267 ACCESSOR::Accessor (const std::string& name)
268  : Base (name)
269 {
270 }
271 
272 
273 /**
274  * @brief Constructor.
275  * @param name Name of this aux variable.
276  * @param clsname The name of its associated class. May be blank.
277  *
278  * The name -> auxid lookup is done here.
279  */
280 template <class CONT, class ALLOC, class VALLOC>
281 inline
282 ACCESSOR::Accessor (const std::string& name,
283  const std::string& clsname)
284  : Base (name, clsname)
285 {
286 }
287 
288 
289 /**
290  * @brief Constructor taking an auxid directly.
291  * @param auxid ID for this auxiliary variable.
292  *
293  * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
294  */
295 template <class CONT, class ALLOC, class VALLOC>
296 inline
297 ACCESSOR::Accessor (const SG::auxid_t auxid)
298  : Base (auxid)
299 {
300 }
301 
302 
303 /**
304  * @brief Fetch the variable for one element.
305  * @param e The element for which to fetch the variable.
306  *
307  * This will return a range of @c ElementLink proxies.
308  * These proxies may be converted to or assigned from @c ElementLink.
309  */
310 template <class CONT, class ALLOC, class VALLOC>
311 template <IsAuxElement ELT>
312 auto
313 ACCESSOR::operator() (ELT& e) const -> elt_span
314 {
315  assert (e.container() != 0);
316  VElt_t* veltArr = getPackedLinkVectorArray(*e.container());
317  return elt_span (veltArr[e.index()], *e.container(),
318  this->m_auxid,
319  this->m_linkedAuxid);
320 }
321 
322 
323 /**
324  * @brief Fetch the variable for one element, as a non-const reference.
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 ElementLink proxies.
331  * These proxies may be converted to or assigned from @c ElementLink.
332  */
333 template <class CONT, class ALLOC, class VALLOC>
334 auto
335 ACCESSOR::operator() (AuxVectorData& container,
336  size_t index) const -> elt_span
337 {
338  VElt_t* veltArr = getPackedLinkVectorArray(container);
339  return elt_span (veltArr[index], container,
340  this->m_auxid,
341  this->m_linkedAuxid);
342 }
343 
344 
345 /**
346  * @brief Set the variable for one element.
347  * @param e The element for which to fetch the variable.
348  * @param r The variable value to set, as a range over @c ElementLink.
349  */
350 template <class CONT, class ALLOC, class VALLOC>
351 template <detail::ElementLinkRange<CONT> RANGE>
352 void ACCESSOR::set (AuxElement& e, const RANGE& r) const
353 {
354  set (*e.container(), e.index(), r);
355 }
356 
357 
358 /**
359  * @brief Set the variable for one element.
360  * @param container The container for which to set the variable.
361  * @param index The index of the desired element.
362  * @param r The variable value to set, as a range over @c ElementLink.
363  */
364 template <class CONT, class ALLOC, class VALLOC>
365 template <detail::ElementLinkRange<CONT> RANGE>
366 void ACCESSOR::set (AuxVectorData& container,
367  size_t index,
368  const RANGE& r) const
369 {
370  detail::PackedLinkConverter<CONT> cnv (container,
371  this->m_auxid,
372  this->m_linkedAuxid);
373  VElt_t& velt = container.template getData<VElt_t> (this->m_auxid, index);
374  cnv.set (velt, r);
375 }
376 
377 
378 /**
379  * @brief Get a pointer to the start of the array of vectors of @c PackedLinks.
380  * @param container The container from which to fetch the variable.
381  */
382 template <class CONT, class ALLOC, class VALLOC>
383 inline
384 auto
385 ACCESSOR::getPackedLinkVectorArray (AuxVectorData& container) const
386  -> VElt_t*
387 {
388  return reinterpret_cast<VElt_t*>
389  (container.getDataArray (this->m_auxid));
390 }
391 
392 
393 /**
394  * @brief Get a pointer to the start of the linked array of @c DataLinks.
395  * @param container The container from which to fetch the variable.
396  */
397 template <class CONT, class ALLOC, class VALLOC>
398 inline
399 auto
400 ACCESSOR::getDataLinkArray (AuxVectorData& container) const
401  -> DLink_t*
402 {
403  return reinterpret_cast<DLink_t*>
404  (container.getDataArray (this->m_linkedAuxid));
405 }
406 
407 
408 /**
409  * @brief Get a span over the vector of @c PackedLinks for a given element.
410  * @param e The element for which to fetch the variable.
411  */
412 template <class CONT, class ALLOC, class VALLOC>
413 inline
414 auto
415 ACCESSOR::getPackedLinkSpan (AuxElement& e) const
416  -> PackedLink_span
417 {
418  auto elt = reinterpret_cast<VElt_t*>
419  (e.container()->getDataArray (this->m_auxid)) + e.index();
420  return PackedLink_span (elt->data(), elt->size());
421 }
422 
423 
424 /**
425  * @brief Get a span over the vector of @c PackedLinks for a given element.
426  * @param container The container from which to fetch the variable.
427  * @param index The index of the desired element.
428  */
429 template <class CONT, class ALLOC, class VALLOC>
430 inline
431 auto
432 ACCESSOR::getPackedLinkSpan (AuxVectorData& container,
433  size_t index) const
434  -> PackedLink_span
435 {
436  auto elt = reinterpret_cast<VElt_t*>
437  (container.getDataArray (this->m_auxid)) + index;
438  return PackedLink_span (elt->data(), elt->size());
439 }
440 
441 
442 /**
443  * @brief Get a span over the vectors of @c PackedLinks.
444  * @param container The container from which to fetch the variable.
445  */
446 template <class CONT, class ALLOC, class VALLOC>
447 auto
448 ACCESSOR::getPackedLinkVectorSpan (AuxVectorData& container) const
449  -> PackedLinkVector_span
450 {
451  auto beg = reinterpret_cast<VElt_t*> (container.getDataArray (this->m_auxid));
452  return PackedLinkVector_span (beg, container.size_v());
453 }
454 
455 /**
456  * @brief Get a span over the array of @c DataLinks.
457  * @param container The container from which to fetch the variable.
458  */
459 template <class CONT, class ALLOC, class VALLOC>
460 auto
461 ACCESSOR::getDataLinkSpan (AuxVectorData& container) const
462  -> DataLink_span
463 {
464  const AuxDataSpanBase* sp = container.getDataSpan (this->m_linkedAuxid);
465  return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
466 }
467 
468 /**
469  * @brief Get a span over spans of @c ElementLink proxies.
470  * @param container The container from which to fetch the variable.
471  *
472  * The individual proxies may be converted to or assigned from @c ElementLink.
473  * Each element may also be assigned from a range of @c ElementLink,
474  * or converted to a vector of @c ElementLink.
475  */
476 template <class CONT, class ALLOC, class VALLOC>
477 inline
478 auto
479 ACCESSOR::getDataSpan (AuxVectorData& container) const
480  -> span
481 {
482  return span (getPackedLinkVectorSpan(container),
483  ELSpanConverter (container, this->m_auxid, this->m_linkedAuxid));
484 }
485 
486 
487 /**
488  * @brief Test to see if this variable exists in the store and is writable.
489  * @param e An element of the container in which to test the variable.
490  */
491 template <class CONT, class ALLOC, class VALLOC>
492 inline
493 bool
494 ACCESSOR::isAvailableWritable (AuxElement& e) const
495 {
496  return e.container() &&
497  e.container()->isAvailableWritable (this->m_auxid) &&
498  e.container()->isAvailableWritable (this->m_linkedAuxid);
499 }
500 
501 
502 /**
503  * @brief Test to see if this variable exists in the store and is writable.
504  * @param c The container in which to test the variable.
505  */
506 template <class CONT, class ALLOC, class VALLOC>
507 inline
508 bool
509 ACCESSOR::isAvailableWritable (AuxVectorData& c) const
510 {
511  return c.isAvailableWritable (this->m_auxid) &&
512  c.isAvailableWritable (this->m_linkedAuxid);
513 }
514 
515 
516 #undef ACCESSOR
517 
518 
519 } // namespace SG