ATLAS Offline Software
Loading...
Searching...
No Matches
PackedLinkAccessor.icc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2026 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
19namespace 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 */
28template <class CONT, class ALLOC>
29inline
30Accessor<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 */
43template <class CONT, class ALLOC>
44inline
45Accessor<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 */
58template <class CONT, class ALLOC>
59inline
60Accessor<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 */
74template <class CONT, class ALLOC>
75template <IsAuxElement ELT>
76inline
77auto
78Accessor<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 */
98template <class CONT, class ALLOC>
99inline
100auto
101Accessor<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 */
116template <class CONT, class ALLOC>
117inline
118void 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 */
130template <class CONT, class ALLOC>
131void 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 */
148template <class CONT, class ALLOC>
149inline
150auto
151Accessor<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 */
162template <class CONT, class ALLOC>
163inline
164auto
165Accessor<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 */
177template <class CONT, class ALLOC>
178inline
179auto
180Accessor<PackedLink<CONT>, ALLOC>::getPackedLinkSpan (AuxVectorData& container) const
181 -> PackedLink_span
182{
183 // nb. AuxVectorData::getDataSpan is suitable only for const;
184 // getDataArray may throw if the container is empty.
185 size_t sz = container.size_v();
186 PLink_t* beg = nullptr;
187 if (sz) {
188 beg = reinterpret_cast<PLink_t*> (container.getDataArray (this->m_auxid));
189 }
190 return PackedLink_span (beg, sz);
191}
192
193
194/**
195 * @brief Get a span over the array of @c DataLinks.
196 * @param container The container from which to fetch the variable.
197 */
198template <class CONT, class ALLOC>
199inline
200auto
201Accessor<PackedLink<CONT>, ALLOC>::getDataLinkSpan (AuxVectorData& container) const
202 -> DataLink_span
203{
204 const AuxDataSpanBase sp = *container.getDataSpan (this->m_linkedAuxid);
205 if (sp.size > 0) {
206 // Accessibility check. ??? Can we get rid of this?
207 (void)container.getDataArray (this->m_linkedAuxid);
208 }
209 return DataLink_span (reinterpret_cast<DLink_t*>(sp.beg), sp.size);
210}
211
212
213
214/**
215 * @brief Get a span of @c ElementLink proxies.
216 * @param container The container from which to fetch the variable.
217 *
218 * The proxies may be converted to or assigned from @c ElementLink.
219 */
220template <class CONT, class ALLOC>
221inline
222auto
223Accessor<PackedLink<CONT>, ALLOC>::getDataSpan (AuxVectorData& container) const
224 -> span
225{
226 return span (getPackedLinkSpan(container),
227 detail::PackedLinkConverter<CONT> (container,
228 this->m_auxid,
229 this->m_linkedAuxid));
230}
231
232
233/**
234 * @brief Test to see if this variable exists in the store and is writable.
235 * @param e An element of the container which to test the variable.
236 */
237template <class CONT, class ALLOC>
238inline
239bool
240Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxElement& e) const
241{
242 return e.container() &&
243 e.container()->isAvailableWritable (this->m_auxid) &&
244 e.container()->isAvailableWritable (this->m_linkedAuxid);
245}
246
247
248/**
249 * @brief Test to see if this variable exists in the store and is writable.
250 * @param c The container which to test the variable.
251 */
252template <class CONT, class ALLOC>
253inline
254bool
255Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxVectorData& c) const
256{
257 return c.isAvailableWritable (this->m_auxid) &&
258 c.isAvailableWritable (this->m_linkedAuxid);
259}
260
261
262//************************************************************************
263
264
265// To make the declarations a bit more readable.
266#define ACCESSOR Accessor<std::vector<PackedLink<CONT>, VALLOC>, ALLOC>
267
268
269/**
270 * @brief Constructor.
271 * @param name Name of this aux variable.
272 *
273 * The name -> auxid lookup is done here.
274 */
275template <class CONT, class ALLOC, class VALLOC>
276inline
277ACCESSOR::Accessor (const std::string& name)
278 : Base (name)
279{
280}
281
282
283/**
284 * @brief Constructor.
285 * @param name Name of this aux variable.
286 * @param clsname The name of its associated class. May be blank.
287 *
288 * The name -> auxid lookup is done here.
289 */
290template <class CONT, class ALLOC, class VALLOC>
291inline
292ACCESSOR::Accessor (const std::string& name,
293 const std::string& clsname)
294 : Base (name, clsname)
295{
296}
297
298
299/**
300 * @brief Constructor taking an auxid directly.
301 * @param auxid ID for this auxiliary variable.
302 *
303 * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
304 */
305template <class CONT, class ALLOC, class VALLOC>
306inline
307ACCESSOR::Accessor (const SG::auxid_t auxid)
308 : Base (auxid)
309{
310}
311
312
313/**
314 * @brief Fetch the variable for one element.
315 * @param e The element for which to fetch the variable.
316 *
317 * This will return a range of @c ElementLink proxies.
318 * These proxies may be converted to or assigned from @c ElementLink.
319 */
320template <class CONT, class ALLOC, class VALLOC>
321template <IsAuxElement ELT>
322auto
323ACCESSOR::operator() (ELT& e) const -> elt_span
324{
325 assert (e.container() != 0);
326 VElt_t* veltArr = getPackedLinkVectorArray(*e.container());
327 return elt_span (veltArr[e.index()], *e.container(),
328 this->m_auxid,
329 this->m_linkedAuxid);
330}
331
332
333/**
334 * @brief Fetch the variable for one element, as a non-const reference.
335 * @param container The container from which to fetch the variable.
336 * @param index The index of the desired element.
337 *
338 * This allows retrieving aux data by container / index.
339 *
340 * This will return a range of @c ElementLink proxies.
341 * These proxies may be converted to or assigned from @c ElementLink.
342 */
343template <class CONT, class ALLOC, class VALLOC>
344auto
345ACCESSOR::operator() (AuxVectorData& container,
346 size_t index) const -> elt_span
347{
348 VElt_t* veltArr = getPackedLinkVectorArray(container);
349 return elt_span (veltArr[index], container,
350 this->m_auxid,
351 this->m_linkedAuxid);
352}
353
354
355/**
356 * @brief Set the variable for one element.
357 * @param e The element for which to fetch the variable.
358 * @param r The variable value to set, as a range over @c ElementLink.
359 */
360template <class CONT, class ALLOC, class VALLOC>
361template <detail::ElementLinkRange<CONT> RANGE>
362void ACCESSOR::set (AuxElement& e, const RANGE& r) const
363{
364 set (*e.container(), e.index(), r);
365}
366
367
368/**
369 * @brief Set the variable for one element.
370 * @param container The container for which to set the variable.
371 * @param index The index of the desired element.
372 * @param r The variable value to set, as a range over @c ElementLink.
373 */
374template <class CONT, class ALLOC, class VALLOC>
375template <detail::ElementLinkRange<CONT> RANGE>
376void ACCESSOR::set (AuxVectorData& container,
377 size_t index,
378 const RANGE& r) const
379{
380 detail::PackedLinkConverter<CONT> cnv (container,
381 this->m_auxid,
382 this->m_linkedAuxid);
383 VElt_t& velt = container.template getData<VElt_t> (this->m_auxid, index);
384 cnv.set (velt, r);
385}
386
387
388/**
389 * @brief Get a pointer to the start of the array of vectors of @c PackedLinks.
390 * @param container The container from which to fetch the variable.
391 */
392template <class CONT, class ALLOC, class VALLOC>
393inline
394auto
395ACCESSOR::getPackedLinkVectorArray (AuxVectorData& container) const
396 -> VElt_t*
397{
398 return reinterpret_cast<VElt_t*>
399 (container.getDataArray (this->m_auxid));
400}
401
402
403/**
404 * @brief Get a pointer to the start of the linked array of @c DataLinks.
405 * @param container The container from which to fetch the variable.
406 */
407template <class CONT, class ALLOC, class VALLOC>
408inline
409auto
410ACCESSOR::getDataLinkArray (AuxVectorData& container) const
411 -> DLink_t*
412{
413 return reinterpret_cast<DLink_t*>
414 (container.getDataArray (this->m_linkedAuxid));
415}
416
417
418/**
419 * @brief Get a span over the vector of @c PackedLinks for a given element.
420 * @param e The element for which to fetch the variable.
421 */
422template <class CONT, class ALLOC, class VALLOC>
423inline
424auto
425ACCESSOR::getPackedLinkSpan (AuxElement& e) const
426 -> PackedLink_span
427{
428 auto elt = reinterpret_cast<VElt_t*>
429 (e.container()->getDataArray (this->m_auxid)) + e.index();
430 return PackedLink_span (elt->data(), elt->size());
431}
432
433
434/**
435 * @brief Get a span over the vector of @c PackedLinks for a given element.
436 * @param container The container from which to fetch the variable.
437 * @param index The index of the desired element.
438 */
439template <class CONT, class ALLOC, class VALLOC>
440inline
441auto
442ACCESSOR::getPackedLinkSpan (AuxVectorData& container,
443 size_t index) const
444 -> PackedLink_span
445{
446 auto elt = reinterpret_cast<VElt_t*>
447 (container.getDataArray (this->m_auxid)) + index;
448 return PackedLink_span (elt->data(), elt->size());
449}
450
451
452/**
453 * @brief Get a span over the vectors of @c PackedLinks.
454 * @param container The container from which to fetch the variable.
455 */
456template <class CONT, class ALLOC, class VALLOC>
457auto
458ACCESSOR::getPackedLinkVectorSpan (AuxVectorData& container) const
459 -> PackedLinkVector_span
460{
461 auto beg = reinterpret_cast<VElt_t*> (container.getDataArray (this->m_auxid));
462 return PackedLinkVector_span (beg, container.size_v());
463}
464
465/**
466 * @brief Get a span over the array of @c DataLinks.
467 * @param container The container from which to fetch the variable.
468 */
469template <class CONT, class ALLOC, class VALLOC>
470auto
471ACCESSOR::getDataLinkSpan (AuxVectorData& container) const
472 -> DataLink_span
473{
474 const AuxDataSpanBase* sp = container.getDataSpan (this->m_linkedAuxid);
475 return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
476}
477
478/**
479 * @brief Get a span over spans of @c ElementLink proxies.
480 * @param container The container from which to fetch the variable.
481 *
482 * The individual proxies may be converted to or assigned from @c ElementLink.
483 * Each element may also be assigned from a range of @c ElementLink,
484 * or converted to a vector of @c ElementLink.
485 */
486template <class CONT, class ALLOC, class VALLOC>
487inline
488auto
489ACCESSOR::getDataSpan (AuxVectorData& container) const
490 -> span
491{
492 return span (getPackedLinkVectorSpan(container),
493 ELSpanConverter (container, this->m_auxid, this->m_linkedAuxid));
494}
495
496
497/**
498 * @brief Test to see if this variable exists in the store and is writable.
499 * @param e An element of the container in which to test the variable.
500 */
501template <class CONT, class ALLOC, class VALLOC>
502inline
503bool
504ACCESSOR::isAvailableWritable (AuxElement& e) const
505{
506 return e.container() &&
507 e.container()->isAvailableWritable (this->m_auxid) &&
508 e.container()->isAvailableWritable (this->m_linkedAuxid);
509}
510
511
512/**
513 * @brief Test to see if this variable exists in the store and is writable.
514 * @param c The container in which to test the variable.
515 */
516template <class CONT, class ALLOC, class VALLOC>
517inline
518bool
519ACCESSOR::isAvailableWritable (AuxVectorData& c) const
520{
521 return c.isAvailableWritable (this->m_auxid) &&
522 c.isAvailableWritable (this->m_linkedAuxid);
523}
524
525
526#undef ACCESSOR
527
528
529} // namespace SG