ATLAS Offline Software
JaggedVecDecorator.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/JaggedVecDecorator.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Apr, 2024
8  * @brief Helper class to provide type-safe access to aux data,
9  * specialized for @c JaggedVecElt.
10  */
11 
12 
13 #include "AthContainers/AuxElement.h"
14 #include "AthContainers/AuxTypeRegistry.h"
15 #include "AthContainers/exceptions.h"
16 
17 
18 namespace SG {
19 
20 
21 /**
22  * @brief Constructor.
23  * @param name Name of this aux variable.
24  *
25  * The name -> auxid lookup is done here.
26  */
27 template <class PAYLOAD_T, class ALLOC>
28 inline
29 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::Decorator (const std::string& name)
30  : Decorator (name, "", SG::AuxVarFlags::None)
31 {
32 }
33 
34 
35 /**
36  * @brief Constructor.
37  * @param name Name of this aux variable.
38  * @param clsname The name of its associated class. May be blank.
39  *
40  * The name -> auxid lookup is done here.
41  */
42 template <class PAYLOAD_T, class ALLOC>
43 inline
44 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::Decorator (const std::string& name,
45  const std::string& clsname)
46  : Decorator (name, clsname, SG::AuxVarFlags::None)
47 {
48 }
49 
50 
51 /**
52  * @brief Constructor taking an auxid directly.
53  * @param auxid ID for this auxiliary variable.
54  *
55  * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
56  */
57 template <class PAYLOAD_T, class ALLOC>
58 inline
59 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::Decorator (const SG::auxid_t auxid)
60 {
61  AuxTypeRegistry& r = AuxTypeRegistry::instance();
62  this->m_auxid = auxid;
63  r.checkAuxID<Elt_t, ALLOC> (this->m_auxid);
64  this->m_linkedAuxid = r.linkedVariable (this->m_auxid);
65  if (this->m_linkedAuxid == static_cast<uint32_t>(null_auxid)) {
66  throw SG::ExcNoLinkedVar (auxid, typeid (Payload_t));
67  // cppcheck-suppress missingReturn
68  }
69 }
70 
71 
72 /**
73  * @brief Constructor.
74  * @param name Name of this aux variable.
75  * @param clsname The name of its associated class. May be blank.
76  * @param flags Optional flags qualifying the type. See AuxTypeRegsitry.
77  *
78  * The name -> auxid lookup is done here.
79  */
80 template <class PAYLOAD_T, class ALLOC>
81 inline
82 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::Decorator
83  (const std::string& name,
84  const std::string& clsname,
85  const SG::AuxVarFlags flags)
86 {
87  AuxTypeRegistry& r = AuxTypeRegistry::instance();
88  this->m_linkedAuxid = r.getAuxID<Payload_t, PayloadAlloc_t> (AuxTypeRegistry::linkedName (name),
89  clsname,
90  flags | AuxVarFlags::Linked);
91  this->m_auxid = r.getAuxID<Elt_t, ALLOC> (name, clsname, flags, m_linkedAuxid);
92 }
93 
94 
95 /**
96  * @brief Fetch the variable for one element, as a non-const reference.
97  * @param e The element for which to fetch the variable.
98  *
99  * Will return a proxy object, which will allow treating this
100  * jagged vector element as a vector.
101  *
102  * If the container is locked, this will allow fetching only variables
103  * that do not yet exist (in which case they will be marked as decorations)
104  * or variables already marked as decorations.
105  */
106 template <class PAYLOAD_T, class ALLOC>
107 template <IsConstAuxElement ELT>
108 inline
109 auto
110 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::operator() (const ELT& e) const
111  -> reference_type
112 {
113  assert (e.container() != 0);
114  return (*this) (*e.container(), e.index());
115 }
116 
117 
118 /**
119  * @brief Fetch the variable for one element, as a non-const reference.
120  * @param container The container from which to fetch the variable.
121  * @param index The index of the desired element.
122  *
123  * This allows retrieving aux data by container / index.
124  *
125  * Will return a proxy object, which will allow treating this
126  * jagged vector element as a vector.
127  *
128  * If the container is locked, this will allow fetching only variables
129  * that do not yet exist (in which case they will be marked as decorations)
130  * or variables already marked as decorations.
131  */
132 template <class PAYLOAD_T, class ALLOC>
133 inline
134 auto
135 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::operator() (const AuxVectorData& container,
136  size_t index) const
137  -> reference_type
138 {
139  (void)this->getEltDecorArray (container); // const/locking checks
140  AuxVectorData& container_nc ATLAS_THREAD_SAFE =
141  const_cast<AuxVectorData&> (container);
142  return JVecProxy (index,
143  *container.getDataSpan (this->m_linkedAuxid),
144  *container.getDataSpan (this->m_auxid),
145  container_nc,
146  this->m_auxid);
147 }
148 
149 
150 /**
151  * @brief Set the variable for one element.
152  * @param e The element for which to fetch the variable.
153  * @param x The variable value to set.
154  */
155 template <class PAYLOAD_T, class ALLOC>
156 template <IsConstAuxElement ELT,
157  CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
158 inline
159 void Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::set (const ELT& e,
160  const RANGE& x) const
161 {
162  set (*e.container(), e.index(), x);
163 }
164 
165 
166 /**
167  * @brief Set the variable for one element.
168  * @param container The container from which to fetch the variable.
169  * @param index The index of the desired element.
170  * @param x The variable value to set.
171  */
172 template <class PAYLOAD_T, class ALLOC>
173 template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
174 inline
175 void Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::set (const AuxVectorData& container,
176  size_t index,
177  const RANGE& x) const
178 {
179  (*this) (container, index) = x;
180 }
181 
182 
183 /**
184  * @brief Get a pointer to the start of the array of @c JaggedVecElt objects.
185  * @param container The container from which to fetch the variable.
186  */
187 template <class PAYLOAD_T, class ALLOC>
188 inline
189 auto
190 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getEltArray (const AuxVectorData& container) const
191  -> const Elt_t*
192 {
193  return reinterpret_cast<const Elt_t*>
194  (container.getDataArray (m_auxid));
195 }
196 
197 
198 /**
199  * @brief Get a pointer to the start of the payload array.
200  * @param container The container from which to fetch the variable.
201  */
202 template <class PAYLOAD_T, class ALLOC>
203 inline
204 auto
205 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getPayloadArray (const AuxVectorData& container) const
206  -> const Payload_t*
207 {
208  return reinterpret_cast<const Payload_t*>
209  (container.getDataArray (m_linkedAuxid));
210 }
211 
212 
213 /**
214  * @brief Get a pointer to the start of the array of @c JaggedVecElt objects,
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 PAYLOAD_T, class ALLOC>
223 inline
224 auto
225 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getEltDecorArray (const AuxVectorData& container) const
226  -> Elt_t*
227 {
228  return reinterpret_cast<Elt_t*>
229  (container.getDecorationArray (m_auxid));
230 }
231 
232 
233 /**
234  * @brief Get a pointer to the start of the payload array,
235  * as a decoration.
236  * @param container The container from which to fetch the variable.
237  *
238  * If the container is locked, this will allow fetching only variables
239  * that do not yet exist (in which case they will be marked as decorations)
240  * or variables already marked as decorations.
241  */
242 template <class PAYLOAD_T, class ALLOC>
243 inline
244 auto
245 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getPayloadDecorArray (const AuxVectorData& container) const
246  -> Payload_t*
247 {
248  return reinterpret_cast<Payload_t*>
249  (container.getDecorationArray (m_linkedAuxid));
250 }
251 
252 
253 /**
254  * @brief Get a span over the array of @c JaggedVecElt objects.
255  * @param container The container from which to fetch the variable.
256  */
257 template <class PAYLOAD_T, class ALLOC>
258 inline
259 auto
260 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getEltSpan (const AuxVectorData& container) const
261  -> const_Elt_span
262 {
263  auto beg = reinterpret_cast<const Elt_t*>(container.getDataArray (m_auxid));
264  return const_Elt_span (beg, container.size_v());
265 }
266 
267 
268 /**
269  * @brief Get a span over the payload vector.
270  * @param container The container from which to fetch the variable.
271  */
272 template <class PAYLOAD_T, class ALLOC>
273 inline
274 auto
275 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getPayloadSpan (const AuxVectorData& container) const
276  -> const_Payload_span
277 {
278  const AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
279  return const_Payload_span (reinterpret_cast<const Payload_t*>(sp->beg),
280  sp->size);
281 }
282 
283 
284 /**
285  * @brief Get a span over spans representing the jagged vector.
286  * @param container The container from which to fetch the variable.
287  */
288 template <class PAYLOAD_T, class ALLOC>
289 inline
290 auto
291 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getDataSpan (const AuxVectorData& container) const
292  -> const_span
293 {
294  const_Elt_span elt_span = getEltSpan (container);
295  return const_span (elt_span,
296  ConstConverter_t (elt_span.data(),
297  *container.getDataSpan (m_linkedAuxid)));
298 }
299 
300 
301 /**
302  * @brief Get a span over the array of @c JaggedVecElt objects,
303  * as a decoration.
304  * @param container The container from which to fetch the variable.
305  *
306  * If the container is locked, this will allow fetching only variables
307  * that do not yet exist (in which case they will be marked as decorations)
308  * or variables already marked as decorations.
309  */
310 template <class PAYLOAD_T, class ALLOC>
311 inline
312 auto
313 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getEltDecorSpan (const AuxVectorData& container) const
314  -> Elt_span
315 {
316  auto beg = reinterpret_cast<Elt_t*>
317  (container.getDecorationArray (this->m_auxid));
318  return Elt_span (beg, container.size_v());
319 }
320 
321 
322 /**
323  * @brief Get a span over the payload vector,
324  * as a decoration.
325  * @param container The container from which to fetch the variable.
326  *
327  * If the container is locked, this will allow fetching only variables
328  * that do not yet exist (in which case they will be marked as decorations)
329  * or variables already marked as decorations.
330  */
331 template <class PAYLOAD_T, class ALLOC>
332 inline
333 auto
334 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getPayloadDecorSpan (const AuxVectorData& container) const
335  -> Payload_span
336 {
337  (void)container.getDecorationArray (this->m_linkedAuxid); // check for locking
338  const AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
339  return Payload_span (reinterpret_cast<Payload_t*>(sp->beg), sp->size);
340 }
341 
342 
343 /**
344  * @brief Get a span over spans representing the jagged vector,
345  * as a decoration.
346  * @param container The container from which to fetch the variable.
347  *
348  * If the container is locked, this will allow fetching only variables
349  * that do not yet exist (in which case they will be marked as decorations)
350  * or variables already marked as decorations.
351  */
352 template <class PAYLOAD_T, class ALLOC>
353 inline
354 auto
355 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getDecorationSpan (const AuxVectorData& container) const
356  -> span
357 {
358  Elt_span elt_span = getEltDecorSpan(container);
359  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&> (container);
360  return span (elt_span,
361  Converter_t (container_nc, this->auxid(), this->linkedAuxid()));
362 }
363 
364 
365 /**
366  * @brief Test to see if this variable exists in the store and is writable.
367  * @param e An element of the container om which to test the variable.
368  */
369 template <class PAYLOAD_T, class ALLOC>
370 template <IsConstAuxElement ELT>
371 inline
372 bool
373 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::isAvailableWritable (const ELT& e) const
374 {
375  return e.container() &&
376  e.container()->isAvailableWritableAsDecoration (m_auxid) &&
377  e.container()->isAvailableWritableAsDecoration (m_linkedAuxid);
378 }
379 
380 
381 /**
382  * @brief Test to see if this variable exists in the store and is writable.
383  * @param c The container in which to test the variable.
384  */
385 template <class PAYLOAD_T, class ALLOC>
386 inline
387 bool
388 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::isAvailableWritable (const AuxVectorData& c) const
389 {
390  return c.isAvailableWritableAsDecoration (m_auxid) &&
391  c.isAvailableWritableAsDecoration (m_linkedAuxid);
392 }
393 
394 
395 } // namespace SG