2 * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
5 * @file AthContainers/tools/ELProxy.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Helpers for proxying ElementLink for PackedLink accessors.
12 namespace SG { namespace detail {
17 * @param cnv Converter to copy.
21 ELProxyValBase<CONT>::ELProxyValBase (PackedLinkConverter<CONT>& cnv) :
29 * @param container Container holding the variables.
30 * @param auxid The ID of the PackedLink variable.
31 * @param linked_auxid The ID of the linked DataLinks.
35 ELProxyValBase<CONT>::ELProxyValBase (AuxVectorData& container,
37 SG::auxid_t linked_auxid)
38 : m_cnv (container, auxid, linked_auxid)
40 // cppcheck-suppress missingReturn; false positive
46 * @param cnv Converter to reference.
50 ELProxyRefBase<CONT>::ELProxyRefBase (PackedLinkConverter<CONT>& cnv)
58 * @param pl @c PackedLink object to proxy.
59 * @param cnv Converter to use.
63 ELProxyT<BASE>::ELProxyT (PLink_t& pl, PackedLinkConverter<Cont_t>& cnv)
72 * @param container Container holding the variables.
73 * @param auxid The ID of the PackedLink variable.
74 * @param linked_auxid The ID of the linked DataLinks.
76 * This constructor can only be used if the converter is being
81 ELProxyT<BASE>::ELProxyT (PLink_t& pl, AuxVectorData& container,
83 SG::auxid_t linked_auxid)
84 : BASE (container, auxid, linked_auxid),
91 * @brief Convert the held @c PackedLink to an @c ElementLink.
95 ELProxyT<BASE>::operator const Link_t() const
97 return this->m_cnv (m_pl);
102 * @brief Update the held @c PackedLink from an @c ElementLink.
103 * @param link The @c ElementLink from which to update.
105 template <class BASE>
107 auto ELProxyT<BASE>::operator= (const Link_t& link) -> const Link_t
109 this->m_cnv.set (m_pl, link);
115 * @brief Equality comparison with ElementLink.
116 * @param l The link with which to compare.
118 * (Default conversions don't suffice to make this work.)
120 template <class BASE>
122 bool ELProxyT<BASE>::operator== (const Link_t& l) const
124 return Link_t(*this) == l;
129 * @brief Equality comparison with another proxy.
130 * @param l The proxy with which to compare.
132 * (Default conversions don't suffice to make this work.)
134 template <class BASE>
136 bool ELProxyT<BASE>::operator== (const ELProxyT& p) const
138 return m_pl == p.m_pl;
142 //***************************************************************************
146 * @brief Constructor.
147 * @param cnv Converter. We'll make a copy of this.
149 template <class PROXY>
151 ELProxyConverter<PROXY>::ELProxyConverter (const Base& cnv)
158 * @brief Constructor.
159 * @param container Container holding the variables.
160 * @param auxid The ID of the PackedLink variable.
161 * @param linked_auxid The ID of the linked DataLinks.
163 template <class PROXY>
165 ELProxyConverter<PROXY>::ELProxyConverter (AuxVectorData& container,
167 SG::auxid_t linked_auxid)
168 : Base (container, auxid, linked_auxid)
174 * @brief Produce a proxy object for a given @c PackedLink.
175 * @param pl The @c PackedLink object to proxy.
177 template <class PROXY>
179 PROXY ELProxyConverter<PROXY>::operator() (PLink_t& pl)
181 return PROXY (pl, *this);
185 //***************************************************************************
189 * @brief Constructor.
190 * @param velt The vector of @c PackedLink that we proxy.
191 * @param container Container holding the variables.
192 * @param auxid The ID of the PackedLink variable.
193 * @param linked_auxid The ID of the linked DataLinks.
195 template <class CONT, class PLINK_ALLOC>
197 ELSpanProxy<CONT, PLINK_ALLOC>::ELSpanProxy (VElt_t& velt,
198 AuxVectorData& container,
200 SG::auxid_t linked_auxid)
201 : Base (PackedLink_span (velt.data(), velt.size()), m_cnv),
203 m_cnv (container, auxid, linked_auxid)
209 * @brief Assign from a range of @c ElementLink.
210 * @param r The range from which to assign.
212 template <class CONT, class PLINK_ALLOC>
213 template <ElementLinkRange<CONT> RANGE>
214 void ELSpanProxy<CONT, PLINK_ALLOC>::operator= (const RANGE& r)
216 auto end = m_velt.end();
219 m_cnv.set (m_velt, r);
221 // Update the range we're proxying if it has changed.
222 if (end != m_velt.end())
224 *static_cast<Base*> (this) =
225 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
231 * @brief Convert to a vector of @c ElementLink.
233 template <class CONT, class PLINK_ALLOC>
234 template <class VALLOC>
235 ELSpanProxy<CONT, PLINK_ALLOC>::operator std::vector<Link_t, VALLOC>() const
237 return std::vector<Link_t, VALLOC> (this->begin(), this->end());
242 * @brief Convert to a vector of @c ElementLink.
244 template <class CONT, class PLINK_ALLOC>
245 auto ELSpanProxy<CONT, PLINK_ALLOC>::asVector() const
246 -> std::vector<Link_t>
248 return std::vector<Link_t> (this->begin(), this->end());
253 * @brief Equality testing.
255 template <class CONT, class PLINK_ALLOC>
256 template <class VALLOC>
257 bool ELSpanProxy<CONT, PLINK_ALLOC>::operator== (const std::vector<Link_t, VALLOC>& v) const
259 return this->asVector() == v;
264 * @brief Add a new link to this vector of links.
265 * @param l The new link to add.
267 template <class CONT, class PLINK_ALLOC>
268 void ELSpanProxy<CONT, PLINK_ALLOC>::push_back (const Link_t& l)
270 insert (this->end(), 1, l);
275 * @brief Clear this vector of links.
277 template <class CONT, class PLINK_ALLOC>
278 void ELSpanProxy<CONT, PLINK_ALLOC>::clear()
281 *static_cast<Base*> (this) =
282 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
287 * @brief Resize this vector of links.
288 * @param n The desired new size.
289 * @param l Value with which to fill any new elements.
291 template <class CONT, class PLINK_ALLOC>
292 void ELSpanProxy<CONT, PLINK_ALLOC>::resize (size_t n,
293 const Link_t& l /*= Link_t()*/)
295 size_t sz = this->size();
298 m_cnv.set (plink, l);
299 m_velt.resize (n, plink);
300 *static_cast<Base*> (this) =
301 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
305 *static_cast<Base*> (this) =
306 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
312 * @brief Erase one element from this vector of links.
313 * @param pos The element to erase.
315 template <class CONT, class PLINK_ALLOC>
316 void ELSpanProxy<CONT, PLINK_ALLOC>::erase (iterator pos)
318 m_velt.erase (m_velt.begin() + (pos - this->begin()));
319 *static_cast<Base*> (this) =
320 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
325 * @brief Erase a range of elements from this vector of links.
326 * @param first The first element to erase.
327 * @param last One past the last element to erase.
328 * @param pos The element to erase.
330 template <class CONT, class PLINK_ALLOC>
331 void ELSpanProxy<CONT, PLINK_ALLOC>::erase (iterator first, iterator last)
333 m_velt.erase (m_velt.begin() + (first - this->begin()),
334 m_velt.begin() + (last - this->begin()));
335 *static_cast<Base*> (this) =
336 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
341 * @brief Insert a new link into this vector of links.
342 * @param pos The position at which to insert the link.
343 * @param l The link to insert.
345 template <class CONT, class PLINK_ALLOC>
346 void ELSpanProxy<CONT, PLINK_ALLOC>::insert (iterator pos, const Link_t& l)
353 * @brief Insert copies of a new link into this vector of links.
354 * @param pos The position at which to insert the link.
355 * @param n Number of copies to insert.
356 * @param l The link(s) to insert.
358 template <class CONT, class PLINK_ALLOC>
359 void ELSpanProxy<CONT, PLINK_ALLOC>::insert (iterator pos, size_t n, const Link_t& l)
361 size_t i = pos - this->begin();
363 m_cnv.set (plink, l);
364 m_velt.insert (m_velt.begin() + i, n, plink);
365 *static_cast<Base*> (this) =
366 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
371 * @brief Insert a range of links into this vector of links.
372 * @param pos The position at which to insert the links.
373 * @param first The first element to insert.
374 * @param last One past the last element to insert.
376 template <class CONT, class PLINK_ALLOC>
377 template <CxxUtils::detail::InputValIterator<ElementLink<CONT> > ITERATOR>
378 void ELSpanProxy<CONT, PLINK_ALLOC>::insert (iterator pos,
379 ITERATOR first, ITERATOR last)
381 insert_range (pos, std::ranges::subrange (first, last));
386 * @brief Insert a range of links into this vector of links.
387 * @param pos The position at which to insert the links.
388 * @param range The range to insert.
390 template <class CONT, class PLINK_ALLOC>
391 template <ElementLinkRange<CONT> RANGE>
392 void ELSpanProxy<CONT, PLINK_ALLOC>::insert_range (iterator pos,
395 m_cnv.insert (m_velt, pos - this->begin(), range);
396 *static_cast<Base*> (this) =
397 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
402 * @brief Append a range of links to the end of this vector of links.
403 * @param range The range to append.
405 template <class CONT, class PLINK_ALLOC>
406 template <ElementLinkRange<CONT> RANGE>
407 void ELSpanProxy<CONT, PLINK_ALLOC>::append_range (const RANGE& range)
409 insert_range (this->end(), range);
414 * @brief Remove the last element in this vector of links.
416 template <class CONT, class PLINK_ALLOC>
417 void ELSpanProxy<CONT, PLINK_ALLOC>::pop_back()
419 erase (this->end()-1);
424 * @brief Set this vector of links to copies of a new link.
425 * @param n Number of copies to insert.
426 * @param l The link(s) to insert.
428 template <class CONT, class PLINK_ALLOC>
429 void ELSpanProxy<CONT, PLINK_ALLOC>::assign (size_t n, const Link_t& l)
432 insert (this->begin(), n, l);
437 * @brief Set this vector of links to a range of links.
438 * @param first The first element to copy.
439 * @param last One past the last element to copy.
441 template <class CONT, class PLINK_ALLOC>
442 template <CxxUtils::detail::InputValIterator<ElementLink<CONT> > ITERATOR>
443 void ELSpanProxy<CONT, PLINK_ALLOC>::assign (ITERATOR first, ITERATOR last)
445 assign_range (std::ranges::subrange (first, last));
450 * @brief Set this vector of links to a range of links.
451 * @param range The range of links to copy.
452 * @param last One past the last element to copy.
454 template <class CONT, class PLINK_ALLOC>
455 template <ElementLinkRange<CONT> RANGE>
456 void ELSpanProxy<CONT, PLINK_ALLOC>::assign_range (const RANGE& range)
459 insert_range (this->begin(), range);
463 //***************************************************************************
467 * @brief Constructor.
468 * @param container Container holding the variables.
469 * @param auxid The ID of the PackedLink variable.
470 * @param linked_auxid The ID of the linked DataLinks.
472 template <class CONT, class PLINK_ALLOC>
473 ELSpanConverter<CONT, PLINK_ALLOC>::ELSpanConverter (AuxVectorData& container,
475 auxid_t linked_auxid)
476 : m_container (container),
478 m_linkedAuxid (linked_auxid)
484 * @brief Convert from a @c PackedLink vector to a proxy for the span.
485 * @param velt The vector of @c PackedLink that we proxy.
487 template <class CONT, class PLINK_ALLOC>
488 auto ELSpanConverter<CONT, PLINK_ALLOC>::operator() (VElt_t& velt) const
491 AuxVectorData& container ATLAS_THREAD_SAFE = m_container;
492 return value_type (velt, container, m_auxid, m_linkedAuxid);
496 }} // namespace SG::detail