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 #ifndef __CPPCHECK__ // cppcheck gets parse errors on this
133 template <class PAYLOAD_T, class ALLOC>
134 inline
135 auto
136 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::operator() (const AuxVectorData& container,
137  size_t index) const
138  -> reference_type
139 {
140  (void)this->getEltDecorArray (container); // const/locking checks
141  AuxVectorData& container_nc ATLAS_THREAD_SAFE =
142  const_cast<AuxVectorData&> (container);
143  return JVecProxy (index,
144  *container.getDataSpan (this->m_linkedAuxid),
145  *container.getDataSpan (this->m_auxid),
146  container_nc,
147  this->m_auxid);
148 }
149 #endif // not __CPPCHECK__
150 
151 
152 /**
153  * @brief Set the variable for one element.
154  * @param e The element for which to fetch the variable.
155  * @param x The variable value to set.
156  */
157 template <class PAYLOAD_T, class ALLOC>
158 template <IsConstAuxElement ELT,
159  CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
160 inline
161 void Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::set (const ELT& e,
162  const RANGE& x) const
163 {
164  set (*e.container(), e.index(), x);
165 }
166 
167 
168 /**
169  * @brief Set the variable for one element.
170  * @param container The container from which to fetch the variable.
171  * @param index The index of the desired element.
172  * @param x The variable value to set.
173  */
174 template <class PAYLOAD_T, class ALLOC>
175 template <CxxUtils::InputRangeOverT<PAYLOAD_T> RANGE>
176 inline
177 void Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::set (const AuxVectorData& container,
178  size_t index,
179  const RANGE& x) const
180 {
181  (*this) (container, index) = x;
182 }
183 
184 
185 /**
186  * @brief Get a pointer to the start of the array of @c JaggedVecElt objects.
187  * @param container The container from which to fetch the variable.
188  */
189 template <class PAYLOAD_T, class ALLOC>
190 inline
191 auto
192 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getEltArray (const AuxVectorData& container) const
193  -> const Elt_t*
194 {
195  return reinterpret_cast<const Elt_t*>
196  (container.getDataArray (m_auxid));
197 }
198 
199 
200 /**
201  * @brief Get a pointer to the start of the payload array.
202  * @param container The container from which to fetch the variable.
203  */
204 template <class PAYLOAD_T, class ALLOC>
205 inline
206 auto
207 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getPayloadArray (const AuxVectorData& container) const
208  -> const Payload_t*
209 {
210  return reinterpret_cast<const Payload_t*>
211  (container.getDataArray (m_linkedAuxid));
212 }
213 
214 
215 /**
216  * @brief Get a pointer to the start of the array of @c JaggedVecElt objects,
217  * as a decoration.
218  * @param container The container from which to fetch the variable.
219  *
220  * If the container is locked, this will allow fetching only variables
221  * that do not yet exist (in which case they will be marked as decorations)
222  * or variables already marked as decorations.
223  */
224 template <class PAYLOAD_T, class ALLOC>
225 inline
226 auto
227 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getEltDecorArray (const AuxVectorData& container) const
228  -> Elt_t*
229 {
230  return reinterpret_cast<Elt_t*>
231  (container.getDecorationArray (m_auxid));
232 }
233 
234 
235 /**
236  * @brief Get a pointer to the start of the payload array,
237  * as a decoration.
238  * @param container The container from which to fetch the variable.
239  *
240  * If the container is locked, this will allow fetching only variables
241  * that do not yet exist (in which case they will be marked as decorations)
242  * or variables already marked as decorations.
243  */
244 template <class PAYLOAD_T, class ALLOC>
245 inline
246 auto
247 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getPayloadDecorArray (const AuxVectorData& container) const
248  -> Payload_t*
249 {
250  return reinterpret_cast<Payload_t*>
251  (container.getDecorationArray (m_linkedAuxid));
252 }
253 
254 
255 /**
256  * @brief Get a span over the array of @c JaggedVecElt objects.
257  * @param container The container from which to fetch the variable.
258  */
259 template <class PAYLOAD_T, class ALLOC>
260 inline
261 auto
262 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getEltSpan (const AuxVectorData& container) const
263  -> const_Elt_span
264 {
265  auto beg = reinterpret_cast<const Elt_t*>(container.getDataArray (m_auxid));
266  return const_Elt_span (beg, container.size_v());
267 }
268 
269 
270 /**
271  * @brief Get a span over the payload vector.
272  * @param container The container from which to fetch the variable.
273  */
274 template <class PAYLOAD_T, class ALLOC>
275 inline
276 auto
277 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getPayloadSpan (const AuxVectorData& container) const
278  -> const_Payload_span
279 {
280  const AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
281  return const_Payload_span (reinterpret_cast<const Payload_t*>(sp->beg),
282  sp->size);
283 }
284 
285 
286 /**
287  * @brief Get a span over spans representing the jagged vector.
288  * @param container The container from which to fetch the variable.
289  */
290 template <class PAYLOAD_T, class ALLOC>
291 inline
292 auto
293 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getDataSpan (const AuxVectorData& container) const
294  -> const_span
295 {
296  const_Elt_span elt_span = getEltSpan (container);
297  return const_span (elt_span,
298  ConstConverter_t (elt_span.data(),
299  *container.getDataSpan (m_linkedAuxid)));
300 }
301 
302 
303 /**
304  * @brief Get a span over the array of @c JaggedVecElt objects,
305  * as a decoration.
306  * @param container The container from which to fetch the variable.
307  *
308  * If the container is locked, this will allow fetching only variables
309  * that do not yet exist (in which case they will be marked as decorations)
310  * or variables already marked as decorations.
311  */
312 template <class PAYLOAD_T, class ALLOC>
313 inline
314 auto
315 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getEltDecorSpan (const AuxVectorData& container) const
316  -> Elt_span
317 {
318  auto beg = reinterpret_cast<Elt_t*>
319  (container.getDecorationArray (this->m_auxid));
320  return Elt_span (beg, container.size_v());
321 }
322 
323 
324 /**
325  * @brief Get a span over the payload vector,
326  * as a decoration.
327  * @param container The container from which to fetch the variable.
328  *
329  * If the container is locked, this will allow fetching only variables
330  * that do not yet exist (in which case they will be marked as decorations)
331  * or variables already marked as decorations.
332  */
333 template <class PAYLOAD_T, class ALLOC>
334 inline
335 auto
336 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getPayloadDecorSpan (const AuxVectorData& container) const
337  -> Payload_span
338 {
339  (void)container.getDecorationArray (this->m_linkedAuxid); // check for locking
340  const AuxDataSpanBase* sp = container.getDataSpan (m_linkedAuxid);
341  return Payload_span (reinterpret_cast<Payload_t*>(sp->beg), sp->size);
342 }
343 
344 
345 /**
346  * @brief Get a span over spans representing the jagged vector,
347  * as a decoration.
348  * @param container The container from which to fetch the variable.
349  *
350  * If the container is locked, this will allow fetching only variables
351  * that do not yet exist (in which case they will be marked as decorations)
352  * or variables already marked as decorations.
353  */
354 template <class PAYLOAD_T, class ALLOC>
355 inline
356 auto
357 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::getDecorationSpan (const AuxVectorData& container) const
358  -> span
359 {
360  Elt_span elt_span = getEltDecorSpan(container);
361  AuxVectorData& container_nc ATLAS_THREAD_SAFE = const_cast<AuxVectorData&> (container);
362  return span (elt_span,
363  Converter_t (container_nc, this->auxid(), this->linkedAuxid()));
364 }
365 
366 
367 /**
368  * @brief Test to see if this variable exists in the store and is writable.
369  * @param e An element of the container om which to test the variable.
370  */
371 template <class PAYLOAD_T, class ALLOC>
372 template <IsConstAuxElement ELT>
373 inline
374 bool
375 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::isAvailableWritable (const ELT& e) const
376 {
377  return e.container() &&
378  e.container()->isAvailableWritableAsDecoration (m_auxid) &&
379  e.container()->isAvailableWritableAsDecoration (m_linkedAuxid);
380 }
381 
382 
383 /**
384  * @brief Test to see if this variable exists in the store and is writable.
385  * @param c The container in which to test the variable.
386  */
387 template <class PAYLOAD_T, class ALLOC>
388 inline
389 bool
390 Decorator<JaggedVecElt<PAYLOAD_T>, ALLOC>::isAvailableWritable (const AuxVectorData& c) const
391 {
392  return c.isAvailableWritableAsDecoration (m_auxid) &&
393  c.isAvailableWritableAsDecoration (m_linkedAuxid);
394 }
395 
396 
397 } // namespace SG