ATLAS Offline Software
DataProxyHolder.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 /**
5  * @file AthLinks/tools/DataProxyHolder.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Mar, 2014
8  * @brief Manage @c DataProxy reference in ElementLink/DataLink.
9  */
10 
11 
12 namespace SG {
13 
14 
15 /**
16  * @brief Default constructor.
17  *
18  * Make a null link.
19  */
20 inline
21 DataProxyHolder::DataProxyHolder()
22  : m_proxy(0)
23 {
24 }
25 
26 
27 /**
28  * @brief Constructor from a holder referencing a different type.
29  * @param other The object from which to copy.
30  *
31  * @c FROM_STORABLE is the storable class to which @c other refers;
32  * @c TO_STORABLE is the storable class for this object.
33  * The actual pointer values are not used, just the types are used.
34  * Default conversions for the storable pointer (i.e., derived->base)
35  * are allowed.
36  */
37 template <class FROM_STORABLE, class TO_STORABLE>
38 DataProxyHolder::DataProxyHolder (const DataProxyHolder& other,
39  FROM_STORABLE*, TO_STORABLE*)
40 {
41  if (other.isObjpointer()) {
42  FROM_STORABLE* from_ptr = reinterpret_cast<FROM_STORABLE*>(other.objpointer());
43  TO_STORABLE* to_ptr = from_ptr;
44  storeObjpointer (to_ptr);
45  }
46  else
47  m_proxy = other.m_proxy;
48 }
49 
50 
51 /**
52  * @brief Reset the link to null.
53  */
54 inline
55 void DataProxyHolder::clear()
56 {
57  m_proxy = 0;
58 }
59 
60 
61 /**
62  * @brief Test to see if this is a null link.
63  */
64 inline
65 bool DataProxyHolder::isDefault() const
66 {
67  return m_proxy == 0;
68 }
69 
70 
71 /**
72  * @brief Return the @c DataProxy for this link.
73  * @param nothrow If true, return 0 on failure instead of throwing
74  * an exception.
75  *
76  * If this is a null link, we return 0.
77  * Otherwise, if we're pointing at a @c DataProxy, return it.
78  * Otherwise, we're pointing at an object directly. Try to look up
79  * the corresponding @c DataProxy using the default store. Return it
80  * if we find it; otherwise, either throw @c ExcPointerNotInSG or
81  * return 0, depending on the @c nothrow parameter.
82  */
83 inline
84 SG::DataProxy* DataProxyHolder::proxy (bool nothrow /*= false*/) const
85 {
86  if (!isObjpointer())
87  return m_proxy;
88 
89  // Do the rest out-of-line.
90  return proxy1(nothrow);
91 }
92 
93 
94 /**
95  * @brief Prepare this link for writing.
96  * @param sgkey Reference to the hashed SG key.
97  * @param index Index of this link.
98  *
99  * One of the @c toPersistent methods should be called before
100  * trying to write the link with root.
101  *
102  * This takes a reference to the hashed SG key. In the case where we're
103  * referencing an object directly by pointer, the hashed key will be 0.
104  * In that case, we try to look up the object in the default store.
105  * If we find it, the hashed key is updated appropriately; otherwise,
106  * we throw @c ExcPointerNotInSG.
107  *
108  * This version is for the case where indices are not given by @c size_t.
109  * No remapping will be performed for this case; this function will
110  * always return false.
111  */
112 template <class T>
113 bool DataProxyHolder::toPersistent (sgkey_t& sgkey, const T& /*index*/)
114 {
115  toPersistentNoRemap (sgkey);
116  return false;
117 }
118 
119 
120 /**
121  * @brief Test to see if we're pointing directly at an object.
122  * @returns True if we're pointing directly at an object, false
123  * if we're pointing at a @c DataProxy (or the link is null).
124  */
125 inline
126 bool DataProxyHolder::isObjpointer() const
127 {
128  return (reinterpret_cast<unsigned long> (m_proxy) & 1) != 0;
129 }
130 
131 
132 /**
133  * @brief Return a pointer to the object we're pointing at directly.
134  *
135  * Should be used only if @c isObjpointer() is true.
136  */
137 inline
138 DataProxyHolder::pointer_t DataProxyHolder::objpointer() const
139 {
140  return reinterpret_cast<pointer_t>
141  (reinterpret_cast<unsigned long> (m_proxy) & ~1UL);
142 }
143 
144 
145 /**
146  * @brief Store a direct pointer to an object.
147  * @param p Pointer to the object that we're referencing.
148  *
149  * This will overwrite @c m_proxy with the reference to the object.
150  */
151 inline
152 void DataProxyHolder::storeObjpointer (const_pointer_t p)
153 {
154  assert ((reinterpret_cast<unsigned long>(p) & 1) == 0);
155  m_proxy = reinterpret_cast<SG::DataProxy*>
156  (reinterpret_cast<unsigned long>(p) | 1);
157 }
158 
159 
160 /**
161  * @brief Return the data source for this reference.
162  *
163  * If we're holding a pointer directly, rather than a proxy,
164  * then return 0 rather than raising an exception.
165  */
166 inline
167 IProxyDict* DataProxyHolder::source1()
168 {
169  if (!m_proxy || isObjpointer()) {
170  return 0;
171  }
172  return m_proxy->store();
173 }
174 
175 
176 } // namespace SG