2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
5 * @file AthLinks/tools/DataProxyHolder.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Manage @c DataProxy reference in ElementLink/DataLink.
16 * @brief Default constructor.
21 DataProxyHolder::DataProxyHolder()
28 * @brief Constructor from a holder referencing a different type.
29 * @param other The object from which to copy.
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)
37 template <class FROM_STORABLE, class TO_STORABLE>
38 DataProxyHolder::DataProxyHolder (const DataProxyHolder& other,
39 FROM_STORABLE*, TO_STORABLE*)
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);
47 m_proxy = other.m_proxy;
52 * @brief Reset the link to null.
55 void DataProxyHolder::clear()
62 * @brief Test to see if this is a null link.
65 bool DataProxyHolder::isDefault() const
72 * @brief Return the @c DataProxy for this link.
73 * @param nothrow If true, return 0 on failure instead of throwing
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.
84 SG::DataProxy* DataProxyHolder::proxy (bool nothrow /*= false*/) const
89 // Do the rest out-of-line.
90 return proxy1(nothrow);
95 * @brief Prepare this link for writing.
96 * @param sgkey Reference to the hashed SG key.
97 * @param index Index of this link.
99 * One of the @c toPersistent methods should be called before
100 * trying to write the link with root.
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.
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.
113 bool DataProxyHolder::toPersistent (sgkey_t& sgkey, const T& /*index*/)
115 toPersistentNoRemap (sgkey);
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).
126 bool DataProxyHolder::isObjpointer() const
128 return (reinterpret_cast<unsigned long> (m_proxy) & 1) != 0;
133 * @brief Return a pointer to the object we're pointing at directly.
135 * Should be used only if @c isObjpointer() is true.
138 DataProxyHolder::pointer_t DataProxyHolder::objpointer() const
140 return reinterpret_cast<pointer_t>
141 (reinterpret_cast<unsigned long> (m_proxy) & ~1UL);
146 * @brief Store a direct pointer to an object.
147 * @param p Pointer to the object that we're referencing.
149 * This will overwrite @c m_proxy with the reference to the object.
152 void DataProxyHolder::storeObjpointer (const_pointer_t p)
154 assert ((reinterpret_cast<unsigned long>(p) & 1) == 0);
155 m_proxy = reinterpret_cast<SG::DataProxy*>
156 (reinterpret_cast<unsigned long>(p) | 1);
161 * @brief Return the data source for this reference.
163 * If we're holding a pointer directly, rather than a proxy,
164 * then return 0 rather than raising an exception.
167 IProxyDict* DataProxyHolder::source1()
169 if (!m_proxy || isObjpointer()) {
172 return m_proxy->store();