ATLAS Offline Software
Decorator.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/Decorator.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  */
10 
11 
12 #include "AthContainers/AuxTypeRegistry.h"
13 #include "AthContainers/exceptions.h"
14 
15 
16 namespace SG {
17 
18 
19 /**
20  * @brief Constructor.
21  * @param name Name of this aux variable.
22  *
23  * The name -> auxid lookup is done here.
24  */
25 template <class T, class ALLOC>
26 inline
27 Decorator<T, ALLOC>::Decorator (const std::string& name)
28  : Decorator (name, "", SG::AuxVarFlags::None)
29 {
30 }
31 
32 
33 /**
34  * @brief Constructor.
35  * @param name Name of this aux variable.
36  * @param clsname The name of its associated class. May be blank.
37  *
38  * The name -> auxid lookup is done here.
39  */
40 template <class T, class ALLOC>
41 inline
42 Decorator<T, ALLOC>::Decorator (const std::string& name,
43  const std::string& clsname)
44  : Decorator (name, clsname, SG::AuxVarFlags::None)
45 {
46 }
47 
48 
49 /**
50  * @brief Constructor taking an auxid directly.
51  * @param auxid ID for this auxiliary variable.
52  *
53  * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
54  */
55 template <class T, class ALLOC>
56 inline
57 Decorator<T, ALLOC>::Decorator (const SG::auxid_t auxid)
58  : Decorator (auxid, SG::AuxVarFlags::None)
59 {
60 }
61 
62 
63 /**
64  * @brief Constructor.
65  * @param name Name of this aux variable.
66  * @param clsname The name of its associated class. May be blank.
67  * @param flags Optional flags qualifying the type. See AuxTypeRegsitry.
68  *
69  * The name -> auxid lookup is done here.
70  */
71 template <class T, class ALLOC>
72 inline
73 Decorator<T, ALLOC>::Decorator
74  (const std::string& name,
75  const std::string& clsname,
76  const SG::AuxVarFlags flags)
77  : m_auxid (SG::AuxTypeRegistry::instance().getAuxID<T, ALLOC> (name, clsname, flags))
78 {
79 }
80 
81 
82 /**
83  * @brief Constructor taking an auxid directly.
84  * @param auxid ID for this auxiliary variable.
85  * @param flags Optional flags qualifying the type. See AuxTypeRegistry.
86  *
87  * Will throw @c SG::ExcAuxTypeMismatch if the types don't match.
88  */
89 template <class T, class ALLOC>
90 inline
91 Decorator<T, ALLOC>::Decorator (const SG::auxid_t auxid,
92  const SG::AuxVarFlags flags)
93  : m_auxid (auxid)
94 {
95  SG::AuxTypeRegistry::instance().checkAuxID<T, ALLOC> (auxid, flags);
96 }
97 
98 
99 /**
100  * @brief Fetch the variable for one element, as a non-const reference.
101  * @param e The element for which to fetch the variable.
102  *
103  * If the container is locked, this will allow fetching only variables
104  * that do not yet exist (in which case they will be marked as decorations)
105  * or variables already marked as decorations.
106  */
107 template <class T, class ALLOC>
108 template <class ELT>
109 ATH_REQUIRES( IsConstAuxElement<ELT> )
110 inline
111 typename Decorator<T, ALLOC>::reference_type
112 Decorator<T, ALLOC>::operator() (const ELT& e) const
113 {
114  assert (e.container() != 0);
115  return e.container()->template getDecoration<T> (m_auxid, e.index());
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  * Looping over the index via this method will be faster then
125  * looping over the elements of the container.
126  *
127  * If the container is locked, this will allow fetching only variables
128  * that do not yet exist (in which case they will be marked as decorations)
129  * or variables already marked as decorations.
130  */
131 template <class T, class ALLOC>
132 inline
133 typename Decorator<T, ALLOC>::reference_type
134 Decorator<T, ALLOC>::operator() (const AuxVectorData& container,
135  size_t index) const
136 {
137  return container.template getDecoration<T> (m_auxid, index);
138 }
139 
140 
141 /**
142  * @brief Set the variable for one element.
143  * @param e The element for which to fetch the variable.
144  * @param x The variable value to set.
145  */
146 template <class T, class ALLOC>
147 template <class ELT>
148 ATH_REQUIRES( IsConstAuxElement<ELT> )
149 inline
150 void Decorator<T, ALLOC>::set (const ELT& e,
151  const element_type& x) const
152 {
153  (*this)(e) = x;
154 }
155 
156 
157 /**
158  * @brief Get a pointer to the start of the auxiliary data array.
159  * @param container The container from which to fetch the variable.
160  */
161 template <class T, class ALLOC>
162 inline
163 typename Decorator<T, ALLOC>::const_container_pointer_type
164 Decorator<T, ALLOC>::getDataArray (const AuxVectorData& container) const
165 {
166  return reinterpret_cast<const_container_pointer_type>
167  (container.getDataArray (m_auxid));
168 }
169 
170 
171 /**
172  * @brief Get a pointer to the start of the auxiliary data array.
173  * @param container The container from which to fetch the variable.
174  *
175  * If the container is locked, this will allow fetching only variables
176  * that do not yet exist (in which case they will be marked as decorations)
177  * or variables already marked as decorations.
178  */
179 template <class T, class ALLOC>
180 inline
181 typename Decorator<T, ALLOC>::container_pointer_type
182 Decorator<T, ALLOC>::getDecorationArray (const AuxVectorData& container) const
183 {
184  return reinterpret_cast<container_pointer_type>
185  (container.getDecorationArray (m_auxid));
186 }
187 
188 
189 /**
190  * @brief Get a span over the auxilary data array.
191  * @param container The container from which to fetch the variable.
192  */
193 template <class T, class ALLOC>
194 inline
195 typename Decorator<T, ALLOC>::const_span
196 Decorator<T, ALLOC>::getDataSpan (const AuxVectorData& container) const
197 {
198  auto beg = reinterpret_cast<const_container_pointer_type>
199  (container.getDataArray (m_auxid));
200  return const_span (beg, container.size_v());
201 }
202 
203 
204 /**
205  * @brief Get a span over the auxilary data array.
206  * @param container The container from which to fetch the variable.
207  *
208  * If the container is locked, this will allow fetching only variables
209  * that do not yet exist (in which case they will be marked as decorations)
210  * or variables already marked as decorations.
211  */
212 template <class T, class ALLOC>
213 inline
214 typename Decorator<T, ALLOC>::span
215 Decorator<T, ALLOC>::getDecorationSpan (const AuxVectorData& container) const
216 {
217  auto beg = reinterpret_cast<container_pointer_type>
218  (container.getDecorationArray (m_auxid));
219  return span (beg, container.size_v());
220 }
221 
222 
223 /**
224  * @brief Test to see if this variable exists in the store.
225  * @param e An element of the container which to test the variable.
226  */
227 template <class T, class ALLOC>
228 template <class ELT>
229 ATH_REQUIRES( IsConstAuxElement<ELT> )
230 inline
231 bool
232 Decorator<T, ALLOC>::isAvailable (const ELT& e) const
233 {
234  return e.container() && e.container()->isAvailable (m_auxid);
235 }
236 
237 /**
238  * @brief Test to see if this variable exists in the store and is writable.
239  * @param e An element of the container which to test the variable.
240  */
241 template <class T, class ALLOC>
242 template <class ELT>
243 ATH_REQUIRES( IsConstAuxElement<ELT> )
244 inline
245 bool
246 Decorator<T, ALLOC>::isAvailableWritable (const ELT& e) const
247 {
248  return e.container() && e.container()->isAvailableWritableAsDecoration (m_auxid);
249 }
250 
251 /**
252  * @brief Return the aux id for this variable.
253  */
254 template <class T, class ALLOC>
255 inline
256 SG::auxid_t
257 Decorator<T, ALLOC>::auxid() const
258 {
259  return m_auxid;
260 }
261 
262 
263 } // namespace SG