ATLAS Offline Software
AthLinks/DataLink.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 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/proxyDictFromEventContext.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::proxyDictFromEventContext(ctx))
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::proxyDictFromEventContext(ctx))
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::proxyDictFromEventContext(ctx))
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::proxyDictFromEventContext(ctx))
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::proxyDictFromEventContext(ctx));
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::proxyDictFromEventContext(ctx));
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::proxyDictFromEventContext(ctx));
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(),
300  Atlas::proxyDictFromEventContext(ctx));
301 }
302 
303 
304 /**
305  * @brief Finish initialization after link has been read.
306  * @param sg Associated store.
307  *
308  * This should be called after a link has been read by root
309  * in order to set the proxy pointer.
310  * Returns true.
311  *
312  * If @c sg is 0, then we use the global default store.
313  */
314 template <typename STORABLE>
315 inline
316 bool DataLink<STORABLE>::toTransient (IProxyDict* sg /*= 0*/)
317 {
318  return DataLinkBase::toTransient (sg);
319 }
320 
321 
322 /**
323  * @brief Finish initialization after link has been read.
324  * @param ctx Event context for this link.
325  *
326  * This should be called after a link has been read by root
327  * in order to set the proxy pointer.
328  * Returns true.
329  */
330 template <typename STORABLE>
331 inline
332 bool DataLink<STORABLE>::toTransient (const EventContext& ctx)
333 {
334  return DataLinkBase::toTransient (Atlas::proxyDictFromEventContext(ctx));
335 }
336 
337 
338 /**
339  * @brief Finish initialization like the link as just been read from root,
340  * but with a specified key.
341  * @param dataID Key of the object.
342  * @param sg Associated store.
343  *
344  * The link should be clear before this is called.
345  * Returns true.
346  *
347  * If @c sg is 0, then we use the global default store.
348  */
349 template <typename STORABLE>
350 inline
351 bool DataLink<STORABLE>::toTransient (const ID_type& dataID,
352  IProxyDict* sg /*= 0*/)
353 {
354  return DataLinkBase::toTransient (dataID, classID(), sg);
355 }
356 
357 
358 /**
359  * @brief Finish initialization like the link as just been read from root,
360  * but with a specified key.
361  * @param dataID Key of the object.
362  * @param ctx Event context for this link.
363  *
364  * The link should be clear before this is called.
365  * Returns true.
366  */
367 template <typename STORABLE>
368 inline
369 bool DataLink<STORABLE>::toTransient (const ID_type& dataID,
370  const EventContext& ctx)
371 {
372  return DataLinkBase::toTransient (dataID, classID(), Atlas::proxyDictFromEventContext(ctx));
373 }
374 
375 
376 /**
377  * @brief Return a pointer to the currently-referenced object.
378  * @return A pointer to an object of the type given by @a clid,
379  * or null on a failure (or if the reference is null).
380  */
381 template <typename STORABLE>
382 inline
383 typename DataLink<STORABLE>::const_pointer
384 DataLink<STORABLE>::getDataPtr() const
385 {
386  return reinterpret_cast<const_pointer> (this->storable());
387 }
388 
389 
390 /**
391  * @brief Return a pointer to the currently-referenced object.
392  * @return A pointer to an object of the type given by @a clid,
393  * or null on a failure (or if the reference is null).
394  */
395 template <typename STORABLE>
396 inline
397 typename DataLink<STORABLE>::pointer
398 DataLink<STORABLE>::getDataNonConstPtr()
399 {
400  return reinterpret_cast<pointer> (this->storableNonConst());
401 }
402 
403 
404 /**
405  * @brief Dereference the link.
406  */
407 template< typename STORABLE>
408 inline
409 typename DataLink< STORABLE >::const_reference
410 DataLink< STORABLE >::operator* () const
411 {
412  const_pointer p = this->getDataPtr();
413  if (!p)
414  throwInvalidLink();
415  return *p;
416 }
417 
418 
419 /**
420  * @brief Dereference the link.
421  */
422 template< typename STORABLE>
423 inline
424 typename DataLink< STORABLE >::const_pointer
425 DataLink< STORABLE >::operator->() const
426 {
427  return this->getDataPtr();
428 }
429 
430 
431 /**
432  * @brief Dereference the link.
433  */
434 template< typename STORABLE>
435 inline
436 DataLink<STORABLE>::operator const_pointer() const
437 {
438  return cptr();
439 }
440 
441 
442 /**
443  * @brief Dereference the link.
444  */
445 template< typename STORABLE>
446 inline
447 typename DataLink< STORABLE >::const_pointer
448 DataLink< STORABLE >::cptr() const
449 {
450  return this->getDataPtr();
451 }
452 
453 
454 /**
455  * @brief Test to see if the link is dereferencable.
456  */
457 template <typename STORABLE>
458 inline
459 bool
460 DataLink<STORABLE>::isValid() const
461 {
462  return 0 != getDataPtr();
463 }
464 
465 
466 /**
467  * @brief True if the link is not dereferencable.
468  */
469 template <typename STORABLE>
470 inline
471 bool DataLink<STORABLE>::operator!() const
472 {
473  return !isValid();
474 }
475 
476 
477 /**
478  * @brief Return a (void) pointer to the currently-referenced object.
479  * @return A pointer to an object of the type given by @a clid,
480  * or null on a failure (or if the reference is null).
481  */
482 template <typename STORABLE>
483 inline
484 const void* DataLink<STORABLE>::storable() const
485 {
486  typedef STORABLE* fn_t (SG::DataProxy*);
487  fn_t* fn = &SG::DataProxy_cast<STORABLE>;
488  return this->storableBase (reinterpret_cast<castfn_t*> (fn), classID(), true);
489 }
490 
491 
492 /**
493  * @brief Return a (void) pointer to the currently-referenced object.
494  * @return A pointer to an object of the type given by @a clid,
495  * or null on a failure (or if the reference is null).
496  */
497 template <typename STORABLE>
498 inline
499 void* DataLink<STORABLE>::storableNonConst()
500 {
501  typedef STORABLE* fn_t (SG::DataProxy*);
502  fn_t* fn = &SG::DataProxy_cast<STORABLE>;
503  return this->storableBase (reinterpret_cast<castfn_t*> (fn), classID(), false);
504 }
505 
506 
507 
508