ATLAS Offline Software
Loading...
Searching...
No Matches
PackedLinkAccessor.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/PackedLinkAccessor.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Oct, 2023
8 * @brief Helper class to provide type-safe access to aux data,
9 * specialized for @c PackedLink.
10 */
11
12
13#include "AthContainers/AuxElement.h"
14#include "AthContainers/AuxTypeRegistry.h"
15#include "AthContainers/exceptions.h"
16#include "CxxUtils/checker_macros.h"
17
18
19namespace SG {
20
21
22/**
23 * @brief Constructor.
24 * @param name Name of this aux variable.
25 *
26 * The name -> auxid lookup is done here.
27 */
28template <class CONT, class ALLOC>
29inline
30Accessor<PackedLink<CONT>, ALLOC>::Accessor (const std::string& name)
31 : Base (name)
32{
33}
34
35
36/**
37 * @brief Constructor.
38 * @param name Name of this aux variable.
39 * @param clsname The name of its associated class. May be blank.
40 *
41 * The name -> auxid lookup is done here.
42 */
43template <class CONT, class ALLOC>
44inline
45Accessor<PackedLink<CONT>, ALLOC>::Accessor (const std::string& name,
46 const std::string& clsname)
47 : Base (name, clsname)
48{
49}
50
51
52/**
53 * @brief Constructor taking an auxid directly.
54 * @param auxid ID for this auxiliary variable.
55 *
56 * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
57 */
58template <class CONT, class ALLOC>
59inline
60Accessor<PackedLink<CONT>, ALLOC>::Accessor (const SG::auxid_t auxid)
61 : Base (auxid)
62{
63 // cppcheck-suppress missingReturn; false positive
64}
65
66
67/**
68 * @brief Fetch the variable for one element.
69 * @param e The element for which to fetch the variable.
70 *
71 * Will return an @c ElementLink proxy, which may be converted to
72 * or assigned from an @c ElementLink.
73 */
74template <class CONT, class ALLOC>
75template <IsAuxElement ELT>
76inline
77auto
78Accessor<PackedLink<CONT>, ALLOC>::operator() (ELT& e) const -> ELProxy
79{
80 assert (e.container() != 0);
81 return ELProxy (e.container()->template getData<PLink_t> (this->m_auxid, e.index()),
82 *e.container(),
83 this->m_auxid,
84 this->m_linkedAuxid);
85}
86
87
88/**
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.
92 *
93 * This allows retrieving aux data by container / index.
94 *
95 * Will return an @c ElementLink proxy, which may be converted to
96 * or assigned from an @c ElementLink.
97 */
98template <class CONT, class ALLOC>
99inline
100auto
101Accessor<PackedLink<CONT>, ALLOC>::operator() (AuxVectorData& container,
102 size_t index) const -> ELProxy
103{
104 return ELProxy (container.template getData<PLink_t> (this->m_auxid, index),
105 container,
106 this->m_auxid,
107 this->m_linkedAuxid);
108}
109
110
111/**
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.
115 */
116template <class CONT, class ALLOC>
117inline
118void Accessor<PackedLink<CONT>, ALLOC>::set (AuxElement& e, const Link_t& l) const
119{
120 set (*e.container(), e.index(), l);
121}
122
123
124/**
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.
129 */
130template <class CONT, class ALLOC>
131void Accessor<PackedLink<CONT>, ALLOC>::set (AuxVectorData& container,
132 size_t index,
133 const Link_t& x) const
134{
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,
138 this->m_auxid,
139 this->m_linkedAuxid);
140 cnv.set (ll, x);
141}
142
143
144/**
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.
147 */
148template <class CONT, class ALLOC>
149inline
150auto
151Accessor<PackedLink<CONT>, ALLOC>::getPackedLinkArray (AuxVectorData& container) const
152 -> PLink_t*
153{
154 return reinterpret_cast<PLink_t*> (container.getDataArray (this->m_auxid));
155}
156
157
158/**
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.
161 */
162template <class CONT, class ALLOC>
163inline
164auto
165Accessor<PackedLink<CONT>, ALLOC>::getDataLinkArray (AuxVectorData& container) const
166 -> DLink_t*
167{
168 return reinterpret_cast<DLink_t*>
169 (container.getDataArray (this->m_linkedAuxid));
170}
171
172
173/**
174 * @brief Get a span over the array of @c PackedLinks.
175 * @param container The container from which to fetch the variable.
176 */
177template <class CONT, class ALLOC>
178inline
179auto
180Accessor<PackedLink<CONT>, ALLOC>::getPackedLinkSpan (AuxVectorData& container) const
181 -> PackedLink_span
182{
183 auto beg = reinterpret_cast<PLink_t*>(container.getDataArray (this->m_auxid));
184 return PackedLink_span (beg, container.size_v());
185}
186
187
188/**
189 * @brief Get a span over the array of @c DataLinks.
190 * @param container The container from which to fetch the variable.
191 */
192template <class CONT, class ALLOC>
193inline
194auto
195Accessor<PackedLink<CONT>, ALLOC>::getDataLinkSpan (AuxVectorData& container) const
196 -> DataLink_span
197{
198 const AuxDataSpanBase* sp = container.getDataSpan (this->m_linkedAuxid);
199 return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
200}
201
202
203
204/**
205 * @brief Get a span of @c ElementLink proxies.
206 * @param container The container from which to fetch the variable.
207 *
208 * The proxies may be converted to or assigned from @c ElementLink.
209 */
210template <class CONT, class ALLOC>
211inline
212auto
213Accessor<PackedLink<CONT>, ALLOC>::getDataSpan (AuxVectorData& container) const
214 -> span
215{
216 return span (getPackedLinkSpan(container),
217 detail::PackedLinkConverter<CONT> (container,
218 this->m_auxid,
219 this->m_linkedAuxid));
220}
221
222
223/**
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.
226 */
227template <class CONT, class ALLOC>
228inline
229bool
230Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxElement& e) const
231{
232 return e.container() &&
233 e.container()->isAvailableWritable (this->m_auxid) &&
234 e.container()->isAvailableWritable (this->m_linkedAuxid);
235}
236
237
238/**
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.
241 */
242template <class CONT, class ALLOC>
243inline
244bool
245Accessor<PackedLink<CONT>, ALLOC>::isAvailableWritable (AuxVectorData& c) const
246{
247 return c.isAvailableWritable (this->m_auxid) &&
248 c.isAvailableWritable (this->m_linkedAuxid);
249}
250
251
252//************************************************************************
253
254
255// To make the declarations a bit more readable.
256#define ACCESSOR Accessor<std::vector<PackedLink<CONT>, VALLOC>, ALLOC>
257
258
259/**
260 * @brief Constructor.
261 * @param name Name of this aux variable.
262 *
263 * The name -> auxid lookup is done here.
264 */
265template <class CONT, class ALLOC, class VALLOC>
266inline
267ACCESSOR::Accessor (const std::string& name)
268 : Base (name)
269{
270}
271
272
273/**
274 * @brief Constructor.
275 * @param name Name of this aux variable.
276 * @param clsname The name of its associated class. May be blank.
277 *
278 * The name -> auxid lookup is done here.
279 */
280template <class CONT, class ALLOC, class VALLOC>
281inline
282ACCESSOR::Accessor (const std::string& name,
283 const std::string& clsname)
284 : Base (name, clsname)
285{
286}
287
288
289/**
290 * @brief Constructor taking an auxid directly.
291 * @param auxid ID for this auxiliary variable.
292 *
293 * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
294 */
295template <class CONT, class ALLOC, class VALLOC>
296inline
297ACCESSOR::Accessor (const SG::auxid_t auxid)
298 : Base (auxid)
299{
300}
301
302
303/**
304 * @brief Fetch the variable for one element.
305 * @param e The element for which to fetch the variable.
306 *
307 * This will return a range of @c ElementLink proxies.
308 * These proxies may be converted to or assigned from @c ElementLink.
309 */
310template <class CONT, class ALLOC, class VALLOC>
311template <IsAuxElement ELT>
312auto
313ACCESSOR::operator() (ELT& e) const -> elt_span
314{
315 assert (e.container() != 0);
316 VElt_t* veltArr = getPackedLinkVectorArray(*e.container());
317 return elt_span (veltArr[e.index()], *e.container(),
318 this->m_auxid,
319 this->m_linkedAuxid);
320}
321
322
323/**
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.
327 *
328 * This allows retrieving aux data by container / index.
329 *
330 * This will return a range of @c ElementLink proxies.
331 * These proxies may be converted to or assigned from @c ElementLink.
332 */
333template <class CONT, class ALLOC, class VALLOC>
334auto
335ACCESSOR::operator() (AuxVectorData& container,
336 size_t index) const -> elt_span
337{
338 VElt_t* veltArr = getPackedLinkVectorArray(container);
339 return elt_span (veltArr[index], container,
340 this->m_auxid,
341 this->m_linkedAuxid);
342}
343
344
345/**
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.
349 */
350template <class CONT, class ALLOC, class VALLOC>
351template <detail::ElementLinkRange<CONT> RANGE>
352void ACCESSOR::set (AuxElement& e, const RANGE& r) const
353{
354 set (*e.container(), e.index(), r);
355}
356
357
358/**
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.
363 */
364template <class CONT, class ALLOC, class VALLOC>
365template <detail::ElementLinkRange<CONT> RANGE>
366void ACCESSOR::set (AuxVectorData& container,
367 size_t index,
368 const RANGE& r) const
369{
370 detail::PackedLinkConverter<CONT> cnv (container,
371 this->m_auxid,
372 this->m_linkedAuxid);
373 VElt_t& velt = container.template getData<VElt_t> (this->m_auxid, index);
374 cnv.set (velt, r);
375}
376
377
378/**
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.
381 */
382template <class CONT, class ALLOC, class VALLOC>
383inline
384auto
385ACCESSOR::getPackedLinkVectorArray (AuxVectorData& container) const
386 -> VElt_t*
387{
388 return reinterpret_cast<VElt_t*>
389 (container.getDataArray (this->m_auxid));
390}
391
392
393/**
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.
396 */
397template <class CONT, class ALLOC, class VALLOC>
398inline
399auto
400ACCESSOR::getDataLinkArray (AuxVectorData& container) const
401 -> DLink_t*
402{
403 return reinterpret_cast<DLink_t*>
404 (container.getDataArray (this->m_linkedAuxid));
405}
406
407
408/**
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.
411 */
412template <class CONT, class ALLOC, class VALLOC>
413inline
414auto
415ACCESSOR::getPackedLinkSpan (AuxElement& e) const
416 -> PackedLink_span
417{
418 auto elt = reinterpret_cast<VElt_t*>
419 (e.container()->getDataArray (this->m_auxid)) + e.index();
420 return PackedLink_span (elt->data(), elt->size());
421}
422
423
424/**
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.
428 */
429template <class CONT, class ALLOC, class VALLOC>
430inline
431auto
432ACCESSOR::getPackedLinkSpan (AuxVectorData& container,
433 size_t index) const
434 -> PackedLink_span
435{
436 auto elt = reinterpret_cast<VElt_t*>
437 (container.getDataArray (this->m_auxid)) + index;
438 return PackedLink_span (elt->data(), elt->size());
439}
440
441
442/**
443 * @brief Get a span over the vectors of @c PackedLinks.
444 * @param container The container from which to fetch the variable.
445 */
446template <class CONT, class ALLOC, class VALLOC>
447auto
448ACCESSOR::getPackedLinkVectorSpan (AuxVectorData& container) const
449 -> PackedLinkVector_span
450{
451 auto beg = reinterpret_cast<VElt_t*> (container.getDataArray (this->m_auxid));
452 return PackedLinkVector_span (beg, container.size_v());
453}
454
455/**
456 * @brief Get a span over the array of @c DataLinks.
457 * @param container The container from which to fetch the variable.
458 */
459template <class CONT, class ALLOC, class VALLOC>
460auto
461ACCESSOR::getDataLinkSpan (AuxVectorData& container) const
462 -> DataLink_span
463{
464 const AuxDataSpanBase* sp = container.getDataSpan (this->m_linkedAuxid);
465 return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
466}
467
468/**
469 * @brief Get a span over spans of @c ElementLink proxies.
470 * @param container The container from which to fetch the variable.
471 *
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.
475 */
476template <class CONT, class ALLOC, class VALLOC>
477inline
478auto
479ACCESSOR::getDataSpan (AuxVectorData& container) const
480 -> span
481{
482 return span (getPackedLinkVectorSpan(container),
483 ELSpanConverter (container, this->m_auxid, this->m_linkedAuxid));
484}
485
486
487/**
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.
490 */
491template <class CONT, class ALLOC, class VALLOC>
492inline
493bool
494ACCESSOR::isAvailableWritable (AuxElement& e) const
495{
496 return e.container() &&
497 e.container()->isAvailableWritable (this->m_auxid) &&
498 e.container()->isAvailableWritable (this->m_linkedAuxid);
499}
500
501
502/**
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.
505 */
506template <class CONT, class ALLOC, class VALLOC>
507inline
508bool
509ACCESSOR::isAvailableWritable (AuxVectorData& c) const
510{
511 return c.isAvailableWritable (this->m_auxid) &&
512 c.isAvailableWritable (this->m_linkedAuxid);
513}
514
515
516#undef ACCESSOR
517
518
519} // namespace SG