ATLAS Offline Software
AthLinks/DataLink.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 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 "SGTools/DataProxy_cast.h"
14 #include "AthenaKernel/proxyDictFromEventContext.h"
15 
16 
17 /**
18  * @brief Return the CLID for the class that we reference.
19  */
20 template <typename STORABLE>
21 inline
22 const CLID& DataLink<STORABLE>::classID()
23 {
24  return ClassID_traits<value_type>::ID();
25 }
26 
27 
28 /**
29  * @brief Default constructor --- gives the equivalent of a NULL pointer.
30  */
31 template <typename STORABLE>
32 inline
33 DataLink<STORABLE>::DataLink()
34 {
35 }
36 
37 
38 /**
39  * @brief Constructor --- link to a STORABLE using a transient ref to it.
40  * @param data The object to which to link.
41  * @param sg Associated store; if 0, use the global default.
42  */
43 template <typename STORABLE>
44 inline
45 DataLink<STORABLE>::DataLink(const_reference data, IProxyDict* sg/*=0*/)
46  : DataLinkBase (&data, classID(), sg)
47 {
48 }
49 
50 
51 /**
52  * @brief Constructor --- link to a STORABLE using a transient ref to it.
53  * @param data The object to which to link.
54  * @param ctx Event context for this link.
55  */
56 template <typename STORABLE>
57 inline
58 DataLink<STORABLE>::DataLink(const_reference data, const EventContext& ctx)
59  : DataLinkBase (&data, classID(), Atlas::proxyDictFromEventContext(ctx))
60 {
61 }
62 
63 
64 /**
65  * @brief Constructor --- link to a STORABLE using a transient pointer to it.
66  * @param data The object to which to link.
67  * @param sg Associated store; if 0, use the global default.
68  */
69 template <typename STORABLE>
70 inline
71 DataLink<STORABLE>::DataLink(const_pointer pdata, IProxyDict* sg/*=0*/)
72  : DataLinkBase (pdata, classID(), sg)
73 {
74 }
75 
76 
77 /**
78  * @brief Constructor --- link to a STORABLE using a transient pointer to it.
79  * @param data The object to which to link.
80  * @param ctx Event context for this link.
81  */
82 template <typename STORABLE>
83 inline
84 DataLink<STORABLE>::DataLink(const_pointer pdata, const EventContext& ctx)
85  : DataLinkBase (pdata, classID(), Atlas::proxyDictFromEventContext(ctx))
86 {
87 }
88 
89 
90 /**
91  * @brief Constructor --- link to a STORABLE using a string ID.
92  * @param dataID Key of the object.
93  * @param sg Associated store; if 0, use the global default.
94  */
95 template <typename STORABLE>
96 inline
97 DataLink<STORABLE>::DataLink(const ID_type& dataID,
98  IProxyDict* sg /*=0*/)
99  : DataLinkBase (dataID, classID(), sg)
100 {
101 }
102 
103 
104 /**
105  * @brief Constructor --- link to a STORABLE using a string ID.
106  * @param dataID Key of the object.
107  * @param ctx Event context for this link.
108  */
109 template <typename STORABLE>
110 inline
111 DataLink<STORABLE>::DataLink(const ID_type& dataID,
112  const EventContext& ctx)
113  : DataLinkBase (dataID, classID(), Atlas::proxyDictFromEventContext(ctx))
114 {
115 }
116 
117 
118 /**
119  * @brief Constructor --- link to a STORABLE using a hashed ID.
120  * @param key Hashed key of the object.
121  * @param sg Associated store; if 0, use the global default.
122  *
123  * May throw @c ExcCLIDMismatch.
124  */
125 template <typename STORABLE>
126 inline
127 DataLink<STORABLE>::DataLink(sgkey_t key, IProxyDict* sg /*=0*/)
128  : DataLinkBase (key, classID(), sg)
129 {
130 }
131 
132 
133 /**
134  * @brief Constructor --- link to a STORABLE using a hashed ID.
135  * @param key Hashed key of the object.
136  * @param ctx Event context for this link.
137  *
138  * May throw @c ExcCLIDMismatch.
139  */
140 template <typename STORABLE>
141 inline
142 DataLink<STORABLE>::DataLink(sgkey_t key, const EventContext& ctx)
143  : DataLinkBase (key, classID(), Atlas::proxyDictFromEventContext(ctx))
144 {
145 }
146 
147 
148 /**
149  * @brief Constructor from a hashed key and a proxy holder object.
150  * Used internally for EL -> DL conversion.
151  * @param key Hashed key of the object.
152  * @param holder Internal holder object for the proxy.
153  */
154 template <typename STORABLE>
155 inline
156 DataLink<STORABLE>::DataLink(sgkey_t key, const SG::DataProxyHolder& holder)
157  : DataLinkBase (key, holder)
158 {
159 }
160 
161 
162 /**
163  * @brief Set the link to an object given by a reference.
164  * @param data The object to which to link.
165  * @param sg Associated store.
166  *
167  * If @c sg is 0, then we take the store from whatever the link's currently
168  * set to. If the link has no current store, then we take the global
169  * default.
170  */
171 template <typename STORABLE>
172 inline
173 void DataLink<STORABLE>::toStorableObject(const_reference data,
174  IProxyDict* sg /*= 0*/)
175 {
176  DataLinkBase::toStorableObject (&data, classID(), sg);
177 }
178 
179 
180 /**
181  * @brief Set the link to an object given by a reference.
182  * @param data The object to which to link.
183  * @param ctx Event context for this link.
184  */
185 template <typename STORABLE>
186 inline
187 void DataLink<STORABLE>::toStorableObject(const_reference data,
188  const EventContext& ctx)
189 {
190  DataLinkBase::toStorableObject (&data, classID(), Atlas::proxyDictFromEventContext(ctx));
191 }
192 
193 
194 /**
195  * @brief Set the link to an object given by a string key.
196  * @param dataID Key of the object.
197  * @param sg Associated store.
198  *
199  * If @c sg is 0, then we take the store from whatever the link's currently
200  * set to. If the link has no current store, then we take the global
201  * default.
202  */
203 template <typename STORABLE>
204 inline
205 void DataLink<STORABLE>::toIdentifiedObject(const ID_type& dataID,
206  IProxyDict* sg /*= 0*/)
207 {
208  DataLinkBase::toIdentifiedObject (dataID, classID(), sg);
209 }
210 
211 
212 /**
213  * @brief Set the link to an object given by a string key.
214  * @param dataID Key of the object.
215  * @param ctx Event context for this link.
216  */
217 template <typename STORABLE>
218 inline
219 void DataLink<STORABLE>::toIdentifiedObject(const ID_type& dataID,
220  const EventContext& ctx)
221 {
222  DataLinkBase::toIdentifiedObject (dataID, classID(), Atlas::proxyDictFromEventContext(ctx));
223 }
224 
225 
226 /**
227  * @brief Set the link to an object given by a hashed key.
228  * @param key Hashed key of the object.
229  * @param sg Associated store.
230  *
231  * If @c sg is 0, then we take the store from whatever the link's currently
232  * set to. If the link has no current store, then we take the global
233  * default.
234  *
235  * May throw @c ExcCLIDMismatch.
236  */
237 template <typename STORABLE>
238 inline
239 void DataLink<STORABLE>::toIdentifiedObject(sgkey_t key,
240  IProxyDict* sg /*= 0*/)
241 {
242  DataLinkBase::toIdentifiedObject (key, classID(), sg);
243 }
244 
245 
246 /**
247  * @brief Set the link to an object given by a hashed key.
248  * @param key Hashed key of the object.
249  * @param ctx Event context for this link.
250  *
251  * May throw @c ExcCLIDMismatch.
252  */
253 template <typename STORABLE>
254 inline
255 void DataLink<STORABLE>::toIdentifiedObject(sgkey_t key,
256  const EventContext& ctx)
257 {
258  DataLinkBase::toIdentifiedObject (key, classID(), Atlas::proxyDictFromEventContext(ctx));
259 }
260 
261 
262 /**
263  * @brief Set the link to the default object of this type.
264  * @param sg Associated store.
265  *
266  * If @c sg is 0, then we take the store from whatever the link's currently
267  * set to. If the link has no current store, then we take the global
268  * default.
269  *
270  * Note that this is _not_ the same as clearing the link
271  * (use @c clear for that). This produces a link that will resolve
272  * to any object in SG of the given type, provided that there is only
273  * one of them. (An attempt to dereference an ambiguous default link
274  * will give an error.)
275  */
276 template <typename STORABLE>
277 inline
278 void DataLink<STORABLE>::toDefaultObject (IProxyDict* sg /*= 0*/)
279 {
280  DataLinkBase::toIdentifiedObject (SG::DEFAULTKEY, classID(), sg);
281 }
282 
283 
284 /**
285  * @brief Set the link to the default object of this type.
286  * @param ctx Event context for this link.
287  *
288  * Note that this is _not_ the same as clearing the link
289  * (use @c clear for that). This produces a link that will resolve
290  * to any object in SG of the given type, provided that there is only
291  * one of them. (An attempt to dereference an ambiguous default link
292  * will give an error.)
293  */
294 template <typename STORABLE>
295 inline
296 void DataLink<STORABLE>::toDefaultObject (const EventContext& ctx)
297 {
298  DataLinkBase::toIdentifiedObject (SG::DEFAULTKEY, classID(),
299  Atlas::proxyDictFromEventContext(ctx));
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::proxyDictFromEventContext(ctx));
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::proxyDictFromEventContext(ctx));
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