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.
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 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.
192template <class CONT, class ALLOC>
195Accessor<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.
210template <class CONT, class ALLOC>
213Accessor<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.
227template <class CONT, class ALLOC>
230Accessor<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.
242template <class CONT, class ALLOC>
245Accessor<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.
265template <class CONT, class ALLOC, class VALLOC>
267ACCESSOR::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.
280template <class CONT, class ALLOC, class VALLOC>
282ACCESSOR::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.
295template <class CONT, class ALLOC, class VALLOC>
297ACCESSOR::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.
310template <class CONT, class ALLOC, class VALLOC>
311template <IsAuxElement ELT>
313ACCESSOR::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.
333template <class CONT, class ALLOC, class VALLOC>
335ACCESSOR::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.
350template <class CONT, class ALLOC, class VALLOC>
351template <detail::ElementLinkRange<CONT> RANGE>
352void 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.
364template <class CONT, class ALLOC, class VALLOC>
365template <detail::ElementLinkRange<CONT> RANGE>
366void 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.
382template <class CONT, class ALLOC, class VALLOC>
385ACCESSOR::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.
397template <class CONT, class ALLOC, class VALLOC>
400ACCESSOR::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.
412template <class CONT, class ALLOC, class VALLOC>
415ACCESSOR::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.
429template <class CONT, class ALLOC, class VALLOC>
432ACCESSOR::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.
446template <class CONT, class ALLOC, class VALLOC>
448ACCESSOR::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.
459template <class CONT, class ALLOC, class VALLOC>
461ACCESSOR::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.
476template <class CONT, class ALLOC, class VALLOC>
479ACCESSOR::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.
491template <class CONT, class ALLOC, class VALLOC>
494ACCESSOR::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.
506template <class CONT, class ALLOC, class VALLOC>
509ACCESSOR::isAvailableWritable (AuxVectorData& c) const
511 return c.isAvailableWritable (this->m_auxid) &&
512 c.isAvailableWritable (this->m_linkedAuxid);