ATLAS Offline Software
AthLinks/DataLink.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 /**
5  * @file AthLinks/DataLink.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Nov, 2013
8  * @brief Object reference supporting deferred reading from StoreGate.
9  */
10 
11 
12 #include "AthLinks/exceptions.h"
13 #include "AthenaKernel/StorableConversions.h"
14 #include "SGTools/DataProxy.h"
15 #include "AthenaKernel/ExtendedEventContext.h"
16 
17 
18 /**
19  * @brief Return the CLID for the class that we reference.
20  */
21 template <typename STORABLE>
22 inline
23 const CLID& DataLink<STORABLE>::classID()
24 {
25  return ClassID_traits<value_type>::ID();
26 }
27 
28 
29 /**
30  * @brief Default constructor --- gives the equivalent of a NULL pointer.
31  */
32 template <typename STORABLE>
33 inline
34 DataLink<STORABLE>::DataLink()
35 {
36 }
37 
38 
39 /**
40  * @brief Constructor --- link to a STORABLE using a transient ref to it.
41  * @param data The object to which to link.
42  * @param sg Associated store; if 0, use the global default.
43  */
44 template <typename STORABLE>
45 inline
46 DataLink<STORABLE>::DataLink(const_reference data, IProxyDict* sg/*=0*/)
47  : DataLinkBase (&data, classID(), sg)
48 {
49 }
50 
51 
52 /**
53  * @brief Constructor --- link to a STORABLE using a transient ref to it.
54  * @param data The object to which to link.
55  * @param ctx Event context for this link.
56  */
57 template <typename STORABLE>
58 inline
59 DataLink<STORABLE>::DataLink(const_reference data, const EventContext& ctx)
60  : DataLinkBase (&data, classID(), Atlas::getExtendedEventContext(ctx).proxy())
61 {
62 }
63 
64 
65 /**
66  * @brief Constructor --- link to a STORABLE using a transient pointer to it.
67  * @param data The object to which to link.
68  * @param sg Associated store; if 0, use the global default.
69  */
70 template <typename STORABLE>
71 inline
72 DataLink<STORABLE>::DataLink(const_pointer pdata, IProxyDict* sg/*=0*/)
73  : DataLinkBase (pdata, classID(), sg)
74 {
75 }
76 
77 
78 /**
79  * @brief Constructor --- link to a STORABLE using a transient pointer to it.
80  * @param data The object to which to link.
81  * @param ctx Event context for this link.
82  */
83 template <typename STORABLE>
84 inline
85 DataLink<STORABLE>::DataLink(const_pointer pdata, const EventContext& ctx)
86  : DataLinkBase (pdata, classID(), Atlas::getExtendedEventContext(ctx).proxy())
87 {
88 }
89 
90 
91 /**
92  * @brief Constructor --- link to a STORABLE using a string ID.
93  * @param dataID Key of the object.
94  * @param sg Associated store; if 0, use the global default.
95  */
96 template <typename STORABLE>
97 inline
98 DataLink<STORABLE>::DataLink(const ID_type& dataID,
99  IProxyDict* sg /*=0*/)
100  : DataLinkBase (dataID, classID(), sg)
101 {
102 }
103 
104 
105 /**
106  * @brief Constructor --- link to a STORABLE using a string ID.
107  * @param dataID Key of the object.
108  * @param ctx Event context for this link.
109  */
110 template <typename STORABLE>
111 inline
112 DataLink<STORABLE>::DataLink(const ID_type& dataID,
113  const EventContext& ctx)
114  : DataLinkBase (dataID, classID(), Atlas::getExtendedEventContext(ctx).proxy())
115 {
116 }
117 
118 
119 /**
120  * @brief Constructor --- link to a STORABLE using a hashed ID.
121  * @param key Hashed key of the object.
122  * @param sg Associated store; if 0, use the global default.
123  *
124  * May throw @c ExcCLIDMismatch.
125  */
126 template <typename STORABLE>
127 inline
128 DataLink<STORABLE>::DataLink(sgkey_t key, IProxyDict* sg /*=0*/)
129  : DataLinkBase (key, classID(), sg)
130 {
131 }
132 
133 
134 /**
135  * @brief Constructor --- link to a STORABLE using a hashed ID.
136  * @param key Hashed key of the object.
137  * @param ctx Event context for this link.
138  *
139  * May throw @c ExcCLIDMismatch.
140  */
141 template <typename STORABLE>
142 inline
143 DataLink<STORABLE>::DataLink(sgkey_t key, const EventContext& ctx)
144  : DataLinkBase (key, classID(), Atlas::getExtendedEventContext(ctx).proxy())
145 {
146 }
147 
148 
149 /**
150  * @brief Constructor from a hashed key and a proxy holder object.
151  * Used internally for EL -> DL conversion.
152  * @param key Hashed key of the object.
153  * @param holder Internal holder object for the proxy.
154  */
155 template <typename STORABLE>
156 inline
157 DataLink<STORABLE>::DataLink(sgkey_t key, const SG::DataProxyHolder& holder)
158  : DataLinkBase (key, holder)
159 {
160 }
161 
162 
163 /**
164  * @brief Set the link to an object given by a reference.
165  * @param data The object to which to link.
166  * @param sg Associated store.
167  *
168  * If @c sg is 0, then we take the store from whatever the link's currently
169  * set to. If the link has no current store, then we take the global
170  * default.
171  */
172 template <typename STORABLE>
173 inline
174 void DataLink<STORABLE>::toStorableObject(const_reference data,
175  IProxyDict* sg /*= 0*/)
176 {
177  DataLinkBase::toStorableObject (&data, classID(), sg);
178 }
179 
180 
181 /**
182  * @brief Set the link to an object given by a reference.
183  * @param data The object to which to link.
184  * @param ctx Event context for this link.
185  */
186 template <typename STORABLE>
187 inline
188 void DataLink<STORABLE>::toStorableObject(const_reference data,
189  const EventContext& ctx)
190 {
191  DataLinkBase::toStorableObject (&data, classID(), Atlas::getExtendedEventContext(ctx).proxy());
192 }
193 
194 
195 /**
196  * @brief Set the link to an object given by a string key.
197  * @param dataID Key of the object.
198  * @param sg Associated store.
199  *
200  * If @c sg is 0, then we take the store from whatever the link's currently
201  * set to. If the link has no current store, then we take the global
202  * default.
203  */
204 template <typename STORABLE>
205 inline
206 void DataLink<STORABLE>::toIdentifiedObject(const ID_type& dataID,
207  IProxyDict* sg /*= 0*/)
208 {
209  DataLinkBase::toIdentifiedObject (dataID, classID(), sg);
210 }
211 
212 
213 /**
214  * @brief Set the link to an object given by a string key.
215  * @param dataID Key of the object.
216  * @param ctx Event context for this link.
217  */
218 template <typename STORABLE>
219 inline
220 void DataLink<STORABLE>::toIdentifiedObject(const ID_type& dataID,
221  const EventContext& ctx)
222 {
223  DataLinkBase::toIdentifiedObject (dataID, classID(), Atlas::getExtendedEventContext(ctx).proxy());
224 }
225 
226 
227 /**
228  * @brief Set the link to an object given by a hashed key.
229  * @param key Hashed key of the object.
230  * @param sg Associated store.
231  *
232  * If @c sg is 0, then we take the store from whatever the link's currently
233  * set to. If the link has no current store, then we take the global
234  * default.
235  *
236  * May throw @c ExcCLIDMismatch.
237  */
238 template <typename STORABLE>
239 inline
240 void DataLink<STORABLE>::toIdentifiedObject(sgkey_t key,
241  IProxyDict* sg /*= 0*/)
242 {
243  DataLinkBase::toIdentifiedObject (key, classID(), sg);
244 }
245 
246 
247 /**
248  * @brief Set the link to an object given by a hashed key.
249  * @param key Hashed key of the object.
250  * @param ctx Event context for this link.
251  *
252  * May throw @c ExcCLIDMismatch.
253  */
254 template <typename STORABLE>
255 inline
256 void DataLink<STORABLE>::toIdentifiedObject(sgkey_t key,
257  const EventContext& ctx)
258 {
259  DataLinkBase::toIdentifiedObject (key, classID(), Atlas::getExtendedEventContext(ctx).proxy());
260 }
261 
262 
263 /**
264  * @brief Set the link to the default object of this type.
265  * @param sg Associated store.
266  *
267  * If @c sg is 0, then we take the store from whatever the link's currently
268  * set to. If the link has no current store, then we take the global
269  * default.
270  *
271  * Note that this is _not_ the same as clearing the link
272  * (use @c clear for that). This produces a link that will resolve
273  * to any object in SG of the given type, provided that there is only
274  * one of them. (An attempt to dereference an ambiguous default link
275  * will give an error.)
276  */
277 template <typename STORABLE>
278 inline
279 void DataLink<STORABLE>::toDefaultObject (IProxyDict* sg /*= 0*/)
280 {
281  DataLinkBase::toIdentifiedObject (SG::DEFAULTKEY, classID(), sg);
282 }
283 
284 
285 /**
286  * @brief Set the link to the default object of this type.
287  * @param ctx Event context for this link.
288  *
289  * Note that this is _not_ the same as clearing the link
290  * (use @c clear for that). This produces a link that will resolve
291  * to any object in SG of the given type, provided that there is only
292  * one of them. (An attempt to dereference an ambiguous default link
293  * will give an error.)
294  */
295 template <typename STORABLE>
296 inline
297 void DataLink<STORABLE>::toDefaultObject (const EventContext& ctx)
298 {
299  DataLinkBase::toIdentifiedObject (SG::DEFAULTKEY, classID(), Atlas::getExtendedEventContext(ctx).proxy());
300 }
301 
302 
303 /**
304  * @brief Finish initialization after link has been read.
305  * @param sg Associated store.
306  *
307  * This should be called after a link has been read by root
308  * in order to set the proxy pointer.
309  * Returns true.
310  *
311  * If @c sg is 0, then we use the global default store.
312  */
313 template <typename STORABLE>
314 inline
315 bool DataLink<STORABLE>::toTransient (IProxyDict* sg /*= 0*/)
316 {
317  return DataLinkBase::toTransient (sg);
318 }
319 
320 
321 /**
322  * @brief Finish initialization after link has been read.
323  * @param ctx Event context for this link.
324  *
325  * This should be called after a link has been read by root
326  * in order to set the proxy pointer.
327  * Returns true.
328  */
329 template <typename STORABLE>
330 inline
331 bool DataLink<STORABLE>::toTransient (const EventContext& ctx)
332 {
333  return DataLinkBase::toTransient (Atlas::getExtendedEventContext(ctx).proxy());
334 }
335 
336 
337 /**
338  * @brief Finish initialization like the link as just been read from root,
339  * but with a specified key.
340  * @param dataID Key of the object.
341  * @param sg Associated store.
342  *
343  * The link should be clear before this is called.
344  * Returns true.
345  *
346  * If @c sg is 0, then we use the global default store.
347  */
348 template <typename STORABLE>
349 inline
350 bool DataLink<STORABLE>::toTransient (const ID_type& dataID,
351  IProxyDict* sg /*= 0*/)
352 {
353  return DataLinkBase::toTransient (dataID, classID(), sg);
354 }
355 
356 
357 /**
358  * @brief Finish initialization like the link as just been read from root,
359  * but with a specified key.
360  * @param dataID Key of the object.
361  * @param ctx Event context for this link.
362  *
363  * The link should be clear before this is called.
364  * Returns true.
365  */
366 template <typename STORABLE>
367 inline
368 bool DataLink<STORABLE>::toTransient (const ID_type& dataID,
369  const EventContext& ctx)
370 {
371  return DataLinkBase::toTransient (dataID, classID(), Atlas::getExtendedEventContext(ctx).proxy());
372 }
373 
374 
375 /**
376  * @brief Return a pointer to the currently-referenced object.
377  * @return A pointer to an object of the type given by @a clid,
378  * or null on a failure (or if the reference is null).
379  */
380 template <typename STORABLE>
381 inline
382 typename DataLink<STORABLE>::const_pointer
383 DataLink<STORABLE>::getDataPtr() const
384 {
385  return reinterpret_cast<const_pointer> (this->storable());
386 }
387 
388 
389 /**
390  * @brief Return a pointer to the currently-referenced object.
391  * @return A pointer to an object of the type given by @a clid,
392  * or null on a failure (or if the reference is null).
393  */
394 template <typename STORABLE>
395 inline
396 typename DataLink<STORABLE>::pointer
397 DataLink<STORABLE>::getDataNonConstPtr()
398 {
399  return reinterpret_cast<pointer> (this->storableNonConst());
400 }
401 
402 
403 /**
404  * @brief Dereference the link.
405  */
406 template< typename STORABLE>
407 inline
408 typename DataLink< STORABLE >::const_reference
409 DataLink< STORABLE >::operator* () const
410 {
411  const_pointer p = this->getDataPtr();
412  if (!p)
413  throwInvalidLink();
414  return *p;
415 }
416 
417 
418 /**
419  * @brief Dereference the link.
420  */
421 template< typename STORABLE>
422 inline
423 typename DataLink< STORABLE >::const_pointer
424 DataLink< STORABLE >::operator->() const
425 {
426  return this->getDataPtr();
427 }
428 
429 
430 /**
431  * @brief Dereference the link.
432  */
433 template< typename STORABLE>
434 inline
435 DataLink<STORABLE>::operator const_pointer() const
436 {
437  return cptr();
438 }
439 
440 
441 /**
442  * @brief Dereference the link.
443  */
444 template< typename STORABLE>
445 inline
446 typename DataLink< STORABLE >::const_pointer
447 DataLink< STORABLE >::cptr() const
448 {
449  return this->getDataPtr();
450 }
451 
452 
453 /**
454  * @brief Test to see if the link is dereferencable.
455  */
456 template <typename STORABLE>
457 inline
458 bool
459 DataLink<STORABLE>::isValid() const
460 {
461  return 0 != getDataPtr();
462 }
463 
464 
465 /**
466  * @brief True if the link is not dereferencable.
467  */
468 template <typename STORABLE>
469 inline
470 bool DataLink<STORABLE>::operator!() const
471 {
472  return !isValid();
473 }
474 
475 
476 /**
477  * @brief Return a (void) pointer to the currently-referenced object.
478  * @return A pointer to an object of the type given by @a clid,
479  * or null on a failure (or if the reference is null).
480  */
481 template <typename STORABLE>
482 inline
483 const void* DataLink<STORABLE>::storable() const
484 {
485  typedef STORABLE* fn_t (SG::DataProxy*);
486  fn_t* fn = &SG::DataProxy_cast<STORABLE>;
487  return this->storableBase (reinterpret_cast<castfn_t*> (fn), classID(), true);
488 }
489 
490 
491 /**
492  * @brief Return a (void) pointer to the currently-referenced object.
493  * @return A pointer to an object of the type given by @a clid,
494  * or null on a failure (or if the reference is null).
495  */
496 template <typename STORABLE>
497 inline
498 void* DataLink<STORABLE>::storableNonConst()
499 {
500  typedef STORABLE* fn_t (SG::DataProxy*);
501  fn_t* fn = &SG::DataProxy_cast<STORABLE>;
502  return this->storableBase (reinterpret_cast<castfn_t*> (fn), classID(), false);
503 }
504 
505 
506 
507