2 * Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration.
5 * @file AthContainers/PackedLinkAccessor.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Helper class to provide type-safe access to aux data,
9 * specialized for @c PackedLink.
13#include "AthContainers/AuxElement.h"
14#include "AthContainers/AuxTypeRegistry.h"
15#include "AthContainers/exceptions.h"
16#include "CxxUtils/checker_macros.h"
24 * @param name Name of this aux variable.
26 * The name -> auxid lookup is done here.
28template <class CONT, class ALLOC>
30Accessor<PackedLink<CONT>, ALLOC>::Accessor (const std::string& name)
38 * @param name Name of this aux variable.
39 * @param clsname The name of its associated class. May be blank.
41 * The name -> auxid lookup is done here.
43template <class CONT, class ALLOC>
45Accessor<PackedLink<CONT>, ALLOC>::Accessor (const std::string& name,
46 const std::string& clsname)
47 : Base (name, clsname)
53 * @brief Constructor taking an auxid directly.
54 * @param auxid ID for this auxiliary variable.
56 * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
58template <class CONT, class ALLOC>
60Accessor<PackedLink<CONT>, ALLOC>::Accessor (const SG::auxid_t auxid)
63 // cppcheck-suppress missingReturn; false positive
68 * @brief Fetch the variable for one element.
69 * @param e The element for which to fetch the variable.
71 * Will return an @c ElementLink proxy, which may be converted to
72 * or assigned from an @c ElementLink.
74template <class CONT, class ALLOC>
75template <IsAuxElement ELT>
78Accessor<PackedLink<CONT>, ALLOC>::operator() (ELT& e) const -> ELProxy
80 assert (e.container() != 0);
81 return ELProxy (e.container()->template getData<PLink_t> (this->m_auxid, e.index()),
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.
93 * This allows retrieving aux data by container / index.
95 * Will return an @c ElementLink proxy, which may be converted to
96 * or assigned from an @c ElementLink.
98template <class CONT, class ALLOC>
101Accessor<PackedLink<CONT>, ALLOC>::operator() (AuxVectorData& container,
102 size_t index) const -> ELProxy
104 return ELProxy (container.template getData<PLink_t> (this->m_auxid, index),
107 this->m_linkedAuxid);
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.
116template <class CONT, class ALLOC>
118void Accessor<PackedLink<CONT>, ALLOC>::set (AuxElement& e, const Link_t& l) const
120 set (*e.container(), e.index(), l);
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.
130template <class CONT, class ALLOC>
131void Accessor<PackedLink<CONT>, ALLOC>::set (AuxVectorData& container,
133 const Link_t& x) const
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,
139 this->m_linkedAuxid);
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.
148template <class CONT, class ALLOC>
151Accessor<PackedLink<CONT>, ALLOC>::getPackedLinkArray (AuxVectorData& container) const
154 return reinterpret_cast<PLink_t*> (container.getDataArray (this->m_auxid));
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.
162template <class CONT, class ALLOC>
165Accessor<PackedLink<CONT>, ALLOC>::getDataLinkArray (AuxVectorData& container) const
168 return reinterpret_cast<DLink_t*>
169 (container.getDataArray (this->m_linkedAuxid));
174 * @brief Get a span over the array of @c PackedLinks.
175 * @param container The container from which to fetch the variable.
177template <class CONT, class ALLOC>
180Accessor<PackedLink<CONT>, ALLOC>::getPackedLinkSpan (AuxVectorData& container) const
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;
188 beg = reinterpret_cast<PLink_t*> (container.getDataArray (this->m_auxid));
190 return PackedLink_span (beg, sz);
195 * @brief Get a span over the array of @c DataLinks.
196 * @param container The container from which to fetch the variable.
198template <class CONT, class ALLOC>
201Accessor<PackedLink<CONT>, ALLOC>::getDataLinkSpan (AuxVectorData& container) const
204 const AuxDataSpanBase sp = *container.getDataSpan (this->m_linkedAuxid);
206 // Accessibility check. ??? Can we get rid of this?
207 (void)container.getDataArray (this->m_linkedAuxid);
209 return DataLink_span (reinterpret_cast<DLink_t*>(sp.beg), sp.size);
215 * @brief Get a span of @c ElementLink proxies.
216 * @param container The container from which to fetch the variable.
218 * The proxies may be converted to or assigned from @c ElementLink.
220template <class CONT, class ALLOC>
223Accessor<PackedLink<CONT>, ALLOC>::getDataSpan (AuxVectorData& container) const
226 return span (getPackedLinkSpan(container),
227 detail::PackedLinkConverter<CONT> (container,
229 this->m_linkedAuxid));
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.
237template <class CONT, class ALLOC>
240Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxElement& e) const
242 return e.container() &&
243 e.container()->isAvailableWritable (this->m_auxid) &&
244 e.container()->isAvailableWritable (this->m_linkedAuxid);
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.
252template <class CONT, class ALLOC>
255Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxVectorData& c) const
257 return c.isAvailableWritable (this->m_auxid) &&
258 c.isAvailableWritable (this->m_linkedAuxid);
262//************************************************************************
265// To make the declarations a bit more readable.
266#define ACCESSOR Accessor<std::vector<PackedLink<CONT>, VALLOC>, ALLOC>
270 * @brief Constructor.
271 * @param name Name of this aux variable.
273 * The name -> auxid lookup is done here.
275template <class CONT, class ALLOC, class VALLOC>
277ACCESSOR::Accessor (const std::string& name)
284 * @brief Constructor.
285 * @param name Name of this aux variable.
286 * @param clsname The name of its associated class. May be blank.
288 * The name -> auxid lookup is done here.
290template <class CONT, class ALLOC, class VALLOC>
292ACCESSOR::Accessor (const std::string& name,
293 const std::string& clsname)
294 : Base (name, clsname)
300 * @brief Constructor taking an auxid directly.
301 * @param auxid ID for this auxiliary variable.
303 * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
305template <class CONT, class ALLOC, class VALLOC>
307ACCESSOR::Accessor (const SG::auxid_t auxid)
314 * @brief Fetch the variable for one element.
315 * @param e The element for which to fetch the variable.
317 * This will return a range of @c ElementLink proxies.
318 * These proxies may be converted to or assigned from @c ElementLink.
320template <class CONT, class ALLOC, class VALLOC>
321template <IsAuxElement ELT>
323ACCESSOR::operator() (ELT& e) const -> elt_span
325 assert (e.container() != 0);
326 VElt_t* veltArr = getPackedLinkVectorArray(*e.container());
327 return elt_span (veltArr[e.index()], *e.container(),
329 this->m_linkedAuxid);
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.
338 * This allows retrieving aux data by container / index.
340 * This will return a range of @c ElementLink proxies.
341 * These proxies may be converted to or assigned from @c ElementLink.
343template <class CONT, class ALLOC, class VALLOC>
345ACCESSOR::operator() (AuxVectorData& container,
346 size_t index) const -> elt_span
348 VElt_t* veltArr = getPackedLinkVectorArray(container);
349 return elt_span (veltArr[index], container,
351 this->m_linkedAuxid);
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.
360template <class CONT, class ALLOC, class VALLOC>
361template <detail::ElementLinkRange<CONT> RANGE>
362void ACCESSOR::set (AuxElement& e, const RANGE& r) const
364 set (*e.container(), e.index(), r);
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.
374template <class CONT, class ALLOC, class VALLOC>
375template <detail::ElementLinkRange<CONT> RANGE>
376void ACCESSOR::set (AuxVectorData& container,
378 const RANGE& r) const
380 detail::PackedLinkConverter<CONT> cnv (container,
382 this->m_linkedAuxid);
383 VElt_t& velt = container.template getData<VElt_t> (this->m_auxid, index);
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.
392template <class CONT, class ALLOC, class VALLOC>
395ACCESSOR::getPackedLinkVectorArray (AuxVectorData& container) const
398 return reinterpret_cast<VElt_t*>
399 (container.getDataArray (this->m_auxid));
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.
407template <class CONT, class ALLOC, class VALLOC>
410ACCESSOR::getDataLinkArray (AuxVectorData& container) const
413 return reinterpret_cast<DLink_t*>
414 (container.getDataArray (this->m_linkedAuxid));
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.
422template <class CONT, class ALLOC, class VALLOC>
425ACCESSOR::getPackedLinkSpan (AuxElement& e) const
428 auto elt = reinterpret_cast<VElt_t*>
429 (e.container()->getDataArray (this->m_auxid)) + e.index();
430 return PackedLink_span (elt->data(), elt->size());
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.
439template <class CONT, class ALLOC, class VALLOC>
442ACCESSOR::getPackedLinkSpan (AuxVectorData& container,
446 auto elt = reinterpret_cast<VElt_t*>
447 (container.getDataArray (this->m_auxid)) + index;
448 return PackedLink_span (elt->data(), elt->size());
453 * @brief Get a span over the vectors of @c PackedLinks.
454 * @param container The container from which to fetch the variable.
456template <class CONT, class ALLOC, class VALLOC>
458ACCESSOR::getPackedLinkVectorSpan (AuxVectorData& container) const
459 -> PackedLinkVector_span
461 auto beg = reinterpret_cast<VElt_t*> (container.getDataArray (this->m_auxid));
462 return PackedLinkVector_span (beg, container.size_v());
466 * @brief Get a span over the array of @c DataLinks.
467 * @param container The container from which to fetch the variable.
469template <class CONT, class ALLOC, class VALLOC>
471ACCESSOR::getDataLinkSpan (AuxVectorData& container) const
474 const AuxDataSpanBase* sp = container.getDataSpan (this->m_linkedAuxid);
475 return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
479 * @brief Get a span over spans of @c ElementLink proxies.
480 * @param container The container from which to fetch the variable.
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.
486template <class CONT, class ALLOC, class VALLOC>
489ACCESSOR::getDataSpan (AuxVectorData& container) const
492 return span (getPackedLinkVectorSpan(container),
493 ELSpanConverter (container, this->m_auxid, this->m_linkedAuxid));
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.
501template <class CONT, class ALLOC, class VALLOC>
504ACCESSOR::isAvailableWritable (AuxElement& e) const
506 return e.container() &&
507 e.container()->isAvailableWritable (this->m_auxid) &&
508 e.container()->isAvailableWritable (this->m_linkedAuxid);
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.
516template <class CONT, class ALLOC, class VALLOC>
519ACCESSOR::isAvailableWritable (AuxVectorData& c) const
521 return c.isAvailableWritable (this->m_auxid) &&
522 c.isAvailableWritable (this->m_linkedAuxid);