1 // This file's extension implies that it's C, but it's really -*- C++ -*-.
4 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
7 /***************************************************************************
8 implementation of DataProxy_cast operator
9 -----------------------------------------
11 ***************************************************************************/
13 // $Id: DataProxy.icc,v 1.6 2008-07-14 22:16:25 calaf Exp $
15 #include "AthenaKernel/DataBucketBase.h"
16 #include "AthenaKernel/StorableConversions.h"
17 #include "AthenaKernel/ClassID_traits.h"
19 # include "AthenaKernel/getMessageSvc.h"
20 # include "GaudiKernel/MsgStream.h"
27 /// Retrieve data object key == string
29 const SG::DataProxy::name_type& SG::DataProxy::name() const
32 return m_tAddress.name();
36 /// Retrieve data object key == string
37 /// duplicated for Gaudi folks does same as name()
39 const SG::DataProxy::id_type& SG::DataProxy::identifier() const
42 return m_tAddress.name();
46 /// Retrieve DataObject
48 DataObject* SG::DataProxy::object ATLAS_NOT_CONST_THREAD_SAFE () const
54 /// Retrieve IOpaqueAddress
56 IOpaqueAddress* SG::DataProxy::address() const
58 lock_t lock (m_mutex);
59 return m_tAddress.address();
63 /// set DataSvc (Gaudi-specific); do nothing for us
65 IDataProviderSvc* SG::DataProxy::dataSvc() const
70 ///< Get the primary (hashed) SG key.
72 SG::sgkey_t SG::DataProxy::sgkey() const
74 // No lock; underlying member is atomic.
75 return m_tAddress.sgkey();
79 /// Set the primary (hashed) SG key.
81 void SG::DataProxy::setSGKey (sgkey_t sgkey)
83 lock_t lock (m_mutex);
84 m_tAddress.setSGKey (sgkey);
88 ///< Return the ID of the store containing this proxy.
90 StoreID::type SG::DataProxy::storeID() const
92 lock_t lock (m_mutex);
93 return m_tAddress.storeID();
97 ///< check if it is a transient ID (primary or symLinked):
99 bool SG::DataProxy::transientID (CLID id) const
101 lock_t lock (m_mutex);
102 return m_tAddress.transientID (id);
106 ///< return the list of transient IDs (primary or symLinked):
108 SG::DataProxy::CLIDCont_t SG::DataProxy::transientID() const
110 lock_t lock (m_mutex);
111 return m_tAddress.transientID();
115 /// Add a new transient ID
117 void SG::DataProxy::setTransientID(CLID id)
119 lock_t lock (m_mutex);
120 m_tAddress.setTransientID (id);
124 /// access set of proxy aliases
125 /// Returns a COPY of the alias set.
127 SG::DataProxy::AliasCont_t SG::DataProxy::alias() const
129 lock_t lock (m_mutex);
130 return m_tAddress.alias();
134 /// Add a new proxy alias.
136 void SG::DataProxy::setAlias(const std::string& key)
138 lock_t lock (m_mutex);
139 m_tAddress.setAlias (key);
143 /// Test to see if a given string is in the alias set.
145 bool SG::DataProxy::hasAlias(const std::string& key) const
147 lock_t lock (m_mutex);
148 const AliasCont_t& alias = m_tAddress.alias();
149 return alias.find(key) != alias.end();
153 /// remove alias from proxy
155 bool SG::DataProxy::removeAlias(const std::string& key)
157 lock_t lock (m_mutex);
158 return m_tAddress.removeAlias (key);
162 /// Return the address provider.
164 IAddressProvider* SG::DataProxy::provider()
166 lock_t lock (m_mutex);
167 return m_tAddress.provider();
171 /// Set the address provider.
173 void SG::DataProxy::setProvider(IAddressProvider* provider,
174 StoreID::type storeID)
176 lock_t lock (m_mutex);
177 m_tAddress.setProvider (provider, storeID);
181 /// Set the CLID / key.
182 /// This will only succeed if the clid/key are currently clear.
184 void SG::DataProxy::setID (CLID id, const std::string& key)
186 lock_t lock (m_mutex);
187 m_tAddress.setID (id, key);
193 bool SG::DataProxy::isValid() const
195 return (isValidObject() || isValidAddress());
199 /// is the object valid?
201 bool SG::DataProxy::isValidObject() const
203 // FIXME: should we try to chase?
204 return (0!= m_dObject);
208 /// Access DataObject on-demand using conversion service
209 ///@throws runtime_error when converter fails
211 DataObject* SG::DataProxy::accessData()
213 // Inlined part: return m_dObject if it's valid.
214 // Otherwise, call the out-of-line part of the code.
215 if (0 != m_dObject) return m_dObject; // cached object
216 return accessDataOol();
221 SG::DataProxy::ErrNo SG::DataProxy::errNo() const
223 lock_t lock (m_objMutex);
230 CLID SG::DataProxy::clID() const
232 // No lock; underlying member is atomic.
233 return m_tAddress.clID();
237 /// Check if it is a const object
239 bool SG::DataProxy::isConst() const
241 // No lock; underlying member is atomic.
246 /// set the reset only flag: Clear Store will reset and not delete.
248 void SG::DataProxy::resetOnly(const bool& flag)
250 lock_t lock (m_mutex);
255 /// Check reset only:
257 bool SG::DataProxy::isResetOnly() const
259 lock_t lock (m_mutex);
264 /// Set the store of which we're a part.
266 void SG::DataProxy::setStore (IProxyDict* store)
271 /// Return the store of which we're a part.
273 IProxyDict* SG::DataProxy::store()
279 /// Return the store of which we're a part.
281 const IProxyDict* SG::DataProxy::store() const
288 IConverter* SG::DataProxy::loader()
290 lock_t lock (m_mutex);
295 template <typename DATA>
296 DATA* SG::DataProxy_cast(SG::DataProxy* proxy) {
299 if (0 != proxy && proxy->isValid()) {
300 DataObject* pObject(proxy->accessData());
303 const CLID& dataID(ClassID_traits<DATA>::ID());
304 result = SG::Storable_cast<DATA>(pObject, true, proxy, proxy->isConst());
306 //if result is 0, probably DATA is neither the type the object was
307 // stored with, nor it inherits from it.
308 // Before giving up let's check its transient CLIDs
309 DataBucketBase* db(0);
310 if (proxy->transientID(dataID) &&
311 0 != (db = dynamic_cast<DataBucketBase*>(pObject)) )
313 //it is a symlink after all. Let's hard cast and keep our fingers Xed
314 // But first: if this is a non-const proxy, then the cast
315 // may have failed because it needed to go via a copying conversion
316 // that's not allowed for non-const objects. So try the conversion
317 // again as const; if that works, then don't do the hard cast.
318 if (!proxy->isConst() &&
319 SG::Storable_cast<DATA>(pObject, true, proxy, true) != 0)
322 MsgStream gLog(Athena::getMessageSvc(), "SG::DataProxy_cast");
324 << "Request for a non-const object via copying conversion; "
325 << "requested CLID = " << dataID
326 << ", proxy primary ID is " << proxy->clID() << endmsg ;
331 result = static_cast<DATA*>(db->object());
336 MsgStream gLog(Athena::getMessageSvc(), "SG::DataProxy_cast");
338 << "Request for an invalid object; requested CLID = "
340 << ", proxy primary ID is " << proxy->clID() << endmsg ;
344 } else { // invalid pObject
346 MsgStream gLog(Athena::getMessageSvc(), "SG::DataProxy_cast");
348 << "this proxy " << MSG::hex << proxy
349 << MSG::dec << " has a NULL data object ptr" << endmsg;
352 } else {// invalid proxy
355 MsgStream gLog(Athena::getMessageSvc(), "SG::DataProxy_cast");
357 << "this proxy " << MSG::hex << proxy
358 << MSG::dec << " [" << proxy->clID() << "/" << proxy->name()
359 << "] is in an invalid state" << endmsg;
367 ///const ref version of the cast. @throws SG::ExcBadDataProxyCast.
368 template<typename DATA>
369 DATA SG::DataProxy_cast(const SG::DataProxy& proxy)
371 const DATA* result = SG::DataProxy_cast<DATA>(&proxy);
372 if (!result) SG::throwExcBadDataProxyCast(proxy.clID(), typeid(DATA));