2 * Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration.
5 * @file AsgDataHandles/WriteDecorHandle.icc
6 * @author Nils Krumnack <Nils.Erik.Krumnack@cern.h>
7 * @author scott snyder <snyder@bnl.gov> (for original version)
8 * @brief Handle class for adding a decoration to an object.
12 // #include "CxxUtils/checker_macros.h"
19 * @brief Constructor from a WriteDecorHandleKey.
20 * @param key The key object holding the clid/key/store/attr.
22 * This will raise an exception if the StoreGate key is blank,
23 * or if the event store cannot be found.
25 template <class T, class D>
26 WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key)
27 : Base (key.contHandleKey(), nullptr),
28 m_decorKey (key.key()),
29 m_acc (SG::decorKeyFromKey (key.key()))
30 // m_madeAlias (false)
36 * @brief Constructor from a ReadDecorHandleKey and an explicit event context.
37 * @param key The key object holding the clid/key.
38 * @param ctx The event context.
40 * This will raise an exception if the StoreGate key is blank,
41 * or if the event store cannot be found.
43 * If the default event store has been requested, then the thread-specific
44 * store from the event context will be used.
46 template <class T, class D>
47 WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandleKey<T>& key,
48 const EventContext& ctx)
49 : Base (key.contHandleKey(), &ctx),
50 m_decorKey (key.key()),
51 m_acc (SG::decorKeyFromKey (key.key()))
52 // m_madeAlias (false)
58 // * @brief Copy constructor.
60 // template <class T, class D>
61 // WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandle& rhs)
63 // m_decorKey (rhs.m_decorKey),
65 // m_madeAlias (rhs.m_madeAlias)
71 // * @brief Move constructor.
73 // template <class T, class D>
74 // WriteDecorHandle<T, D>::WriteDecorHandle (WriteDecorHandle&& rhs)
75 // : Base (std::move (rhs)),
76 // m_decorKey (std::move (rhs.m_decorKey)),
77 // m_acc (std::move (rhs.m_acc)),
78 // m_madeAlias (rhs.m_madeAlias)
80 // rhs.m_madeAlias = false;
85 // * @brief Destructor. This will lock the decoration.
87 // template <class T, class D>
88 // WriteDecorHandle<T, D>::~WriteDecorHandle()
90 // // Lock the decoration. But don't do anything if we haven't touched it.
92 // const IConstAuxStore* store = this->vectorData()->getConstStore();
94 // IConstAuxStore* store_nc ATLAS_THREAD_SAFE = const_cast<IConstAuxStore*> (store);
95 // store_nc->lockDecoration (auxid());
102 // * @brief Assignment operator.
104 // template <class T, class D>
105 // WriteDecorHandle<T, D>& WriteDecorHandle<T, D>::operator= (const WriteDecorHandle& rhs)
107 // if (this != &rhs) {
108 // *static_cast<Base*>(this) = rhs;
109 // m_acc = rhs.m_acc;
110 // m_decorKey = rhs.m_decorKey;
111 // m_madeAlias = rhs.m_madeAlias;
118 // * @brief Move operator.
120 // template <class T, class D>
121 // WriteDecorHandle<T, D>& WriteDecorHandle<T, D>::operator= (WriteDecorHandle&& rhs)
123 // if (this != &rhs) {
124 // *static_cast<Base*>(this) = std::move (rhs);
125 // m_acc = std::move (rhs.m_acc);
126 // m_decorKey = std::move (rhs.m_decorKey);
127 // m_madeAlias = rhs.m_madeAlias;
128 // rhs.m_madeAlias = false;
135 * @brief Is the referenced container present in SG?
137 * Note that this tests for the presence of the _container_,
138 * not for the decoration.
140 * Const method; the handle does not change as a result of this.
142 template <class T, class D>
143 bool WriteDecorHandle<T, D>::isPresent() const
145 return Base::isPresent();
150 // * @brief Explicitly set the event store.
151 // * @param store The new event store.
153 // * This implicitly does a reset().
155 // * We need to override this so that the setting gets made on the container
158 // template <class T, class D>
159 // StatusCode WriteDecorHandle<T, D>::setProxyDict (IProxyDict* store)
161 // m_madeAlias = false;
162 // return Base::setProxyDict (store);
167 * @brief Fetch the variable for one element, as a reference.
168 * @param e The element for which to fetch the variable.
170 template <class T, class D>
171 typename WriteDecorHandle<T, D>::reference_type
172 WriteDecorHandle<T, D>::operator() (const AuxElement& e)
180 // * @brief Fetch the variable for one element, as a reference.
181 // * @param index The index of the desired element.
183 // * This looks up the variable in the object referenced by this handle.
184 // * For a standalone object, pass an index of 0.
186 // template <class T, class D>
187 // typename WriteDecorHandle<T, D>::reference_type
188 // WriteDecorHandle<T, D>::operator() (size_t i)
191 // return m_acc (*this->vectorData(), i);
196 // * @brief Get a pointer to the start of the auxiliary data array,
197 // * for the referenced object.
199 // template <class T, class D>
200 // typename WriteDecorHandle<T, D>::container_pointer_type
201 // WriteDecorHandle<T, D>::getDecorationArray()
203 // return reinterpret_cast<container_pointer_type>
204 // (this->vectorData()->getDecorationArray (m_acc.auxid()));
209 * @brief Test to see if this variable exists in the store,
210 * for the referenced object.
211 * Specialization for the case of a standalone object
212 * (@c T derives from @c SG::AuxElement).
214 template <class T, class D>
216 bool WriteDecorHandle<T, D>::isAvailable (std::true_type)
218 const T* ptr = this->ptr();
220 const SG::AuxVectorData* obj = ptr->container();
222 return obj->isAvailable (m_acc.auxid());
231 * @brief Test to see if this variable exists in the store,
232 * for the referenced object.
233 * Specialization for the case of a container
234 * (@c T does not derive from @c SG::AuxElement).
236 template <class T, class D>
238 bool WriteDecorHandle<T, D>::isAvailable (std::false_type)
240 const T* ptr = this->ptr();
242 return ptr->isAvailable (m_acc.auxid());
250 * @brief Test to see if this variable exists in the store,
251 * for the referenced object.
253 template <class T, class D>
255 bool WriteDecorHandle<T, D>::isAvailable()
257 // if (!this->m_ptr) {
258 // ReadHandle<T>::typeless_dataPointer_impl (true);
260 // We can't just use vectorData() because that will create the decoration
262 return isAvailable (typename std::is_base_of<SG::AuxElement, T>::type());
267 // * @brief Return the aux id for this variable.
269 // template <class T, class D>
270 // SG::auxid_t WriteDecorHandle<T, D>::auxid() const
272 // return m_acc.auxid();
277 // * @brief Return the mode (read/write/update) for this handle.
279 // template <class T, class D>
281 // Gaudi::DataHandle::Mode WriteDecorHandle<T, D>::mode() const
283 // return Gaudi::DataHandle::Writer;
288 * @brief Return the name of the decoration alias (CONT.DECOR).
290 template <class T, class D>
292 std::string WriteDecorHandle<T, D>::decorKey() const
299 // * @brief Retrieve an object from StoreGate.
300 // * @param quiet If true, suppress failure messages.
302 // * Extended for decoration handles: when we first retrieve the object,
303 // * we make an alias for the decoration and also create the decoration itself.
305 // template <class T, class D>
306 // void* WriteDecorHandle<T, D>::typeless_dataPointer_impl (bool quiet)
308 // if (this->m_ptr && this->m_madeAlias)
309 // return this->m_ptr;
310 // if (!this->m_ptr) {
311 // ReadHandle<T>::typeless_dataPointer_impl (quiet);
313 // if (!this->m_ptr) {
316 // if (this->alias (WriteHandleKey<T> (this->m_decorKey)).isFailure())
318 // // Important to call the base class method above before calling vectorData;
319 // // otherwise, we'll get an infinite recursion.
320 // // Also don't call getDecorationArray if the container is empty.
321 // if (this->m_ptr && this->vectorData()->size_v() > 0) {
322 // m_acc.getDecorationArray (*this->vectorData());
324 // this->m_madeAlias = true;
325 // return this->m_ptr;
330 // * @brief Return the referenced object as a @c SG::AuxVectorData.
331 // * Specialization for the case of a standalone object
332 // * (@c T derives from @c SG::AuxElement).
334 // template <class T, class D>
335 // const SG::AuxVectorData* WriteDecorHandle<T, D>::vectorData (std::true_type)
337 // return (*this)->container();
342 // * @brief Return the referenced object as a @c SG::AuxVectorData.
343 // * Specialization for the case of a container
344 // * (@c T does not derive from @c SG::AuxElement).
346 // template <class T, class D>
347 // const SG::AuxVectorData* WriteDecorHandle<T, D>::vectorData (std::false_type)
349 // return this->cptr();
354 // * @brief Return the referenced object as a @c SG::AuxVectorData.
356 // * If @c T is a container object, then this should be the object itself.
357 // * But if it is a standalone object, deriving from @c SG::AuxElement,
358 // * then we need to call container() on the object.
360 // template <class T, class D>
361 // const SG::AuxVectorData* WriteDecorHandle<T, D>::vectorData()
363 // return vectorData (typename std::is_base_of<SG::AuxElement, T>::type());
368 * @brief Return a @c WriteDecorHandle referencing @c key.
369 * @param key The key object holding the clid/key/store.
371 * This will raise an exception if the StoreGate key is blank,
372 * or if the event store cannot be found.
374 * The type of the decoration must be included as an explicit template parameter:
377 * auto handle = SG::makeHandle<float> (key);
380 * Note that @c D comes first in the argument list. It's given explicitly,
381 * while @c T is inferred from @c key.
383 template <class D, class T>
384 WriteDecorHandle<T, D> makeHandle (const WriteDecorHandleKey<T>& key)
386 return WriteDecorHandle<T, D> (key);
391 * @brief Return a @c WriteDecorHandle referencing @c key for an explicit context.
392 * @param key The key object holding the clid/key/store.
393 * @param ctx The event context.
395 * This will raise an exception if the StoreGate key is blank,
396 * or if the event store cannot be found.
398 * If the default event store has been requested, then the thread-specific
399 * store from the event context will be used.
401 * The type of the decoration must be included as an explicit template parameter:
404 * auto handle = SG::makeHandle<float> (key, ctx);
407 * Note that @c D comes first in the argument list. It's given explicitly,
408 * while @c T is inferred from @c key.
410 template <class D, class T>
411 WriteDecorHandle<T, D> makeHandle (const WriteDecorHandleKey<T>& key,
412 const EventContext& ctx)
414 return WriteDecorHandle<T, D> (key, ctx);
419 // * @brief These two signatures are to catch cases where the explicit
420 // * template argument is omitted from the @c makeHandle call
421 // * and give an error tailored to that. Otherwise, the @c makeHandle
422 // * call for @c ReadHandle would match, potentially giving a much
423 // * more confusing error.
425 // template <class T>
426 // void makeHandle (const WriteDecorHandleKey<T>& /*key*/)
428 // // If you see an error from here, you've forgotten the explicit template
429 // // argument to @c makeHandle giving the decoration type.
430 // // See the examples of @c makeHandle above.
431 // return T::makeHandleForDecorationsRequiresExplicitTemplateArgument();
433 // template <class T>
434 // void makeHandle (const WriteDecorHandleKey<T>& /*key*/,
435 // const EventContext& /*ctx*/)
437 // // If you see an error from here, you've forgotten the explicit template
438 // // argument to @c makeHandle giving the decoration type.
439 // // See the examples of @c makeHandle above.
440 // return T::makeHandleForDecorationsRequiresExplicitTemplateArgument();