ATLAS Offline Software
PackedLinkDecorator.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 PackedLinkDecorator.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Nov, 2023
8  * @brief Helper class to provide type-safe access to aux data,
9  * specialized for @c PackedLink.
10  */
11 
12 #include "AthContainers/AuxElement.h"
13 #include "AthContainers/AuxTypeRegistry.h"
14 #include "AthContainers/exceptions.h"
15 
16 
17 namespace SG {
18 
19 
20 /**
21  * @brief Constructor.
22  * @param name Name of this aux variable.
23  *
24  * The name -> auxid lookup is done here.
25  */
26 template <class CONT, class ALLOC>
27 inline
28 Decorator<PackedLink<CONT>, ALLOC>::Decorator (const std::string& name)
29  : Decorator (name, "", SG::AuxVarFlags::None)
30 {
31 }
32 
33 
34 /**
35  * @brief Constructor.
36  * @param name Name of this aux variable.
37  * @param clsname The name of its associated class. May be blank.
38  *
39  * The name -> auxid lookup is done here.
40  */
41 template <class CONT, class ALLOC>
42 inline
43 Decorator<PackedLink<CONT>, ALLOC>::Decorator (const std::string& name,
44  const std::string& clsname)
45  : Decorator (name, clsname, SG::AuxVarFlags::None)
46 {
47 }
48 
49 
50 /**
51  * @brief Constructor taking an auxid directly.
52  * @param auxid ID for this auxiliary variable.
53  *
54  * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
55  */
56 template <class CONT, class ALLOC>
57 inline
58 Decorator<PackedLink<CONT>, ALLOC>::Decorator (const SG::auxid_t auxid)
59 {
60  AuxTypeRegistry& r = AuxTypeRegistry::instance();
61  m_auxid = auxid;
62  r.checkAuxID<PLink_t, ALLOC> (m_auxid);
63  m_linkedAuxid = r.linkedVariable (m_auxid);
64  if (m_linkedAuxid == static_cast<uint32_t>(null_auxid)) {
65  throw SG::ExcNoLinkedVar (auxid, typeid (CONT));
66  // cppcheck-suppress missingReturn; false positive
67  }
68 }
69 
70 
71 /**
72  * @brief Constructor.
73  * @param name Name of this aux variable.
74  * @param clsname The name of its associated class. May be blank.
75  * @param flags Optional flags qualifying the type. See AuxTypeRegsitry.
76  *
77  * The name -> auxid lookup is done here.
78  */
79 template <class CONT, class ALLOC>
80 inline
81 Decorator<PackedLink<CONT>, ALLOC>::Decorator
82  (const std::string& name,
83  const std::string& clsname,
84  const SG::AuxVarFlags flags)
85 {
86  AuxTypeRegistry& r = AuxTypeRegistry::instance();
87  m_linkedAuxid = r.getAuxID<DLink_t, DLinkAlloc_t> (AuxTypeRegistry::linkedName (name),
88  clsname,
89  flags | AuxVarFlags::Linked);
90  m_auxid = r.getAuxID<PLink_t, ALLOC> (name, clsname, flags, m_linkedAuxid);
91 }
92 
93 
94 /**
95  * @brief Fetch the variable for one element.
96  * @param e The element for which to fetch the variable.
97  *
98  * Will return an @c ElementLink proxy, which may be converted to
99  * or assigned from an @c ElementLink.
100  *
101  * If the container is locked, this will allow fetching only variables
102  * that do not yet exist (in which case they will be marked as decorations)
103  * or variables already marked as decorations.
104  */
105 template <class CONT, class ALLOC>
106 template <IsConstAuxElement ELT>
107 inline
108 auto
109 Decorator<PackedLink<CONT>, ALLOC>::operator() (const ELT& e) const -> ELProxy
110 {
111  assert (e.container() != 0);
112  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&> (*e.container());
113  return ELProxy (e.container()->template getDecoration<PLink_t> (this->m_auxid, e.index()),
114  container_nc,
115  this->m_auxid,
116  this->m_linkedAuxid);
117 }
118 
119 
120 /**
121  * @brief Fetch the variable for one element.
122  * @param container The container from which to fetch the variable.
123  * @param index The index of the desired element.
124  *
125  * This allows retrieving aux data by container / index.
126  *
127  * Will return an @c ElementLink proxy, which may be converted to
128  * or assigned from an @c ElementLink.
129  *
130  * If the container is locked, this will allow fetching only variables
131  * that do not yet exist (in which case they will be marked as decorations)
132  * or variables already marked as decorations.
133  */
134 template <class CONT, class ALLOC>
135 inline
136 auto
137 Decorator<PackedLink<CONT>, ALLOC>::operator() (const AuxVectorData& container,
138  size_t index) const
139  -> ELProxy
140 {
141  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&> (container);
142  return ELProxy (container.template getDecoration<PLink_t> (this->m_auxid, index),
143  container_nc, this->m_auxid, this->m_linkedAuxid);
144 }
145 
146 
147 /**
148  * @brief Set the variable for one element.
149  * @param e The element for which to set the variable.
150  * @param l The @c ElementLink to set.
151  */
152 template <class CONT, class ALLOC>
153 template <IsConstAuxElement ELT>
154 inline
155 void Decorator<PackedLink<CONT>, ALLOC>::set (const ELT& e,
156  const Link_t& l) const
157 {
158  set (*e.container(), e.index(), l);
159 }
160 
161 
162 /**
163  * @brief Set the variable for one element.
164  * @param container The container for which to set the variable.
165  * @param index The index of the desired element.
166  * @param l The @c ElementLink to set.
167  */
168 template <class CONT, class ALLOC>
169 inline
170 void Decorator<PackedLink<CONT>, ALLOC>::set (const AuxVectorData& container,
171  size_t index,
172  const Link_t& l) const
173 {
174  // Have to do this before creating the converter.
175  PLink_t& ll = container.template getDecoration<PLink_t> (this->m_auxid, index);
176  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&> (container);
177  detail::PackedLinkConverter<CONT> cnv (container_nc,
178  this->m_auxid,
179  this->m_linkedAuxid);
180  cnv.set (ll, l);
181 }
182 
183 
184 /**
185  * @brief Get a pointer to the start of the array of @c PackedLinks.
186  * @param container The container from which to fetch the variable.
187  */
188 template <class CONT, class ALLOC>
189 inline
190 auto
191 Decorator<PackedLink<CONT>, ALLOC>::getPackedLinkArray (const AuxVectorData& container) const
192  -> const PLink_t*
193 {
194  return reinterpret_cast<const PLink_t*> (container.getDataArray (m_auxid));
195 }
196 
197 
198 /**
199  * @brief Get a pointer to the start of the linked array of @c DataLinks.
200  * @param container The container from which to fetch the variable.
201  */
202 template <class CONT, class ALLOC>
203 inline
204 auto
205 Decorator<PackedLink<CONT>, ALLOC>::getDataLinkArray (const AuxVectorData& container) const
206  -> const DLink_t*
207 {
208  return reinterpret_cast<const DLink_t*>
209  (container.getDataArray (m_linkedAuxid));
210 }
211 
212 
213 /**
214  * @brief Get a pointer to the start of the array of @c PackedLinks,
215  * as a decoration.
216  * @param container The container from which to fetch the variable.
217  *
218  * If the container is locked, this will allow fetching only variables
219  * that do not yet exist (in which case they will be marked as decorations)
220  * or variables already marked as decorations.
221  */
222 template <class CONT, class ALLOC>
223 inline
224 auto
225 Decorator<PackedLink<CONT>, ALLOC>::getPackedLinkDecorArray (const AuxVectorData& container) const
226  -> PLink_t*
227 {
228  return reinterpret_cast<PLink_t*> (container.getDecorationArray (m_auxid));
229 }
230 
231 
232 /**
233  * @brief Get a pointer to the start of the linked array of @c DataLinks,
234  * as a decoration.
235  * @param container The container from which to fetch the variable.
236  *
237  * If the container is locked, this will allow fetching only variables
238  * that do not yet exist (in which case they will be marked as decorations)
239  * or variables already marked as decorations.
240  */
241 template <class CONT, class ALLOC>
242 inline
243 auto
244 Decorator<PackedLink<CONT>, ALLOC>::getDataLinkDecorArray (const AuxVectorData& container) const
245  -> DLink_t*
246 {
247  return reinterpret_cast<DLink_t*> (container.getDecorationArray (m_linkedAuxid));
248 }
249 
250 
251 /**
252  * @brief Get a span over the array of @c PackedLinks.
253  * @param container The container from which to fetch the variable.
254  */
255 template <class CONT, class ALLOC>
256 inline
257 auto
258 Decorator<PackedLink<CONT>, ALLOC>::getPackedLinkSpan (const AuxVectorData& container) const
259  -> const_PackedLink_span
260 {
261  auto beg = reinterpret_cast<const PLink_t*>(container.getDataArray (m_auxid));
262  return const_PackedLink_span (beg, container.size_v());
263 }
264 
265 
266 /**
267  * @brief Get a span over the array of @c DataLinks.
268  * @param container The container from which to fetch the variable.
269  */
270 template <class CONT, class ALLOC>
271 inline
272 auto
273 Decorator<PackedLink<CONT>, ALLOC>::getDataLinkSpan (const AuxVectorData& container) const
274  -> const_DataLink_span
275 {
276  const AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
277  return const_DataLink_span (reinterpret_cast<const DLink_t*>(sp->beg),
278  sp->size);
279 }
280 
281 
282 /**
283  * @brief Get a span of @c ElementLinks.
284  * @param container The container from which to fetch the variable.
285  */
286 template <class CONT, class ALLOC>
287 inline
288 auto
289 Decorator<PackedLink<CONT>, ALLOC>::getDataSpan (const AuxVectorData& container) const
290  -> const_span
291 {
292  return const_span (getPackedLinkSpan(container),
293  ConstConverter_t (*container.getDataSpan (m_linkedAuxid)));
294 }
295 
296 
297 /**
298  * @brief Get a span over the array of @c PackedLinks, as a decoration.
299  * @param container The container from which to fetch the variable.
300  *
301  * If the container is locked, this will allow fetching only variables
302  * that do not yet exist (in which case they will be marked as decorations)
303  * or variables already marked as decorations.
304  */
305 template <class CONT, class ALLOC>
306 inline
307 auto
308 Decorator<PackedLink<CONT>, ALLOC>::getPackedLinkDecorSpan (const AuxVectorData& container) const
309  -> PackedLink_span
310 {
311  auto beg = reinterpret_cast<PLink_t*>
312  (container.getDecorationArray (this->m_auxid));
313  return PackedLink_span (beg, container.size_v());
314 }
315 
316 
317 /**
318  * @brief Get a span over the array of @c DataLinks, as a decoration.
319  * @param container The container from which to fetch the variable.
320  *
321  * If the container is locked, this will allow fetching only variables
322  * that do not yet exist (in which case they will be marked as decorations)
323  * or variables already marked as decorations.
324  */
325 template <class CONT, class ALLOC>
326 inline
327 auto
328 Decorator<PackedLink<CONT>, ALLOC>::getDataLinkDecorSpan (const AuxVectorData& container) const
329  -> DataLink_span
330 {
331  (void)container.getDecorationArray (this->m_linkedAuxid); // check for locking
332  const AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
333  return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
334 }
335 
336 
337 /**
338  * @brief Get a span of @c ElementLink proxies, as a decoration.
339  * @param container The container from which to fetch the variable.
340  *
341  * The proxies may be converted to or assigned from @c ElementLink.
342  *
343  * If the container is locked, this will allow fetching only variables
344  * that do not yet exist (in which case they will be marked as decorations)
345  * or variables already marked as decorations.
346  */
347 template <class CONT, class ALLOC>
348 inline
349 auto
350 Decorator<PackedLink<CONT>, ALLOC>::getDecorationSpan (const AuxVectorData& container) const
351  -> span
352 {
353  PackedLink_span pspan = getPackedLinkDecorSpan(container);
354  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&> (container);
355  return span (pspan,
356  detail::PackedLinkConverter<CONT> (container_nc,
357  this->m_auxid,
358  this->m_linkedAuxid));
359 }
360 
361 
362 /**
363  * @brief Test to see if this variable exists in the store and is writable.
364  * @param e An element of the container in which to test the variable.
365  */
366 template <class CONT, class ALLOC>
367 template <IsConstAuxElement ELT>
368 inline
369 bool
370 Decorator<PackedLink<CONT>, ALLOC>::isAvailableWritable (const ELT& e) const
371 {
372  return e.container() &&
373  e.container()->isAvailableWritableAsDecoration (m_auxid) &&
374  e.container()->isAvailableWritableAsDecoration (m_linkedAuxid);
375 }
376 
377 
378 /**
379  * @brief Test to see if this variable exists in the store and is writable.
380  * @param c The container in which to test the variable.
381  */
382 template <class CONT, class ALLOC>
383 inline
384 bool
385 Decorator<PackedLink<CONT>, ALLOC>::isAvailableWritable (const AuxVectorData& c) const
386 {
387  return c.isAvailableWritableAsDecoration (m_auxid) &&
388  c.isAvailableWritableAsDecoration (m_linkedAuxid);
389 }
390 
391 
392 //************************************************************************
393 
394 
395 // To make the declarations a bit more readable.
396 #define DECORATOR Decorator<std::vector<PackedLink<CONT>, VALLOC>, ALLOC>
397 
398 
399 /**
400  * @brief Constructor.
401  * @param name Name of this aux variable.
402  *
403  * The name -> auxid lookup is done here.
404  */
405 template <class CONT, class ALLOC, class VALLOC>
406 inline
407 DECORATOR::Decorator (const std::string& name)
408  : Decorator (name, "", SG::AuxVarFlags::None)
409 {
410 }
411 
412 
413 /**
414  * @brief Constructor.
415  * @param name Name of this aux variable.
416  * @param clsname The name of its associated class. May be blank.
417  *
418  * The name -> auxid lookup is done here.
419  */
420 template <class CONT, class ALLOC, class VALLOC>
421 inline
422 DECORATOR::Decorator (const std::string& name,
423  const std::string& clsname)
424  : Decorator (name, clsname, SG::AuxVarFlags::None)
425 {
426 }
427 
428 
429 /**
430  * @brief Constructor taking an auxid directly.
431  * @param auxid ID for this auxiliary variable.
432  *
433  * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
434  */
435 template <class CONT, class ALLOC, class VALLOC>
436 inline
437 DECORATOR::Decorator (const SG::auxid_t auxid)
438 {
439  AuxTypeRegistry& r = AuxTypeRegistry::instance();
440  m_auxid = auxid;
441  r.checkAuxID<VElt_t, ALLOC> (m_auxid);
442  m_linkedAuxid = r.linkedVariable (m_auxid);
443  if (m_linkedAuxid == static_cast<uint32_t>(null_auxid)) {
444  throw SG::ExcNoLinkedVar (auxid, typeid (CONT));
445  }
446 }
447 /**
448  * @brief Constructor.
449  * @param name Name of this aux variable.
450  * @param clsname The name of its associated class. May be blank.
451  * @param flags Optional flags qualifying the type. See AuxTypeRegsitry.
452  *
453  * The name -> auxid lookup is done here.
454  */
455 template <class CONT, class ALLOC, class VALLOC>
456 inline
457 DECORATOR::Decorator (const std::string& name,
458  const std::string& clsname,
459  const SG::AuxVarFlags flags)
460 {
461  AuxTypeRegistry& r = AuxTypeRegistry::instance();
462  m_linkedAuxid = r.getAuxID<DLink_t, DLinkAlloc_t> (AuxTypeRegistry::linkedName (name),
463  clsname,
464  flags | AuxVarFlags::Linked);
465  m_auxid = r.getAuxID<VElt_t, ALLOC> (name, clsname, flags, m_linkedAuxid);
466 }
467 
468 
469 /**
470  * @brief Fetch the variable for one element.
471  * @param e The element for which to fetch the variable.
472  *
473  * This will return a range of @c ElementLink proxies.
474  * These proxies may be converted to or assigned from @c ElementLink.
475  *
476  * If the container is locked, this will allow fetching only variables
477  * that do not yet exist (in which case they will be marked as decorations)
478  * or variables already marked as decorations.
479  */
480 template <class CONT, class ALLOC, class VALLOC>
481 template <IsConstAuxElement ELT>
482 auto
483 DECORATOR::operator() (const ELT& e) const
484  -> elt_span
485 {
486  assert (e.container() != 0);
487  // This has be to called before making the ELSpanProxyHelper.
488  VElt_t* veltArr = getPackedLinkVectorDecorArray(*e.container());
489  AuxVectorData& container_nc ATLAS_THREAD_SAFE = *const_cast<AuxVectorData*>(e.container());
490  return elt_span (veltArr[e.index()], container_nc,
491  this->m_auxid,
492  this->m_linkedAuxid);
493 }
494 
495 
496 /**
497  * @brief Fetch the variable for one element.
498  * @param container The container from which to fetch the variable.
499  * @param index The index of the desired element.
500  *
501  * This allows retrieving aux data by container / index.
502  *
503  * This will return a range of @c ElementLink proxies.
504  * These proxies may be converted to or assigned from @c ElementLink.
505  *
506  * If the container is locked, this will allow fetching only variables
507  * that do not yet exist (in which case they will be marked as decorations)
508  * or variables already marked as decorations.
509  */
510 template <class CONT, class ALLOC, class VALLOC>
511 auto
512 DECORATOR::operator() (const AuxVectorData& container,
513  size_t index) const
514  -> elt_span
515 {
516  // This has be to called before making the ELSpanProxyHelper.
517  VElt_t* veltArr = getPackedLinkVectorDecorArray(container);
518  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&>(container);
519  return elt_span (veltArr[index], container_nc,
520  this->m_auxid,
521  this->m_linkedAuxid);
522 }
523 
524 
525 /**
526  * @brief Set the variable for one element.
527  * @param e The element for which to set the variable.
528  * @param r The variable value to set, as a range over @c ElementLink.
529  */
530 template <class CONT, class ALLOC, class VALLOC>
531 template <IsConstAuxElement ELT, detail::ElementLinkRange<CONT> RANGE>
532 void DECORATOR::set (const ELT& e, const RANGE& r) const
533 {
534  set (*e.container(), e.index(), r);
535 }
536 
537 
538 /**
539  * @brief Set the variable for one element.
540  * @param container The container from which to fetch the variable.
541  * @param index The index of the desired element.
542  * @param r The variable value to set, as a range over @c ElementLink.
543  */
544 template <class CONT, class ALLOC, class VALLOC>
545 template <detail::ElementLinkRange<CONT> RANGE>
546 void DECORATOR::set (const AuxVectorData& container,
547  size_t index,
548  const RANGE& r) const
549 {
550  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&> (container);
551  detail::PackedLinkConverter<CONT> cnv (container_nc,
552  this->m_auxid,
553  this->m_linkedAuxid);
554  VElt_t& velt = container.template getDecoration<VElt_t> (this->m_auxid, index);
555  cnv.set (velt, r);
556 }
557 
558 
559 /**
560  * @brief Get a pointer to the start of the array of vectors of @c PackedLinks.
561  * @param container The container from which to fetch the variable.
562  */
563 template <class CONT, class ALLOC, class VALLOC>
564 inline
565 auto
566 DECORATOR::getPackedLinkVectorArray (const AuxVectorData& container) const
567  -> const VElt_t*
568 {
569  return reinterpret_cast<const VElt_t*>
570  (container.getDataArray (m_auxid));
571 }
572 
573 
574 /**
575  * @brief Get a pointer to the start of the linked array of @c DataLinks.
576  * @param container The container from which to fetch the variable.
577  */
578 template <class CONT, class ALLOC, class VALLOC>
579 inline
580 auto
581 DECORATOR::getDataLinkArray (const AuxVectorData& container) const
582  -> const DLink_t*
583 {
584  return reinterpret_cast<const DLink_t*>
585  (container.getDataArray (m_linkedAuxid));
586 }
587 
588 
589 /**
590  * @brief Get a pointer to the start of the array of vectors of @c PackedLinks,
591  * as a decoration.
592  * @param container The container from which to fetch the variable.
593  */
594 template <class CONT, class ALLOC, class VALLOC>
595 inline
596 auto
597 DECORATOR::getPackedLinkVectorDecorArray (const AuxVectorData& container) const
598  -> VElt_t*
599 {
600  return reinterpret_cast<VElt_t*> (container.getDecorationArray (m_auxid));
601 }
602 
603 
604 /**
605  * @brief Get a pointer to the start of the linked array of @c DataLinks,
606  * as a decoration.
607  * @param container The container from which to fetch the variable.
608  */
609 template <class CONT, class ALLOC, class VALLOC>
610 inline
611 auto
612 DECORATOR::getDataLinkDecorArray (const AuxVectorData& container) const
613  -> DLink_t*
614 {
615  return reinterpret_cast<DLink_t*> (container.getDecorationArray (m_linkedAuxid));
616 }
617 
618 
619 /**
620  * @brief Get a span over the vector of @c PackedLinks for a given element.
621  * @param e The element for which to fetch the variable.
622  */
623 template <class CONT, class ALLOC, class VALLOC>
624 template <IsConstAuxElement ELT>
625 inline
626 auto
627 DECORATOR::getPackedLinkSpan (const ELT& e) const
628  -> const_PackedLink_span
629 {
630  auto elt = reinterpret_cast<const VElt_t*>
631  (e.container()->getDataArray (this->m_auxid)) + e.index();
632  return const_PackedLink_span (elt->data(), elt->size());
633 }
634 
635 
636 /**
637  * @brief Get a span over the vector of @c PackedLinks for a given element.
638  * @param container The container from which to fetch the variable.
639  * @param index The index of the desired element.
640  */
641 template <class CONT, class ALLOC, class VALLOC>
642 inline
643 auto
644 DECORATOR::getPackedLinkSpan (const AuxVectorData& container, size_t index) const
645  -> const_PackedLink_span
646 {
647  auto elt = reinterpret_cast<const VElt_t*>
648  (container.getDataArray (this->m_auxid)) + index;
649  return const_PackedLink_span (elt->data(), elt->size());
650 }
651 
652 
653 /**
654  * @brief Get a span over the vector of @c PackedLinks for a given element.
655  * @param container The container from which to fetch the variable.
656  * @param index The index of the desired element.
657  */
658 template <class CONT, class ALLOC, class VALLOC>
659 inline
660 auto
661 DECORATOR::getPackedLinkSpan (AuxVectorData& container, size_t index) const
662  -> PackedLink_span
663 {
664  auto elt = reinterpret_cast<VElt_t*>
665  (container.getDataArray (this->m_auxid)) + index;
666  return PackedLink_span (elt->data(), elt->size());
667 }
668 
669 
670 /**
671  * @brief Get a span over the vectors of @c PackedLinks.
672  * @param container The container from which to fetch the variable.
673  */
674 template <class CONT, class ALLOC, class VALLOC>
675 inline
676 auto
677 DECORATOR::getPackedLinkVectorSpan (const AuxVectorData& container) const
678  -> const_PackedLinkVector_span
679 {
680  auto beg = reinterpret_cast<const VElt_t*>
681  (container.getDataArray (m_auxid));
682  return const_PackedLinkVector_span (beg, container.size_v());
683 }
684 
685 
686 /**
687  * @brief Get a span over the array of @c DataLinks.
688  * @param container The container from which to fetch the variable.
689  */
690 template <class CONT, class ALLOC, class VALLOC>
691 inline
692 auto
693 DECORATOR::getDataLinkSpan (const AuxVectorData& container) const
694  -> const_DataLink_span
695 {
696  const AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
697  return const_DataLink_span (reinterpret_cast<const DLink_t*>(sp->beg),
698  sp->size);
699 }
700 
701 
702 /**
703  * @brief Get a span over spans of @c ElementLinks.
704  * @param container The container from which to fetch the variable.
705  */
706 template <class CONT, class ALLOC, class VALLOC>
707 inline
708 auto
709 DECORATOR::getDataSpan (const AuxVectorData& container) const
710  -> const_span
711 {
712  const_PackedLinkVector_span pvspan = getPackedLinkVectorSpan(container);
713  return const_span (pvspan,
714  ConstVectorTransform_t (*container.getDataSpan (m_linkedAuxid)));
715 }
716 
717 
718 /**
719  * @brief Get a span over the vector of @c PackedLinks for a given element,
720  * as a decoration.
721  * @param e The element for which to fetch the variable.
722  *
723  * If the container is locked, this will allow fetching only variables
724  * that do not yet exist (in which case they will be marked as decorations)
725  * or variables already marked as decorations.
726  */
727 template <class CONT, class ALLOC, class VALLOC>
728 template <IsConstAuxElement ELT>
729 inline
730 auto
731 DECORATOR::getPackedLinkDecorSpan (const ELT& e) const
732  -> PackedLink_span
733 {
734  auto elt = reinterpret_cast<VElt_t*>
735  (e.container()->getDecorationArray (this->m_auxid)) + e.index();
736  return PackedLink_span (elt->data(), elt->size());
737 }
738 
739 
740 /**
741  * @brief Get a span over the vector of @c PackedLinks for a given element,
742  * as a decoration.
743  * @param container The container from which to fetch the variable.
744  * @param index The index of the desired element.
745  *
746  * If the container is locked, this will allow fetching only variables
747  * that do not yet exist (in which case they will be marked as decorations)
748  * or variables already marked as decorations.
749  */
750 template <class CONT, class ALLOC, class VALLOC>
751 inline
752 auto
753 DECORATOR::getPackedLinkDecorSpan (const AuxVectorData& container, size_t index) const
754  -> PackedLink_span
755 {
756  auto elt = reinterpret_cast<VElt_t*>
757  (container.getDecorationArray (this->m_auxid)) + index;
758  return PackedLink_span (elt->data(), elt->size());
759 }
760 
761 
762 /**
763  * @brief Get a span over the vectors of @c PackedLinks,
764  * as a decoration.
765  * @param container The container from which to fetch the variable.
766  *
767  * If the container is locked, this will allow fetching only variables
768  * that do not yet exist (in which case they will be marked as decorations)
769  * or variables already marked as decorations.
770  */
771 template <class CONT, class ALLOC, class VALLOC>
772 inline
773 auto
774 DECORATOR::getPackedLinkVectorDecorSpan (const AuxVectorData& container) const
775  -> PackedLinkVector_span
776 {
777  auto beg = reinterpret_cast<VElt_t*>
778  (container.getDecorationArray (m_auxid));
779  return PackedLinkVector_span (beg, container.size_v());
780 }
781 
782 
783 /**
784  * @brief Get a span over the array of @c DataLinks, as a decoration.
785  * @param container The container from which to fetch the variable.
786  *
787  * If the container is locked, this will allow fetching only variables
788  * that do not yet exist (in which case they will be marked as decorations)
789  * or variables already marked as decorations.
790  */
791 template <class CONT, class ALLOC, class VALLOC>
792 inline
793 auto
794 DECORATOR::getDataLinkDecorSpan (const AuxVectorData& container) const
795  -> DataLink_span
796 {
797  (void)container.getDecorationArray (this->m_linkedAuxid); // check for locking
798  const AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
799  return DataLink_span (reinterpret_cast<DLink_t*>(sp->beg), sp->size);
800 }
801 
802 
803 /**
804  * @brief Get a span over spans of @c ElementLink proxies,
805  * as a decoration.
806  * @param container The container from which to fetch the variable.
807  *
808  * The individual proxies may be converted to or assigned from @c ElementLink.
809  * Each element may also be assigned from a range of @c ElementLink,
810  * or converted to a vector of @c ElementLink.
811  *
812  * If the container is locked, this will allow fetching only variables
813  * that do not yet exist (in which case they will be marked as decorations)
814  * or variables already marked as decorations.
815  */
816 template <class CONT, class ALLOC, class VALLOC>
817 inline
818 auto
819 DECORATOR::getDecorationSpan (const AuxVectorData& container) const
820  -> span
821 {
822  PackedLinkVector_span pvspan = getPackedLinkVectorDecorSpan(container);
823  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&> (container);
824  return span (pvspan,
825  ELSpanConverter (container_nc,
826  this->m_auxid,
827  this->m_linkedAuxid));
828 }
829 
830 
831 /**
832  * @brief Test to see if this variable exists in the store and is writable.
833  * @param e An element of the container in which to test the variable.
834  */
835 template <class CONT, class ALLOC, class VALLOC>
836 template <IsConstAuxElement ELT>
837 inline
838 bool
839 DECORATOR::isAvailableWritable (const ELT& e) const
840 {
841  return e.container() &&
842  e.container()->isAvailableWritableAsDecoration (m_auxid) &&
843  e.container()->isAvailableWritableAsDecoration (m_linkedAuxid);
844 }
845 
846 
847 /**
848  * @brief Test to see if this variable exists in the store and is writable.
849  * @param c The container in which to test the variable.
850  */
851 template <class CONT, class ALLOC, class VALLOC>
852 inline
853 bool
854 DECORATOR::isAvailableWritable (const AuxVectorData& c) const
855 {
856  return c.isAvailableWritableAsDecoration (m_auxid) &&
857  c.isAvailableWritableAsDecoration (m_linkedAuxid);
858 }
859 
860 
861 #undef DECORATOR
862 
863 
864 } // namespace SG