2 * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
5 * @file StoreGate/ReadDecorHandle.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Handle class for reading a decoration on an object.
16 * @brief Constructor from a ReadDecorHandleKey.
17 * @param key The key object holding the clid/key/store/attr.
19 * This will raise an exception if the StoreGate key is blank,
20 * or if the event store cannot be found.
22 template <class T, class D>
23 ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key)
24 : Base (key.contHandleKey()),
25 m_decorKey (key.key()),
26 m_acc (SG::decorKeyFromKey (key.key()))
32 * @brief Constructor from a ReadDecorHandleKey and an explicit event context.
33 * @param key The key object holding the clid/key.
34 * @param ctx The event context.
36 * This will raise an exception if the StoreGate key is blank,
37 * or if the event store cannot be found.
39 * If the default event store has been requested, then the thread-specific
40 * store from the event context will be used.
42 template <class T, class D>
43 ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandleKey<T>& key,
44 const EventContext& ctx)
45 : Base (key.contHandleKey(), ctx),
46 m_decorKey (key.key()),
47 m_acc (SG::decorKeyFromKey (key.key()))
53 * @brief Copy constructor.
55 template <class T, class D>
56 ReadDecorHandle<T, D>::ReadDecorHandle (const ReadDecorHandle& rhs)
58 m_decorKey (rhs.m_decorKey),
65 * @brief Move constructor.
67 template <class T, class D>
68 ReadDecorHandle<T, D>::ReadDecorHandle (ReadDecorHandle&& rhs)
69 : Base (std::move (rhs)),
70 m_decorKey (std::move (rhs.m_decorKey)),
71 m_acc (std::move (rhs.m_acc))
77 * @brief Assignment operator.
79 template <class T, class D>
80 ReadDecorHandle<T, D>& ReadDecorHandle<T, D>::operator= (const ReadDecorHandle& rhs)
83 *static_cast<Base*>(this) = rhs;
84 m_decorKey = rhs.m_decorKey;
92 * @brief Move operator.
94 template <class T, class D>
95 ReadDecorHandle<T, D>& ReadDecorHandle<T, D>::operator= (ReadDecorHandle&& rhs)
98 *static_cast<Base*>(this) = std::move (rhs);
99 m_decorKey = std::move (rhs.m_decorKey);
100 m_acc = std::move (rhs.m_acc);
107 * @brief Is the referenced container present in SG?
109 * Note that this tests for the presence of the _container_,
110 * not for the decoration.
112 * Const method; the handle does not change as a result of this.
114 template <class T, class D>
116 bool ReadDecorHandle<T, D>::isPresent() const
118 return Base::isPresent();
123 * @brief Fetch the variable for one element, as a const reference.
124 * @param e The element for which to fetch the variable.
126 template <class T, class D>
128 typename ReadDecorHandle<T, D>::const_reference_type
129 ReadDecorHandle<T, D>::operator() (const AuxElement& e) const
131 // FIXME? In principle, should check here that E is actually an element
132 // of our declared container. But that would force a SG lookup here
133 // which we otherwise wouldn't need to do.
139 * @brief Fetch the variable for one element, as a const reference.
140 * @param index The index of the desired element.
142 * This looks up the variable in the object referenced by this handle.
143 * For a standalone object, pass an index of 0.
145 template <class T, class D>
147 typename ReadDecorHandle<T, D>::const_reference_type
148 ReadDecorHandle<T, D>::operator() (size_t i)
150 return m_acc (*this->vectorData(), i);
155 * @brief Fetch the variable for one element, as a const reference.
156 * @param e The element for which to fetch the variable.
157 * @param deflt Default value.
159 * If this variable is not available, then return @c deflt instead.
161 template <class T, class D>
163 typename ReadDecorHandle<T, D>::const_reference_type
164 ReadDecorHandle<T, D>::withDefault (const AuxElement& e, const D& deflt) const
166 // FIXME? In principle, should check here that E is actually an element
167 // of our declared container. But that would force a SG lookup here
168 // which we otherwise wouldn't need to do.
169 return m_acc.withDefault (e, deflt);
174 * @brief Fetch the variable for one element, as a const reference.
175 * @param index The index of the desired element.
176 * @param deflt Default value.
178 * This looks up the variable in the object referenced by this handle.
179 * For a standalone object, pass an index of 0.
180 * If this variable is not available, then return @c deflt instead.
182 template <class T, class D>
184 typename ReadDecorHandle<T, D>::const_reference_type
185 ReadDecorHandle<T, D>::withDefault (size_t i, const D& deflt)
187 return m_acc.withDefault (*this->vectorData(), i, deflt);
192 * @brief Get a pointer to the start of the auxiliary data array.
193 * for the referenced object.
195 template <class T, class D>
196 template <class POINTER_TYPE /*= const_container_pointer_type*/,
197 typename /*= std::enable_if_t<!std::is_void_v<POINTER_TYPE> >*/ >
199 ReadDecorHandle<T, D>::getDataArray()
201 return m_acc.getDataArray (*this->vectorData());
206 * @brief Get a span over the auxilary data array,
207 * for the referenced object.
209 template <class T, class D>
211 ReadDecorHandle<T, D>::getDataSpan() -> const_span
213 return m_acc.getDataSpan (*this->vectorData());
218 * @brief Test to see if this variable exists in the store,
219 * for the referenced object.
221 template <class T, class D>
223 bool ReadDecorHandle<T, D>::isAvailable()
225 const SG::AuxVectorData* vec = this->vectorData();
226 return vec && vec->isAvailable (m_acc.auxid());
231 * @brief Return the aux id for this variable.
233 template <class T, class D>
235 SG::auxid_t ReadDecorHandle<T, D>::auxid() const
237 return m_acc.auxid();
242 * @brief Return the name of the decoration alias (CONT.DECOR).
244 template <class T, class D>
246 const std::string& ReadDecorHandle<T, D>::decorKey() const
253 * @brief Return the referenced object as a @c SG::AuxVectorData.
254 * Specialization for the case of a standalone object
255 * (@c T derives from @c SG::AuxElement).
257 template <class T, class D>
259 const SG::AuxVectorData* ReadDecorHandle<T, D>::vectorData (std::true_type)
261 return (*this)->container();
266 * @brief Return the referenced object as a @c SG::AuxVectorData.
267 * Specialization for the case of a container
268 * (@c T does not derive from @c SG::AuxElement).
270 template <class T, class D>
272 const SG::AuxVectorData* ReadDecorHandle<T, D>::vectorData (std::false_type)
279 * @brief Return the referenced object as a @c SG::AuxVectorData.
281 * If @c T is a container object, then this should be the object itself.
282 * But if it is a standalone object, deriving from @c SG::AuxElement,
283 * then we need to call container() on the object.
285 template <class T, class D>
287 const SG::AuxVectorData* ReadDecorHandle<T, D>::vectorData()
289 // Dispatch to the appropriate specialization, depending on whether or not
290 // @c T derives from @c SG::AuxElement.
291 return vectorData (typename std::is_base_of<SG::AuxElement, T>::type());
296 * @brief Return a @c ReadDecorHandle referencing @c key.
297 * @param key The key object holding the clid/key/store.
299 * This will raise an exception if the StoreGate key is blank,
300 * or if the event store cannot be found.
302 * The type of the decoration must be included as an explicit template parameter:
305 * auto handle = SG::makeHandle<float> (key);
308 * Note that @c D comes first in the argument list. It's given explicitly,
309 * while @c T is inferred from @c key.
311 template <class D, class T>
312 ReadDecorHandle<T, D> makeHandle (const ReadDecorHandleKey<T>& key)
314 return ReadDecorHandle<T, D> (key);
319 * @brief Return a @c ReadDecorHandle referencing @c key for an explicit context.
320 * @param key The key object holding the clid/key/store.
321 * @param ctx The event context.
323 * This will raise an exception if the StoreGate key is blank,
324 * or if the event store cannot be found.
326 * If the default event store has been requested, then the thread-specific
327 * store from the event context will be used.
329 * The type of the decoration must be included as an explicit template parameter:
332 * auto handle = SG::makeHandle<float> (key, ctx);
335 * Note that @c D comes first in the argument list. It's given explicitly,
336 * while @c T is inferred from @c key.
338 template <class D, class T>
339 ReadDecorHandle<T, D> makeHandle (const ReadDecorHandleKey<T>& key,
340 const EventContext& ctx)
342 return ReadDecorHandle<T, D> (key, ctx);
347 * @brief These two signatures are to catch cases where the explicit
348 * template argument is omitted from the @c makeHandle call
349 * and give an error tailored to that. Otherwise, the @c makeHandle
350 * call for @c ReadHandle would match, potentially giving a much
351 * more confusing error.
354 void makeHandle (const ReadDecorHandleKey<T>& /*key*/)
356 // If you see an error from here, you've forgotten the explicit template
357 // argument to @c makeHandle giving the decoration type.
358 // See the examples of @c makeHandle above.
359 return T::makeHandleForDecorationsRequiresExplicitTemplateArgument();
362 void makeHandle (const ReadDecorHandleKey<T>& /*key*/,
363 const EventContext& /*ctx*/)
365 // If you see an error from here, you've forgotten the explicit template
366 // argument to @c makeHandle giving the decoration type.
367 // See the examples of @c makeHandle above.
368 return T::makeHandleForDecorationsRequiresExplicitTemplateArgument();