2 * Copyright (C) 2002-2024 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.
28 template <class CONT, class ALLOC>
30 Accessor<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.
43 template <class CONT, class ALLOC>
45 Accessor<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.
58 template <class CONT, class ALLOC>
60 Accessor<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.
74 template <class CONT, class ALLOC>
75 template <IsAuxElement ELT>
78 Accessor<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.
98 template <class CONT, class ALLOC>
101 Accessor<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.
116 template <class CONT, class ALLOC>
118 void 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.
130 template <class CONT, class ALLOC>
131 void 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.
148 template <class CONT, class ALLOC>
151 Accessor<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.
162 template <class CONT, class ALLOC>
165 Accessor<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.
177 template <class CONT, class ALLOC>
180 Accessor<PackedLink<CONT>, ALLOC>::getPackedLinkSpan (AuxVectorData& container) const
183 auto beg = reinterpret_cast<PLink_t*>(container.getDataArray (this->m_auxid));
184 return PackedLink_span (beg, container.size_v());
189 * @brief Get a span over the array of @c DataLinks.
190 * @param container The container from which to fetch the variable.
192 template <class CONT, class ALLOC>
195 Accessor<PackedLink<CONT>, ALLOC>::getDataLinkSpan (AuxVectorData& container) const
198 const AuxDataSpanBase* sp = container.getDataSpan (this->m_linkedAuxid);
199 return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
205 * @brief Get a span of @c ElementLink proxies.
206 * @param container The container from which to fetch the variable.
208 * The proxies may be converted to or assigned from @c ElementLink.
210 template <class CONT, class ALLOC>
213 Accessor<PackedLink<CONT>, ALLOC>::getDataSpan (AuxVectorData& container) const
216 return span (getPackedLinkSpan(container),
217 detail::PackedLinkConverter<CONT> (container,
219 this->m_linkedAuxid));
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.
227 template <class CONT, class ALLOC>
230 Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxElement& e) const
232 return e.container() &&
233 e.container()->isAvailableWritable (this->m_auxid) &&
234 e.container()->isAvailableWritable (this->m_linkedAuxid);
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.
242 template <class CONT, class ALLOC>
245 Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxVectorData& c) const
247 return c.isAvailableWritable (this->m_auxid) &&
248 c.isAvailableWritable (this->m_linkedAuxid);
252 //************************************************************************
255 // To make the declarations a bit more readable.
256 #define ACCESSOR Accessor<std::vector<PackedLink<CONT>, VALLOC>, ALLOC>
260 * @brief Constructor.
261 * @param name Name of this aux variable.
263 * The name -> auxid lookup is done here.
265 template <class CONT, class ALLOC, class VALLOC>
267 ACCESSOR::Accessor (const std::string& name)
274 * @brief Constructor.
275 * @param name Name of this aux variable.
276 * @param clsname The name of its associated class. May be blank.
278 * The name -> auxid lookup is done here.
280 template <class CONT, class ALLOC, class VALLOC>
282 ACCESSOR::Accessor (const std::string& name,
283 const std::string& clsname)
284 : Base (name, clsname)
290 * @brief Constructor taking an auxid directly.
291 * @param auxid ID for this auxiliary variable.
293 * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
295 template <class CONT, class ALLOC, class VALLOC>
297 ACCESSOR::Accessor (const SG::auxid_t auxid)
304 * @brief Fetch the variable for one element.
305 * @param e The element for which to fetch the variable.
307 * This will return a range of @c ElementLink proxies.
308 * These proxies may be converted to or assigned from @c ElementLink.
310 template <class CONT, class ALLOC, class VALLOC>
311 template <IsAuxElement ELT>
313 ACCESSOR::operator() (ELT& e) const -> elt_span
315 assert (e.container() != 0);
316 VElt_t* veltArr = getPackedLinkVectorArray(*e.container());
317 return elt_span (veltArr[e.index()], *e.container(),
319 this->m_linkedAuxid);
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.
328 * This allows retrieving aux data by container / index.
330 * This will return a range of @c ElementLink proxies.
331 * These proxies may be converted to or assigned from @c ElementLink.
333 template <class CONT, class ALLOC, class VALLOC>
335 ACCESSOR::operator() (AuxVectorData& container,
336 size_t index) const -> elt_span
338 VElt_t* veltArr = getPackedLinkVectorArray(container);
339 return elt_span (veltArr[index], container,
341 this->m_linkedAuxid);
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.
350 template <class CONT, class ALLOC, class VALLOC>
351 template <detail::ElementLinkRange<CONT> RANGE>
352 void ACCESSOR::set (AuxElement& e, const RANGE& r) const
354 set (*e.container(), e.index(), r);
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.
364 template <class CONT, class ALLOC, class VALLOC>
365 template <detail::ElementLinkRange<CONT> RANGE>
366 void ACCESSOR::set (AuxVectorData& container,
368 const RANGE& r) const
370 detail::PackedLinkConverter<CONT> cnv (container,
372 this->m_linkedAuxid);
373 VElt_t& velt = container.template getData<VElt_t> (this->m_auxid, index);
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.
382 template <class CONT, class ALLOC, class VALLOC>
385 ACCESSOR::getPackedLinkVectorArray (AuxVectorData& container) const
388 return reinterpret_cast<VElt_t*>
389 (container.getDataArray (this->m_auxid));
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.
397 template <class CONT, class ALLOC, class VALLOC>
400 ACCESSOR::getDataLinkArray (AuxVectorData& container) const
403 return reinterpret_cast<DLink_t*>
404 (container.getDataArray (this->m_linkedAuxid));
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.
412 template <class CONT, class ALLOC, class VALLOC>
415 ACCESSOR::getPackedLinkSpan (AuxElement& e) const
418 auto elt = reinterpret_cast<VElt_t*>
419 (e.container()->getDataArray (this->m_auxid)) + e.index();
420 return PackedLink_span (elt->data(), elt->size());
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.
429 template <class CONT, class ALLOC, class VALLOC>
432 ACCESSOR::getPackedLinkSpan (AuxVectorData& container,
436 auto elt = reinterpret_cast<VElt_t*>
437 (container.getDataArray (this->m_auxid)) + index;
438 return PackedLink_span (elt->data(), elt->size());
443 * @brief Get a span over the vectors of @c PackedLinks.
444 * @param container The container from which to fetch the variable.
446 template <class CONT, class ALLOC, class VALLOC>
448 ACCESSOR::getPackedLinkVectorSpan (AuxVectorData& container) const
449 -> PackedLinkVector_span
451 auto beg = reinterpret_cast<VElt_t*> (container.getDataArray (this->m_auxid));
452 return PackedLinkVector_span (beg, container.size_v());
456 * @brief Get a span over the array of @c DataLinks.
457 * @param container The container from which to fetch the variable.
459 template <class CONT, class ALLOC, class VALLOC>
461 ACCESSOR::getDataLinkSpan (AuxVectorData& container) const
464 const AuxDataSpanBase* sp = container.getDataSpan (this->m_linkedAuxid);
465 return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
469 * @brief Get a span over spans of @c ElementLink proxies.
470 * @param container The container from which to fetch the variable.
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.
476 template <class CONT, class ALLOC, class VALLOC>
479 ACCESSOR::getDataSpan (AuxVectorData& container) const
482 return span (getPackedLinkVectorSpan(container),
483 ELSpanConverter (container, this->m_auxid, this->m_linkedAuxid));
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.
491 template <class CONT, class ALLOC, class VALLOC>
494 ACCESSOR::isAvailableWritable (AuxElement& e) const
496 return e.container() &&
497 e.container()->isAvailableWritable (this->m_auxid) &&
498 e.container()->isAvailableWritable (this->m_linkedAuxid);
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.
506 template <class CONT, class ALLOC, class VALLOC>
509 ACCESSOR::isAvailableWritable (AuxVectorData& c) const
511 return c.isAvailableWritable (this->m_auxid) &&
512 c.isAvailableWritable (this->m_linkedAuxid);