ATLAS Offline Software
Loading...
Searching...
No Matches
ELProxy.icc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
3 */
4/**
5 * @file AthContainers/tools/ELProxy.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Jan, 2024
8 * @brief Helpers for proxying ElementLink for PackedLink accessors.
9 */
10
11
12namespace SG { namespace detail {
13
14
15/**
16 * @brief Constructor.
17 * @param cnv Converter to copy.
18 */
19template <class CONT>
20inline
21ELProxyValBase<CONT>::ELProxyValBase (PackedLinkConverter<CONT>& cnv) :
22 m_cnv (cnv)
23{
24}
25
26
27/**
28 * @brief Constructor.
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.
32 */
33template <class CONT>
34inline
35ELProxyValBase<CONT>::ELProxyValBase (AuxVectorData& container,
36 SG::auxid_t auxid,
37 SG::auxid_t linked_auxid)
38 : m_cnv (container, auxid, linked_auxid)
39{
40 // cppcheck-suppress missingReturn; false positive
41}
42
43
44/**
45 * @brief Constructor.
46 * @param cnv Converter to reference.
47 */
48template <class CONT>
49inline
50ELProxyRefBase<CONT>::ELProxyRefBase (PackedLinkConverter<CONT>& cnv)
51 : m_cnv (cnv)
52{
53}
54
55
56/**
57 * @brief Constructor.
58 * @param pl @c PackedLink object to proxy.
59 * @param cnv Converter to use.
60 */
61template <class BASE>
62inline
63ELProxyT<BASE>::ELProxyT (PLink_t& pl, PackedLinkConverter<Cont_t>& cnv)
64 : BASE (cnv),
65 m_pl (pl)
66{
67}
68
69
70/**
71 * @brief Constructor.
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.
75 *
76 * This constructor can only be used if the converter is being
77 * held by value.
78 */
79template <class BASE>
80inline
81ELProxyT<BASE>::ELProxyT (PLink_t& pl, AuxVectorData& container,
82 SG::auxid_t auxid,
83 SG::auxid_t linked_auxid)
84 : BASE (container, auxid, linked_auxid),
85 m_pl (pl)
86{
87}
88
89
90/**
91 * @brief Convert the held @c PackedLink to an @c ElementLink.
92 */
93template <class BASE>
94inline
95ELProxyT<BASE>::operator const Link_t() const
96{
97 return this->m_cnv (m_pl);
98}
99
100
101/**
102 * @brief Update the held @c PackedLink from an @c ElementLink.
103 * @param link The @c ElementLink from which to update.
104 */
105template <class BASE>
106inline
107auto ELProxyT<BASE>::operator= (const Link_t& link) -> const Link_t
108{
109 this->m_cnv.set (m_pl, link);
110 return link;
111}
112
113
114/**
115 * @brief Equality comparison with ElementLink.
116 * @param l The link with which to compare.
117 *
118 * (Default conversions don't suffice to make this work.)
119 */
120template <class BASE>
121inline
122bool ELProxyT<BASE>::operator== (const Link_t& l) const
123{
124 return Link_t(*this) == l;
125}
126
127
128/**
129 * @brief Equality comparison with another proxy.
130 * @param l The proxy with which to compare.
131 *
132 * (Default conversions don't suffice to make this work.)
133 */
134template <class BASE>
135inline
136bool ELProxyT<BASE>::operator== (const ELProxyT& p) const
137{
138 return m_pl == p.m_pl;
139}
140
141
142//***************************************************************************
143
144
145/**
146 * @brief Constructor.
147 * @param cnv Converter. We'll make a copy of this.
148 */
149template <class PROXY>
150inline
151ELProxyConverter<PROXY>::ELProxyConverter (const Base& cnv)
152 : Base (cnv)
153{
154}
155
156
157/**
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.
162 */
163template <class PROXY>
164inline
165ELProxyConverter<PROXY>::ELProxyConverter (AuxVectorData& container,
166 SG::auxid_t auxid,
167 SG::auxid_t linked_auxid)
168 : Base (container, auxid, linked_auxid)
169{
170}
171
172
173/**
174 * @brief Produce a proxy object for a given @c PackedLink.
175 * @param pl The @c PackedLink object to proxy.
176 */
177template <class PROXY>
178inline
179PROXY ELProxyConverter<PROXY>::operator() (PLink_t& pl)
180{
181 return PROXY (pl, *this);
182}
183
184
185//***************************************************************************
186
187
188/**
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.
194 */
195template <class CONT, class PLINK_ALLOC>
196inline
197ELSpanProxy<CONT, PLINK_ALLOC>::ELSpanProxy (VElt_t& velt,
198 AuxVectorData& container,
199 SG::auxid_t auxid,
200 SG::auxid_t linked_auxid)
201 : Base (PackedLink_span (velt.data(), velt.size()), m_cnv),
202 m_velt (velt),
203 m_cnv (container, auxid, linked_auxid)
204{
205}
206
207
208/**
209 * @brief Assign from a range of @c ElementLink.
210 * @param r The range from which to assign.
211 */
212template <class CONT, class PLINK_ALLOC>
213template <ElementLinkRange<CONT> RANGE>
214void ELSpanProxy<CONT, PLINK_ALLOC>::operator= (const RANGE& r)
215{
216 auto end = m_velt.end();
217
218 // Update @c m_velt.
219 m_cnv.set (m_velt, r);
220
221 // Update the range we're proxying if it has changed.
222 if (end != m_velt.end())
223 {
224 *static_cast<Base*> (this) =
225 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
226 }
227}
228
229
230/**
231 * @brief Convert to a vector of @c ElementLink.
232 */
233template <class CONT, class PLINK_ALLOC>
234template <class VALLOC>
235ELSpanProxy<CONT, PLINK_ALLOC>::operator std::vector<Link_t, VALLOC>() const
236{
237 return std::vector<Link_t, VALLOC> (this->begin(), this->end());
238}
239
240
241/**
242 * @brief Convert to a vector of @c ElementLink.
243 */
244template <class CONT, class PLINK_ALLOC>
245auto ELSpanProxy<CONT, PLINK_ALLOC>::asVector() const
246 -> std::vector<Link_t>
247{
248 return std::vector<Link_t> (this->begin(), this->end());
249}
250
251
252/**
253 * @brief Equality testing.
254 */
255template <class CONT, class PLINK_ALLOC>
256template <class VALLOC>
257bool ELSpanProxy<CONT, PLINK_ALLOC>::operator== (const std::vector<Link_t, VALLOC>& v) const
258{
259 return this->asVector() == v;
260}
261
262
263/**
264 * @brief Add a new link to this vector of links.
265 * @param l The new link to add.
266 */
267template <class CONT, class PLINK_ALLOC>
268void ELSpanProxy<CONT, PLINK_ALLOC>::push_back (const Link_t& l)
269{
270 insert (this->end(), 1, l);
271}
272
273
274/**
275 * @brief Clear this vector of links.
276 */
277template <class CONT, class PLINK_ALLOC>
278void ELSpanProxy<CONT, PLINK_ALLOC>::clear()
279{
280 m_velt.clear();
281 *static_cast<Base*> (this) =
282 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
283}
284
285
286/**
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.
290 */
291template <class CONT, class PLINK_ALLOC>
292void ELSpanProxy<CONT, PLINK_ALLOC>::resize (size_t n,
293 const Link_t& l /*= Link_t()*/)
294{
295 size_t sz = this->size();
296 if (n > sz) {
297 PLink_t plink;
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);
302 }
303 else if (n < sz) {
304 m_velt.resize (n);
305 *static_cast<Base*> (this) =
306 Base (PackedLink_span (m_velt.data(), m_velt.size()), m_cnv);
307 }
308}
309
310
311/**
312 * @brief Erase one element from this vector of links.
313 * @param pos The element to erase.
314 */
315template <class CONT, class PLINK_ALLOC>
316void ELSpanProxy<CONT, PLINK_ALLOC>::erase (iterator pos)
317{
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);
321}
322
323
324/**
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.
329 */
330template <class CONT, class PLINK_ALLOC>
331void ELSpanProxy<CONT, PLINK_ALLOC>::erase (iterator first, iterator last)
332{
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);
337}
338
339
340/**
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.
344 */
345template <class CONT, class PLINK_ALLOC>
346void ELSpanProxy<CONT, PLINK_ALLOC>::insert (iterator pos, const Link_t& l)
347{
348 insert (pos, 1, l);
349}
350
351
352/**
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.
357 */
358template <class CONT, class PLINK_ALLOC>
359void ELSpanProxy<CONT, PLINK_ALLOC>::insert (iterator pos, size_t n, const Link_t& l)
360{
361 size_t i = pos - this->begin();
362 PLink_t plink;
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);
367}
368
369
370/**
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.
375 */
376template <class CONT, class PLINK_ALLOC>
377template <CxxUtils::detail::InputValIterator<ElementLink<CONT> > ITERATOR>
378void ELSpanProxy<CONT, PLINK_ALLOC>::insert (iterator pos,
379 ITERATOR first, ITERATOR last)
380{
381 insert_range (pos, std::ranges::subrange (first, last));
382}
383
384
385/**
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.
389 */
390template <class CONT, class PLINK_ALLOC>
391template <ElementLinkRange<CONT> RANGE>
392void ELSpanProxy<CONT, PLINK_ALLOC>::insert_range (iterator pos,
393 const RANGE& range)
394{
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);
398}
399
400
401/**
402 * @brief Append a range of links to the end of this vector of links.
403 * @param range The range to append.
404 */
405template <class CONT, class PLINK_ALLOC>
406template <ElementLinkRange<CONT> RANGE>
407void ELSpanProxy<CONT, PLINK_ALLOC>::append_range (const RANGE& range)
408{
409 insert_range (this->end(), range);
410}
411
412
413/**
414 * @brief Remove the last element in this vector of links.
415 */
416template <class CONT, class PLINK_ALLOC>
417void ELSpanProxy<CONT, PLINK_ALLOC>::pop_back()
418{
419 erase (this->end()-1);
420}
421
422
423/**
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.
427 */
428template <class CONT, class PLINK_ALLOC>
429void ELSpanProxy<CONT, PLINK_ALLOC>::assign (size_t n, const Link_t& l)
430{
431 clear();
432 insert (this->begin(), n, l);
433}
434
435
436/**
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.
440 */
441template <class CONT, class PLINK_ALLOC>
442template <CxxUtils::detail::InputValIterator<ElementLink<CONT> > ITERATOR>
443void ELSpanProxy<CONT, PLINK_ALLOC>::assign (ITERATOR first, ITERATOR last)
444{
445 assign_range (std::ranges::subrange (first, last));
446}
447
448
449/**
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.
453 */
454template <class CONT, class PLINK_ALLOC>
455template <ElementLinkRange<CONT> RANGE>
456void ELSpanProxy<CONT, PLINK_ALLOC>::assign_range (const RANGE& range)
457{
458 clear();
459 insert_range (this->begin(), range);
460}
461
462
463//***************************************************************************
464
465
466/***
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.
471 */
472template <class CONT, class PLINK_ALLOC>
473ELSpanConverter<CONT, PLINK_ALLOC>::ELSpanConverter (AuxVectorData& container,
474 auxid_t auxid,
475 auxid_t linked_auxid)
476 : m_container (container),
477 m_auxid (auxid),
478 m_linkedAuxid (linked_auxid)
479{
480}
481
482
483/**
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.
486 */
487template <class CONT, class PLINK_ALLOC>
488auto ELSpanConverter<CONT, PLINK_ALLOC>::operator() (VElt_t& velt) const
489 -> value_type
490{
491 AuxVectorData& container ATLAS_THREAD_SAFE = m_container;
492 return value_type (velt, container, m_auxid, m_linkedAuxid);
493}
494
495
496}} // namespace SG::detail