ATLAS Offline Software
AthToolSupport/AsgDataHandles/AsgDataHandles/WriteDecorHandle.icc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration.
3  */
4 /**
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.
9  */
10 
11 
12 // #include "CxxUtils/checker_macros.h"
13 
14 
15 namespace SG {
16 
17 
18 /**
19  * @brief Constructor from a WriteDecorHandleKey.
20  * @param key The key object holding the clid/key/store/attr.
21  *
22  * This will raise an exception if the StoreGate key is blank,
23  * or if the event store cannot be found.
24  */
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)
31 {
32 }
33 
34 
35 /**
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.
39  *
40  * This will raise an exception if the StoreGate key is blank,
41  * or if the event store cannot be found.
42  *
43  * If the default event store has been requested, then the thread-specific
44  * store from the event context will be used.
45  */
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)
53 {
54 }
55 
56 
57 // /**
58 // * @brief Copy constructor.
59 // */
60 // template <class T, class D>
61 // WriteDecorHandle<T, D>::WriteDecorHandle (const WriteDecorHandle& rhs)
62 // : Base (rhs),
63 // m_decorKey (rhs.m_decorKey),
64 // m_acc (rhs.m_acc),
65 // m_madeAlias (rhs.m_madeAlias)
66 // {
67 // }
68 
69 
70 // /**
71 // * @brief Move constructor.
72 // */
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)
79 // {
80 // rhs.m_madeAlias = false;
81 // }
82 
83 
84 // /**
85 // * @brief Destructor. This will lock the decoration.
86 // */
87 // template <class T, class D>
88 // WriteDecorHandle<T, D>::~WriteDecorHandle()
89 // {
90 // // Lock the decoration. But don't do anything if we haven't touched it.
91 // if (m_madeAlias) {
92 // const IConstAuxStore* store = this->vectorData()->getConstStore();
93 // if (store) {
94 // IConstAuxStore* store_nc ATLAS_THREAD_SAFE = const_cast<IConstAuxStore*> (store);
95 // store_nc->lockDecoration (auxid());
96 // }
97 // }
98 // }
99 
100 
101 // /**
102 // * @brief Assignment operator.
103 // */
104 // template <class T, class D>
105 // WriteDecorHandle<T, D>& WriteDecorHandle<T, D>::operator= (const WriteDecorHandle& rhs)
106 // {
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;
112 // }
113 // return *this;
114 // }
115 
116 
117 // /**
118 // * @brief Move operator.
119 // */
120 // template <class T, class D>
121 // WriteDecorHandle<T, D>& WriteDecorHandle<T, D>::operator= (WriteDecorHandle&& rhs)
122 // {
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;
129 // }
130 // return *this;
131 // }
132 
133 
134 /**
135  * @brief Is the referenced container present in SG?
136  *
137  * Note that this tests for the presence of the _container_,
138  * not for the decoration.
139  *
140  * Const method; the handle does not change as a result of this.
141  */
142 template <class T, class D>
143 bool WriteDecorHandle<T, D>::isPresent() const
144 {
145  return Base::isPresent();
146 }
147 
148 
149 // /**
150 // * @brief Explicitly set the event store.
151 // * @param store The new event store.
152 // *
153 // * This implicitly does a reset().
154 // *
155 // * We need to override this so that the setting gets made on the container
156 // * handle as well.
157 // */
158 // template <class T, class D>
159 // StatusCode WriteDecorHandle<T, D>::setProxyDict (IProxyDict* store)
160 // {
161 // m_madeAlias = false;
162 // return Base::setProxyDict (store);
163 // }
164 
165 
166 /**
167  * @brief Fetch the variable for one element, as a reference.
168  * @param e The element for which to fetch the variable.
169  */
170 template <class T, class D>
171 typename WriteDecorHandle<T, D>::reference_type
172 WriteDecorHandle<T, D>::operator() (const AuxElement& e)
173 {
174  this->cptr();
175  return m_acc (e);
176 }
177 
178 
179 // /**
180 // * @brief Fetch the variable for one element, as a reference.
181 // * @param index The index of the desired element.
182 // *
183 // * This looks up the variable in the object referenced by this handle.
184 // * For a standalone object, pass an index of 0.
185 // */
186 // template <class T, class D>
187 // typename WriteDecorHandle<T, D>::reference_type
188 // WriteDecorHandle<T, D>::operator() (size_t i)
189 // {
190 // this->cptr();
191 // return m_acc (*this->vectorData(), i);
192 // }
193 
194 
195 // /**
196 // * @brief Get a pointer to the start of the auxiliary data array,
197 // * for the referenced object.
198 // */
199 // template <class T, class D>
200 // typename WriteDecorHandle<T, D>::container_pointer_type
201 // WriteDecorHandle<T, D>::getDecorationArray()
202 // {
203 // return reinterpret_cast<container_pointer_type>
204 // (this->vectorData()->getDecorationArray (m_acc.auxid()));
205 // }
206 
207 
208 /**
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).
213  */
214 template <class T, class D>
215 inline
216 bool WriteDecorHandle<T, D>::isAvailable (std::true_type)
217 {
218  const T* ptr = this->ptr();
219  if (ptr) {
220  const SG::AuxVectorData* obj = ptr->container();
221  if (obj) {
222  return obj->isAvailable (m_acc.auxid());
223  }
224  }
225 
226  return false;
227 }
228 
229 
230 /**
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).
235  */
236 template <class T, class D>
237 inline
238 bool WriteDecorHandle<T, D>::isAvailable (std::false_type)
239 {
240  const T* ptr = this->ptr();
241  if (ptr) {
242  return ptr->isAvailable (m_acc.auxid());
243  }
244 
245  return false;
246 }
247 
248 
249 /**
250  * @brief Test to see if this variable exists in the store,
251  * for the referenced object.
252  */
253 template <class T, class D>
254 inline
255 bool WriteDecorHandle<T, D>::isAvailable()
256 {
257  // if (!this->m_ptr) {
258  // ReadHandle<T>::typeless_dataPointer_impl (true);
259  // }
260  // We can't just use vectorData() because that will create the decoration
261  // as a side effect.
262  return isAvailable (typename std::is_base_of<SG::AuxElement, T>::type());
263 }
264 
265 
266 // /**
267 // * @brief Return the aux id for this variable.
268 // */
269 // template <class T, class D>
270 // SG::auxid_t WriteDecorHandle<T, D>::auxid() const
271 // {
272 // return m_acc.auxid();
273 // }
274 
275 
276 // /**
277 // * @brief Return the mode (read/write/update) for this handle.
278 // */
279 // template <class T, class D>
280 // inline
281 // Gaudi::DataHandle::Mode WriteDecorHandle<T, D>::mode() const
282 // {
283 // return Gaudi::DataHandle::Writer;
284 // }
285 
286 
287 /**
288  * @brief Return the name of the decoration alias (CONT.DECOR).
289  */
290 template <class T, class D>
291 inline
292 std::string WriteDecorHandle<T, D>::decorKey() const
293 {
294  return m_decorKey;
295 }
296 
297 
298 // /**
299 // * @brief Retrieve an object from StoreGate.
300 // * @param quiet If true, suppress failure messages.
301 // *
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.
304 // */
305 // template <class T, class D>
306 // void* WriteDecorHandle<T, D>::typeless_dataPointer_impl (bool quiet)
307 // {
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);
312 // }
313 // if (!this->m_ptr) {
314 // return nullptr;
315 // }
316 // if (this->alias (WriteHandleKey<T> (this->m_decorKey)).isFailure())
317 // return nullptr;
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());
323 // }
324 // this->m_madeAlias = true;
325 // return this->m_ptr;
326 // }
327 
328 
329 // /**
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).
333 // */
334 // template <class T, class D>
335 // const SG::AuxVectorData* WriteDecorHandle<T, D>::vectorData (std::true_type)
336 // {
337 // return (*this)->container();
338 // }
339 
340 
341 // /**
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).
345 // */
346 // template <class T, class D>
347 // const SG::AuxVectorData* WriteDecorHandle<T, D>::vectorData (std::false_type)
348 // {
349 // return this->cptr();
350 // }
351 
352 
353 // /**
354 // * @brief Return the referenced object as a @c SG::AuxVectorData.
355 // *
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.
359 // */
360 // template <class T, class D>
361 // const SG::AuxVectorData* WriteDecorHandle<T, D>::vectorData()
362 // {
363 // return vectorData (typename std::is_base_of<SG::AuxElement, T>::type());
364 // }
365 
366 
367 /**
368  * @brief Return a @c WriteDecorHandle referencing @c key.
369  * @param key The key object holding the clid/key/store.
370  *
371  * This will raise an exception if the StoreGate key is blank,
372  * or if the event store cannot be found.
373  *
374  * The type of the decoration must be included as an explicit template parameter:
375  *
376  *@code
377  * auto handle = SG::makeHandle<float> (key);
378  @endcode
379  *
380  * Note that @c D comes first in the argument list. It's given explicitly,
381  * while @c T is inferred from @c key.
382  */
383 template <class D, class T>
384 WriteDecorHandle<T, D> makeHandle (const WriteDecorHandleKey<T>& key)
385 {
386  return WriteDecorHandle<T, D> (key);
387 }
388 
389 
390 /**
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.
394  *
395  * This will raise an exception if the StoreGate key is blank,
396  * or if the event store cannot be found.
397  *
398  * If the default event store has been requested, then the thread-specific
399  * store from the event context will be used.
400  *
401  * The type of the decoration must be included as an explicit template parameter:
402  *
403  *@code
404  * auto handle = SG::makeHandle<float> (key, ctx);
405  @endcode
406  *
407  * Note that @c D comes first in the argument list. It's given explicitly,
408  * while @c T is inferred from @c key.
409  */
410 template <class D, class T>
411 WriteDecorHandle<T, D> makeHandle (const WriteDecorHandleKey<T>& key,
412  const EventContext& ctx)
413 {
414  return WriteDecorHandle<T, D> (key, ctx);
415 }
416 
417 
418 // /**
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.
424 // */
425 // template <class T>
426 // void makeHandle (const WriteDecorHandleKey<T>& /*key*/)
427 // {
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();
432 // }
433 // template <class T>
434 // void makeHandle (const WriteDecorHandleKey<T>& /*key*/,
435 // const EventContext& /*ctx*/)
436 // {
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();
441 // }
442 
443 
444 } // namespace SG