ATLAS Offline Software
StoreGateSvc.icc
Go to the documentation of this file.
1 /* -*- C++ -*- */
2 
3 /*
4  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 /** @file StoreGateSvc.icc
8  */
9 
10 #ifndef STOREGATE_STOREGATESVC_ICC
11 #define STOREGATE_STOREGATESVC_ICC
12 #include "StoreGate/constraints/KeyConcept.h"
13 #include "SGTools/CallBackID.h"
14 #include "AthContainersInterfaces/AuxStore_traits.h"
15 #include "AthenaKernel/ClassName.h"
16 #include "CxxUtils/checker_macros.h"
17 #include "boost/bind/bind.hpp"
18 #include <vector>
19 
20 /// macro to help writing the function calls.
21 /// first looks if there is a hive slot defined, otherwise forwards to the "serial" implementation
22 #define _SGXCALL(FUN,ARGS,ONERR) \
23  SGImplSvc* impl = this->currentStore(); \
24  if (impl) { \
25  return impl->FUN ARGS; \
26  } \
27  return ONERR;
28 
29 
30 /// macro to help writing the function calls
31 #define _SGVOIDCALL(FUN,ARGS) \
32  SGImplSvc* impl = this->currentStore(); \
33  if (impl) { \
34  impl->FUN ARGS; \
35  }
36 
37 
38 inline
39 StoreID::type
40 StoreGateSvc::storeID() const
41 {
42  return m_storeID;
43 }
44 
45 
46 inline
47 SGImplSvc*
48 StoreGateSvc::currentStore() const {
49  if (m_storeID == StoreID::EVENT_STORE) {
50  SG::HiveEventSlot* slot = currentSlot();
51  if (slot) return slot->pEvtStore;
52  }
53  return m_defaultStore;
54 }
55 
56 
57 inline
58 SG::DataProxy*
59 StoreGateSvc::proxy(const CLID& id, const char* key) const {
60  _SGXCALL( proxy, (id, key), 0 );
61 }
62 
63 inline
64 SG::DataProxy*
65 StoreGateSvc::proxy_exact (SG::sgkey_t sgkey) const {
66  _SGXCALL( proxy_exact, (sgkey), 0 );
67 }
68 
69 template <typename H, typename TKEY>
70 StatusCode
71 StoreGateSvc::regHandle ATLAS_NOT_THREAD_SAFE ( const DataHandle<H>& handle, const TKEY& key )
72 {
73  CLID clid = ClassID_traits<H>::ID();
74  IResetable *ir = const_cast<IResetable*> (static_cast<const IResetable*> (&handle));
75  SG::DataProxy *dp = 0;
76 
77  bool ret = this->currentStore()->bindHandleToProxyAndRegister (clid, key, ir, dp);
78  if (!ret) {
79  return StatusCode::FAILURE;
80  }
81 
82  return handle.setState(dp); // FIXME - should be retrieve?
83 }
84 
85 /// non-const method - will return an error
86 template <typename H, typename TKEY>
87 StatusCode
88 StoreGateSvc::regHandle( DataHandle<H>& /*handle*/, const TKEY& key)
89 {
90  error() << "regHandle(): DataHandle must be const: "
91  << ClassName<H>::name() << "[" + key + "]"
92  << endmsg;
93 
94  return StatusCode::FAILURE;
95 }
96 
97 /// register a callback function, with handle + key
98 template <typename T, typename H, typename TKEY>
99 StatusCode
100 StoreGateSvc::regFcn ATLAS_NOT_THREAD_SAFE (StatusCode (T::*updFcn)(IOVSVC_CALLBACK_ARGS),
101  const T* obj, const DataHandle<H>& handle,
102  const TKEY& key, bool trigger)
103 {
104  CLID clid = ClassID_traits<H>::ID();
105  IResetable *ir = const_cast<IResetable*> (static_cast<const IResetable*> (&handle));
106  SG::DataProxy *dp = 0;
107 
108  const CallBackID c(updFcn,obj);
109  using namespace boost::placeholders;
110  IOVSvcCallBackFcn fcn(boost::bind(updFcn,const_cast<T*>(obj), _1, _2));
111 
112  bool ret = this->currentStore()->bindHandleToProxyAndRegister
113  (clid, key, ir, dp, c, fcn, trigger);
114 
115  if (!ret) {
116  return StatusCode::FAILURE;
117  }
118 
119  return handle.setState(dp); // FIXME - should be retrieve?
120 }
121 
122 /// register a callback function, with handle + key. Non const. Error
123 template <typename T, typename H, typename TKEY>
124 StatusCode
125 StoreGateSvc::regFcn(StatusCode (T::* /*updFcn*/)(IOVSVC_CALLBACK_ARGS),
126  const T* /*obj*/, DataHandle<H>& /*handle*/,
127  const TKEY& key, bool /*trigger*/)
128 {
129  error() << "regHandle(): DataHandle must be const: "
130  << ClassName<H>::name() << "[" + key + "]"
131  << endmsg;
132 
133  return StatusCode::FAILURE;
134 }
135 
136 
137 /// register a callback function(2) with an already registered function(1)
138 template <typename T1, typename T2>
139 StatusCode
140 StoreGateSvc::regFcn ATLAS_NOT_THREAD_SAFE (StatusCode (T1::*fcn1)(IOVSVC_CALLBACK_ARGS),
141  const T1* obj1,
142  StatusCode (T2::*fcn2)(IOVSVC_CALLBACK_ARGS),
143  const T2* obj2, bool trigger)
144 {
145  const CallBackID c1(fcn1, obj1);
146  const CallBackID c2(fcn2, obj2);
147  using namespace boost::placeholders;
148  IOVSvcCallBackFcn fcn( boost::bind(fcn2,const_cast<T2*>(obj2), _1, _2));
149 
150  _SGXCALL( regFcn, (c1, c2, fcn, trigger), StatusCode::FAILURE );
151 }
152 
153 
154 /// register a callback function(2) with an already registered AlgTool
155 template <typename T2>
156 StatusCode
157 StoreGateSvc::regFcn ATLAS_NOT_THREAD_SAFE (const std::string& toolName,
158  StatusCode (T2::*fcn2)(IOVSVC_CALLBACK_ARGS),
159  const T2* obj2, bool trigger)
160 {
161  const CallBackID c2(fcn2, obj2);
162  using namespace boost::placeholders;
163  IOVSvcCallBackFcn fcn( boost::bind(fcn2,const_cast<T2*>(obj2),_1,_2));
164  _SGXCALL( regFcn, (toolName, c2, fcn, trigger), StatusCode::FAILURE );
165 }
166 
167 ///////////////////////////////////////////////////////////////////
168 // create an object and record it with key
169 //////////////////////////////////////////////////////////////////
170 template <typename T, typename TKEY, typename... ARGS>
171 SG::WPtr<T>
172 StoreGateSvc::create(const TKEY& key, ARGS... constructorArgs) {
173  T* pT = new T(constructorArgs...);
174  if(!(this->record(pT, key).isSuccess())) {
175  error() << "create: problem recording created object @"
176  << pT << " using key " << key << endmsg;
177  pT=0; //record will take care of deleting pT even if it fails
178  }
179  return pT;
180 }
181 ///////////////////////////////////////////////////////////////////
182 // record an object with key
183 //////////////////////////////////////////////////////////////////
184 template <typename T, typename TKEY>
185 StatusCode StoreGateSvc::record(T* pObject, const TKEY& key)
186 {
187  const bool ALLOWMODS(true);
188  return record(pObject, key, ALLOWMODS); //allow mods by default
189 }
190 //-------------------------------------------------------------------
191 template <typename T, typename TKEY>
192 StatusCode StoreGateSvc::record(const T* pObject, const TKEY& key)
193 {
194  const bool NOMODS(false);
195  // Ok --- we hold objects as non-const pointers internally, but mark
196  // them as const, so they can only be retrieved as const.
197  T* pObject_nc ATLAS_THREAD_SAFE = const_cast<T*> (pObject);
198  return record(pObject_nc, key, NOMODS); // do not allow mods
199 }
200 
201 //-------------------------------------------------------------------
202 template <typename T, typename TKEY>
203 StatusCode StoreGateSvc::record(T* pObject, const TKEY& key,
204  bool allowMods, bool resetOnly, bool noHist)
205 {
206  return record1 (SG::asStorable<T>(pObject), pObject, key,
207  allowMods, resetOnly, noHist);
208 }
209 
210 
211 //-------------------------------------------------------------------
212 
213 
214 template <typename T, typename TKEY>
215 StatusCode StoreGateSvc::record1(DataObject* obj,
216  T* pObject, const TKEY& key,
217  bool allowMods, bool resetOnly, bool noHist)
218 requires KeyConcept<TKEY>
219 {
220  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
221  rememberBadRecord (ClassID_traits<T>::ID(), key);
222  }
223 
224  // make sure the BaseInfo(Base) structure is initialized
225  SG::BaseInfo<T>::baseinfo();
226 
227  // If s_isConst is set for this type, then we want to automatically
228  // make it const when recorded.
229  if (ClassID_traits<T>::s_isConst)
230  allowMods = false;
231 
232  StatusCode sc = this->currentStore()->typeless_record( obj, key, pObject,
233  allowMods, resetOnly, noHist,
234  &typeid(T));
235 #ifndef NDEBUG
236  if (sc.isSuccess()) {
237  SG_MSG_DEBUG(
238  "Recorded object @" << pObject
239  << " with key " << (std::string)key
240  << " of type " << ClassID_traits<T>::typeName()
241  << "(CLID " << ClassID_traits<T>::ID()
242  << ")\n in DataObject @" << obj
243  << "\n object " << (allowMods ? "" : "not ")
244  << "modifiable when retrieved");
245  }
246 #endif
247 
248  return sc;
249 }
250 
251 
252 //-------------------------------------------------------------------
253 
254 
255 template <typename T, typename TKEY>
256 StatusCode StoreGateSvc::overwrite1(DataObject* obj, T* pObject,
257  const TKEY& key,
258  bool allowMods, bool noHist)
259 requires KeyConcept<TKEY>
260 {
261  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
262  rememberBadRecord (ClassID_traits<T>::ID(), key);
263  }
264 
265  // make sure the BaseInfo(Base) structure is initialized
266  SG::BaseInfo<T>::baseinfo();
267 
268  // If s_isConst is set for this type, then we want to automatically
269  // make it const when recorded.
270  if (ClassID_traits<T>::s_isConst) allowMods = false;
271 
272  StatusCode sc = this->currentStore()->typeless_overwrite(ClassID_traits<T>::ID(),
273  obj, key,
274  pObject, allowMods, noHist,
275  &typeid(T));
276 #ifndef NDEBUG
277  if (sc.isSuccess()) {
278  SG_MSG_DEBUG(
279  "overwrite: Recorded object @" << pObject
280  << " with key " << (std::string)key
281  << " of type " << ClassID_traits<T>::typeName()
282  << "(CLID " << ClassID_traits<T>::ID()
283  << ")\n in DataObject @" << obj
284  << "\n object " << (allowMods ? "" : "not ")
285  << "modifiable when retrieved");
286  }
287 #endif
288  return sc;
289 }
290 
291 //////////////////////////////////////////////////////////////////
292 // Retrieve the default object (with no key) as a const pointer
293 //////////////////////////////////////////////////////////////////
294 template <typename T>
295 StatusCode StoreGateSvc::retrieve(const T*& ptr) const
296 {
297  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
298  rememberBadRetrieve (ClassID_traits<T>::ID(), "");
299  }
300 
301  SG::DataProxy* dp =proxy(ClassID_traits<T>::ID());
302  if (!dp || !dp->isValid()) {
303  warning()
304  << "retrieve(default): No valid proxy for default object \n"
305  << " of type " << ClassID_traits<T>::typeName() << "(CLID "
306  << ClassID_traits<T>::ID() << ')' << endmsg;
307  return StatusCode::FAILURE;
308  }
309  ptr = SG::DataProxy_cast<T> (dp);
310  if (!ptr) {
311  return StatusCode::FAILURE;
312  }
313 
314  //for types with an associated store, try to retrieve it and associate it
315  this->associateAux (ptr, SG::DEFAULTKEY);
316 #ifndef NDEBUG
317  SG_MSG_DEBUG("retrieve(default): Retrieved const pointer to default object \n"
318  << " of type " << ClassID_traits<T>::typeName()
319  << "(CLID " << ClassID_traits<T>::ID() << ')');
320 #endif
321 
322  return StatusCode::SUCCESS;
323 }
324 
325 //////////////////////////////////////////////////////////////////
326 // Retrieve the default object (with no key) as a pointer (non-const)
327 //////////////////////////////////////////////////////////////////
328 template <typename T>
329 StatusCode StoreGateSvc::retrieve(T*& ptr) const
330 {
331  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
332  rememberBadRetrieve (ClassID_traits<T>::ID(), "");
333  }
334 
335  SG::DataProxy* dp =proxy(ClassID_traits<T>::ID());
336  if (!dp || !dp->isValid() || dp->isConst()) {
337  warning()
338  << "retrieve(default): No valid proxy for default object "
339  << " of type " << ClassID_traits<T>::typeName() << "(CLID "
340  << ClassID_traits<T>::ID() << ")\n Try to use a const retrieve "
341  << endmsg;
342  return StatusCode::FAILURE;
343  }
344  ptr = SG::DataProxy_cast<T> (dp);
345  if (!ptr) {
346  return StatusCode::FAILURE;
347  }
348 
349  //for types with an associated store, try to retrieve it and associate it
350  this->associateAux (ptr, SG::DEFAULTKEY);
351 #ifndef NDEBUG
352  SG_MSG_DEBUG("retrieve(default): Retrieved non-const pointer to default object \n"
353  << " of type " << ClassID_traits<T>::typeName()
354  << "(CLID " << ClassID_traits<T>::ID() << ')');
355 #endif
356 
357  return StatusCode::SUCCESS;
358 }
359 
360 //////////////////////////////////////////////////////////////////
361 // Retrieve the keyed object as a const pointer
362 // Overload for std::string key type
363 //////////////////////////////////////////////////////////////////
364 template <typename T>
365 StatusCode StoreGateSvc::retrieve(const T*& ptr, const std::string& key) const
366 {
367  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
368  rememberBadRetrieve (ClassID_traits<T>::ID(), key);
369  }
370 
371  SG::DataProxy* dp =proxy (ClassID_traits<T>::ID(),
372  key,
373  false);
374  if (!dp || !dp->isValid()) {
375  warning()
376  << "retrieve(const): No valid proxy for object " << key << ' '
377  << " of type " << ClassID_traits<T>::typeName() << "(CLID "
378  << ClassID_traits<T>::ID() << ')' << endmsg;
379  return StatusCode::FAILURE;
380  }
381  ptr = SG::DataProxy_cast<T> (dp);
382  if (!ptr) {
383  return StatusCode::FAILURE;
384  }
385 
386  //for types with an associated store, try to retrieve it and associate it
387  this->associateAux (ptr, key);
388 #ifndef NDEBUG
389  SG_MSG_DEBUG( "Retrieved const pointer to object " << key << ' '
390  << " of type " << ClassID_traits<T>::typeName()
391  << "(CLID " << ClassID_traits<T>::ID() << ')');
392 #endif
393 
394  return StatusCode::SUCCESS;
395 }
396 
397 //////////////////////////////////////////////////////////////////
398 // Retrieve the keyed object as a const pointer
399 //////////////////////////////////////////////////////////////////
400 template <typename T, typename TKEY>
401 StatusCode StoreGateSvc::retrieve(const T*& ptr, const TKEY& key) const
402 requires KeyConcept<TKEY>
403 {
404  return this->retrieve(ptr, static_cast<std::string>(key));
405 }
406 
407 //////////////////////////////////////////////////////////////////
408 // Retrieve the keyed object as a non-const pointer
409 // Overload for std::string key type
410 //////////////////////////////////////////////////////////////////
411 template <typename T>
412 StatusCode StoreGateSvc::retrieve(T*& ptr, const std::string& key) const
413 {
414  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
415  rememberBadRetrieve (ClassID_traits<T>::ID(), key);
416  }
417 
418  SG::DataProxy* dp =proxy (ClassID_traits<T>::ID(),
419  key,
420  false);
421  if (!dp || !dp->isValid() || dp->isConst()) {
422  SG_MSG_WARNING("retrieve(non-const): No valid proxy for object "
423  << key << ' '
424  << " of type " << ClassID_traits<T>::typeName() << "(CLID "
425  << ClassID_traits<T>::ID()
426  << ") \n Try to use a const retrieve" );
427  return StatusCode::FAILURE;
428  }
429  ptr = SG::DataProxy_cast<T> (dp);
430  if (!ptr) {
431  return StatusCode::FAILURE;
432  }
433 
434  //for types with an associated store, try to retrieve it and associate it
435  this->associateAux (ptr, key);
436 #ifndef NDEBUG
437  SG_MSG_DEBUG("Retrieved non-const pointer to object " << (std::string)key
438  << ' ' << " of type " << ClassID_traits<T>::typeName()
439  << "(CLID " << ClassID_traits<T>::ID() << ')');
440 #endif
441 
442  return StatusCode::SUCCESS;
443 }
444 
445 //////////////////////////////////////////////////////////////////
446 // Retrieve the keyed object as a non-const pointer
447 //////////////////////////////////////////////////////////////////
448 template <typename T, typename TKEY>
449 StatusCode StoreGateSvc::retrieve(T*& ptr, const TKEY& key) const
450 requires KeyConcept<TKEY>
451 {
452  return this->retrieve(ptr, static_cast<std::string>(key));
453 }
454 
455 /// Retrieve all objects of type T: returns an SG::ConstIterator range
456 template <typename T>
457 StatusCode
458 StoreGateSvc::retrieve(SG::ConstIterator<T>& begin,
459  SG::ConstIterator<T>& end) const {
460  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
461  rememberBadRetrieve (ClassID_traits<T>::ID(), "(iterator)");
462  }
463  _SGXCALL(retrieve, (ClassID_traits<T>::ID(), begin, end), StatusCode::FAILURE);
464 }
465 
466 
467 /**
468  * @brief Retrieve an object of type @c T from StoreGate.
469  * Return 0 if not found.
470  **/
471 
472 template <typename T>
473 T* StoreGateSvc::retrieve () const
474 {
475  T* p = 0;
476  retrieve (p).ignore();
477  return p;
478 }
479 
480 /**`<
481  * @brief Retrieve an object of type @c T from StoreGate.
482  * Return 0 if not found.
483  * @param key The key to use for the lookup.
484  **/
485 template <typename T, class TKEY>
486 T* StoreGateSvc::retrieve (const TKEY& key) const
487 {
488  T* p = 0;
489  retrieve (p, key).ignore();
490  return p;
491 }
492 
493 /**
494  * @brief Retrieve an object of type @c T from StoreGate.
495  * Return 0 if not found.
496  **/
497 template <typename T>
498 T* StoreGateSvc::tryRetrieve () const
499 {
500  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
501  rememberBadRetrieve (ClassID_traits<T>::ID(), "");
502  }
503 
504  SG::DataProxy* dp = proxy (ClassID_traits<T>::ID());
505  if (dp && dp->isValid() && !dp->isConst()) {
506  T* ptr = SG::DataProxy_cast<T> (dp);
507  if (ptr) {
508  this->associateAux (ptr, SG::DEFAULTKEY);
509  return ptr;
510  }
511  }
512  return nullptr;
513 }
514 
515 template <typename T>
516 const T* StoreGateSvc::tryConstRetrieve() const
517 {
518  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
519  rememberBadRetrieve (ClassID_traits<T>::ID(), "");
520  }
521 
522  SG::DataProxy* dp = proxy (ClassID_traits<T>::ID());
523  if (dp && dp->isValid()) {
524  const T* ptr = SG::DataProxy_cast<T> (dp);
525  if (ptr) {
526  this->associateAux (ptr, SG::DEFAULTKEY);
527  return ptr;
528  }
529  }
530  return nullptr;
531 }
532 
533 /**
534  * @brief Retrieve an object of type @c T from StoreGate.
535  * Return 0 if not found. Don't print any WARNINGs
536  * @param key The key to use for the lookup.
537  **/
538 template <typename T, class TKEY>
539 T* StoreGateSvc::tryRetrieve (const TKEY& key) const
540 requires KeyConcept<TKEY>
541 {
542  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
543  rememberBadRetrieve (ClassID_traits<T>::ID(), key);
544  }
545  SG::DataProxy* dp = proxy (ClassID_traits<T>::ID(),
546  static_cast<std::string> (key),
547  false);
548  if (dp && dp->isValid() && !dp->isConst()) {
549  T* ptr = SG::DataProxy_cast<T> (dp);
550  if (ptr) {
551  this->associateAux (ptr, key);
552  return ptr;
553  }
554  }
555  return nullptr;
556 }
557 
558 template <typename T, class TKEY>
559 const T* StoreGateSvc::tryConstRetrieve (const TKEY& key) const
560 requires KeyConcept<TKEY>
561 {
562  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
563  rememberBadRetrieve (ClassID_traits<T>::ID(), key);
564  }
565 
566  SG::DataProxy* dp = proxy (ClassID_traits<T>::ID(),
567  static_cast<std::string> (key),
568  false);
569  if (dp && dp->isValid()) {
570  const T* ptr = SG::DataProxy_cast<T> (dp);
571  if (ptr) {
572  this->associateAux (ptr, key);
573  return ptr;
574  }
575  }
576  return nullptr;
577 }
578 
579 template <typename T>
580 int StoreGateSvc::typeCount() const
581 {
582  return typeCount(ClassID_traits<T>::ID());
583 }
584 
585 
586 template <typename T, typename TKEY>
587 bool
588 StoreGateSvc::contains(const TKEY& key) const
589 {
590  return this->contains(ClassID_traits<T>::ID(), key);
591 }
592 
593 template <typename TKEY>
594 bool
595 StoreGateSvc::contains(const CLID& clid, const TKEY& key) const
596 {
597  _SGXCALL( contains, (clid,key), false );
598 }
599 
600 template <typename T, typename TKEY>
601 bool
602 StoreGateSvc::transientContains(const TKEY& key) const
603 {
604  return transientContains(ClassID_traits<T>::ID(), key);
605 }
606 
607 
608 
609 template <typename TKEY>
610 bool
611 StoreGateSvc::transientContains(const CLID& id, const TKEY& key) const
612 {
613  _SGXCALL(transientContains, (id, key), false);
614 }
615 
616 //-------------------------end of contains methods--------------------
617 template <typename T>
618 void
619 StoreGateSvc::keys(std::vector<std::string>& vkeys,
620  bool includeAlias, bool onlyValid) const {
621  return this->keys(ClassID_traits<T>::ID(), vkeys, includeAlias, onlyValid);
622 }
623 
624 
625 template <typename T, typename TKEY>
626 StatusCode
627 StoreGateSvc::bind ATLAS_NOT_THREAD_SAFE (const DataHandle<T>& handle, const TKEY& key) {
628  CLID clid = ClassID_traits<T>::ID();
629  IResetable *ir = const_cast<IResetable*> (static_cast<const IResetable*> (&handle));
630  SG::DataProxy *dp = 0;
631  bool ret = this->currentStore()->bindHandleToProxy (clid, key, ir, dp);
632  if (!ret) {
633  return StatusCode::FAILURE;
634  }
635 
636  return handle.setState(dp); // FIXME - should be retrieve?
637 }
638 
639 //-------------------------------------------------------------------
640 template <typename T, typename TKEY>
641 StatusCode StoreGateSvc::record(std::unique_ptr<T> pUnique, const TKEY& key)
642 {
643  const bool ALLOWMODS(true);
644  return record(std::move(pUnique), key, ALLOWMODS); //allow mods by default
645 }
646 //-------------------------------------------------------------------
647 template <typename T, typename TKEY>
648 StatusCode StoreGateSvc::record(std::unique_ptr<const T> pUnique,
649  const TKEY& key)
650 {
651  const bool NOMODS(false);
652  // Ok --- we hold objects as non-const pointers internally, but mark
653  // them as const, so they can only be retrieved as const.
654  T* ptr ATLAS_THREAD_SAFE = const_cast<T*> (pUnique.release());
655  return record1(SG::asStorable (ptr), ptr,
656  key, NOMODS); // do not allow mods
657 }
658 
659 //-------------------------------------------------------------------
660 template <typename T, typename TKEY>
661 StatusCode StoreGateSvc::record(std::unique_ptr<T> pUnique, const TKEY& key,
662  bool allowMods, bool resetOnly, bool noHist)
663 {
664  T* ptr = pUnique.get();
665  return record1 (SG::asStorable<T>(std::move(pUnique)), ptr, key,
666  allowMods, resetOnly, noHist);
667 }
668 
669 template <typename T, typename TKEY>
670 StatusCode StoreGateSvc::overwrite(T* p2BRegistered, const TKEY& key)
671 {
672  const bool ALLOWMODS(true);
673  return overwrite(p2BRegistered, key, ALLOWMODS); //SG takes ownership
674 }
675 
676 template <typename T, typename TKEY>
677 StatusCode
678 StoreGateSvc::overwrite(T* pObject, const TKEY& key,
679  bool allowMods, bool noHist)
680 {
681  return overwrite1 (SG::asStorable<T>(pObject), pObject, key,
682  allowMods, noHist);
683 }
684 
685 template <typename T, typename TKEY>
686 StatusCode StoreGateSvc::overwrite(std::unique_ptr<T> pUnique, const TKEY& key)
687 {
688  const bool ALLOWMODS(true);
689  return overwrite(std::move(pUnique), key, ALLOWMODS); //allow mods by default
690 }
691 
692 template <typename T, typename TKEY>
693 StatusCode StoreGateSvc::overwrite(std::unique_ptr<T> pUnique, const TKEY& key,
694  bool allowMods, bool noHist)
695 {
696  T* ptr = pUnique.get();
697  return overwrite1 (SG::asStorable<T>(std::move(pUnique)), ptr, key,
698  allowMods, noHist);
699 }
700 
701 template <typename T, typename AKEY>
702 StatusCode StoreGateSvc::setAlias(const T* pObject, const AKEY& aKey)
703 requires KeyConcept<AKEY>
704 {
705  _SGXCALL(setAlias, (pObject, aKey), StatusCode::FAILURE);
706 }
707 //-------------------------------------------------------------------
708 template <typename T, typename TKEY, typename AKEY>
709 StatusCode
710 StoreGateSvc::setAlias(const T* /*dummy*/,
711  const TKEY& key, const AKEY& aKey)
712 requires KeyConcept<TKEY> && KeyConcept<AKEY>
713 {
714  _SGXCALL(setAlias, (ClassID_traits<T>::ID(), key, aKey), StatusCode::FAILURE);
715 }
716 
717 inline
718 StatusCode
719 StoreGateSvc::setAlias(SG::DataProxy* proxy, const std::string& aliasKey)
720 {
721  _SGXCALL(setAlias, (proxy, aliasKey), StatusCode::FAILURE);
722 }
723 
724 //////////////////////////////////////////////////////////////////
725 // Make a soft link to the object with key: return non_const link
726 //////////////////////////////////////////////////////////////////
727 template <typename T, typename TLINK>
728 StatusCode
729 StoreGateSvc::symLink(const T* pObject, TLINK* /*dummy*/)
730 {
731  _SGXCALL(symLink, (pObject, ClassID_traits<TLINK>::ID()), StatusCode::FAILURE);
732 }
733 
734 //////////////////////////////////////////////////////////////////
735 // Make a soft link to the object with key: set const link
736 //////////////////////////////////////////////////////////////////
737 template <typename T, typename TLINK>
738 StatusCode
739 StoreGateSvc::symLink(const T* pObject, const TLINK* /*dummy*/)
740 {
741  _SGXCALL(symLink, (pObject, ClassID_traits<TLINK>::ID()), StatusCode::FAILURE);
742 }
743 
744 template <KeyConcept TKEY>
745 StatusCode
746 StoreGateSvc::symLink(const CLID id, const TKEY& key, const CLID linkid)
747 {
748  _SGXCALL(symLink, (id, key, linkid), StatusCode::FAILURE);
749 }
750 
751 
752 /// Remove pObject, will remove its proxy if not reset only.
753 template <typename T>
754 StatusCode
755 StoreGateSvc::remove(const T* pObject) {
756  _SGXCALL(remove, (pObject), StatusCode::FAILURE);
757 }
758 
759 /// Remove pObject and its proxy no matter what.
760 template <typename T>
761 StatusCode
762 StoreGateSvc::removeDataAndProxy(const T* pObject) {
763  _SGXCALL(removeDataAndProxy, (pObject), StatusCode::FAILURE);
764 }
765 
766 template <typename T, class TKEY>
767 StatusCode
768 StoreGateSvc::retrieveHighestVersion(SG::ObjectWithVersion<T>& dobjWithVersion,
769  const TKEY& requestedKey) const
770 {
771  std::list< SG::ObjectWithVersion<T> > allVersions;
772  StatusCode sc(this->retrieveAllVersions(allVersions,requestedKey));
773  if (sc.isSuccess()) {
774  allVersions.sort(); // on highest version number
775  dobjWithVersion.versionedKey.copyVK(allVersions.back().versionedKey.rawVersionKey());
776  }
777  return sc;
778 }
779 
780 template <typename T, class TKEY>
781 StatusCode
782 StoreGateSvc::retrieveAllVersions(std::list< SG::ObjectWithVersion<T> >& allVersions,
783  const TKEY& requestedKey) const
784 {
785  StatusCode sc(StatusCode::FAILURE);
786  SG::ConstIterator<T> i,e;
787  if ((this->retrieve<T>(i,e)).isSuccess()){
788  SG::VersionedKey reqVK(requestedKey);
789  while (i != e) {
790  SG::VersionedKey vk(i.key());
791  if (reqVK.sameKey(vk)) {
792  sc = StatusCode::SUCCESS;
793  SG::ObjectWithVersion<T> okOWV(vk, i.proxy());
794  allVersions.push_back(okOWV);
795  }
796  ++i;
797  }
798  }
799  return sc;
800 }
801 
802 
803 template <typename T>
804 std::unique_ptr<T>
805 StoreGateSvc::retrieveUniquePrivateCopy (const std::string& key)
806 {
807  CLID clid = ClassID_traits<T>::ID();
808  DataObject* obj = this->currentStore()->typeless_retrievePrivateCopy(clid, key);
809  std::unique_ptr<T> ret (SG::Storable_cast<T>(obj));
810  if (DataBucketBase* dbb = dynamic_cast<DataBucketBase*> (obj))
811  {
812  dbb->relinquish();
813  }
814  obj->release();
815  return ret;
816 }
817 
818 //////////////////////////////////////////////////////////////////
819 // Retrieve the @c CLID of a given "key"
820 // WARNING: slow!
821 //////////////////////////////////////////////////////////////////
822 template<typename TKEY>
823 CLID
824 StoreGateSvc::clid( const TKEY& key ) const
825 {
826  _SGXCALL(clid, (key), CLID_NULL);
827 }
828 
829 //////////////////////////////////////////////////////////////////
830 // Retrieve the @c CLID s of a given "key"
831 // WARNING: slow!
832 //////////////////////////////////////////////////////////////////
833 template<typename TKEY>
834 std::vector<CLID>
835 StoreGateSvc::clids( const TKEY& key ) const
836 {
837  std::vector<CLID> nullV;
838  _SGXCALL(clids, (key), nullV);
839 }
840 
841 ///////////////////////////////////////////////////////////////////////////
842 
843 inline
844 void
845 StoreGateSvc::setProxyProviderSvc(IProxyProviderSvc* pPPSvc) {
846  _SGVOIDCALL(setProxyProviderSvc, (pPPSvc));
847 }
848 
849 
850 inline
851 IProxyProviderSvc*
852 StoreGateSvc::proxyProviderSvc() {
853  _SGXCALL(proxyProviderSvc, (), nullptr);
854 }
855 
856 
857 /**
858  * @brief Return the metadata source ID for the current event slot.
859  * @param key SG key of the DataHeader to query.
860  * Returns an empty string if no source has been set.
861  *
862  * The default version always returns an empty string.
863  */
864 inline
865 SG::SourceID
866 StoreGateSvc::sourceID (const std::string& key /*= "EventSelector"*/) const {
867  _SGXCALL(sourceID, (key), "");
868 }
869 
870 
871 template <class TKEY>
872 void
873 StoreGateSvc::remap (CLID clid,
874  const TKEY& source,
875  const TKEY& target,
876  off_t index_offset) {
877  _SGVOIDCALL(remap_impl, (this->stringToKey (source, clid),
878  this->stringToKey (target, clid),
879  index_offset));
880 }
881 
882 
883 /**
884  * @brief Remember that retrieve() was called for a MT store.
885  * @param clid CLID of the operation.
886  * @param key Key of the operation.
887  */
888 inline
889 void StoreGateSvc::rememberBadRetrieve (CLID clid, const std::string& key) const
890 {
891  rememberBad (m_badRetrieves, clid, key);
892 }
893 
894 
895 /**
896  * @brief Remember that retrieve() was called for a MT store.
897  * @param clid CLID of the operation.
898  * @param key Key of the operation.
899  */
900 inline
901 void StoreGateSvc::rememberBadRecord (CLID clid, const std::string& key) const
902 {
903  rememberBad (m_badRecords, clid, key);
904 }
905 
906 
907 template <class DOBJ, class AUXSTORE>
908 bool StoreGateSvc::associateAux_impl (DOBJ* ptr,
909  const std::string& key,
910  const AUXSTORE*) const
911 {
912  CLID auxclid = ClassID_traits<AUXSTORE>::ID();
913  _SGXCALL( associateAux_impl, (ptr, key, auxclid), false);
914 }
915 
916 
917 template <class DOBJ>
918 bool StoreGateSvc::associateAux_impl (DOBJ* /*ptr*/,
919  const std::string& /*key*/,
920  const SG::NoAuxStore*) const
921 {
922  return true;
923 }
924 
925 
926 /**
927  * @brief associate a data object to its auxiliary store
928  * Return false if the aux store is not found.
929  * @param key The key to use for the lookup.
930  **/
931 template <class DOBJ>
932 bool StoreGateSvc::associateAux (DOBJ* ptr,
933  const std::string& key,
934  bool ignoreMissing) const
935 {
936  typename SG::AuxStore_traits<DOBJ>::type* pDummy(0); //used to pass down auxstore type
937  bool hasAux=associateAux_impl(ptr, key, pDummy) || ignoreMissing;
938  if (!hasAux) SG_MSG_WARNING("associateAux const: Could not associate AuxStore of type "
939  << SG::AuxStore_traits<DOBJ>::const_typeName()
940  << "\n to object of type " << ClassID_traits<DOBJ>::typeName() << "(CLID "
941  << ClassID_traits<DOBJ>::ID() << ") with key " << key << endmsg);
942  return hasAux;
943 }
944 
945 
946 template <class DOBJ>
947 bool StoreGateSvc::associateAux (const DOBJ* ptr,
948  const std::string& key,
949  bool ignoreMissing) const
950 {
951  typename SG::AuxStore_traits<DOBJ>::const_type* pDummy(0); //used to pass down auxstore type
952  // Should generally be ok, since any actual modification is done
953  // inside the store lock. Still kind of a wart that we still do this, though.
954  DOBJ* ptr_nc ATLAS_THREAD_SAFE = const_cast<DOBJ*> (ptr);
955  bool hasAux=associateAux_impl(ptr_nc, key, pDummy) || ignoreMissing;
956  if (!hasAux) SG_MSG_WARNING("associateAux const: Could not associate AuxStore of type "
957  << SG::AuxStore_traits<DOBJ>::const_typeName()
958  << "\n to object of type " << ClassID_traits<DOBJ>::typeName() << "(CLID "
959  << ClassID_traits<DOBJ>::ID() << ") with key " << key << endmsg);
960  return hasAux;
961 }
962 
963 
964 #endif //STOREGATE_STOREGATESVC_ICC