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 {
219  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
220  rememberBadRecord (ClassID_traits<T>::ID(), key);
221  }
222 
223 #ifndef __clang__
224  BOOST_CONCEPT_ASSERT( (KeyConcept<TKEY>) );
225 #endif
226  // make sure the BaseInfo(Base) structure is initialized
227  SG::BaseInfo<T>::baseinfo();
228 
229  // If s_isConst is set for this type, then we want to automatically
230  // make it const when recorded.
231  if (ClassID_traits<T>::s_isConst)
232  allowMods = false;
233 
234  StatusCode sc = this->currentStore()->typeless_record( obj, key, pObject,
235  allowMods, resetOnly, noHist,
236  &typeid(T));
237 #ifndef NDEBUG
238  if (sc.isSuccess()) {
239  SG_MSG_DEBUG(
240  "Recorded object @" << pObject
241  << " with key " << (std::string)key
242  << " of type " << ClassID_traits<T>::typeName()
243  << "(CLID " << ClassID_traits<T>::ID()
244  << ")\n in DataObject @" << obj
245  << "\n object " << (allowMods ? "" : "not ")
246  << "modifiable when retrieved");
247  }
248 #endif
249 
250  return sc;
251 }
252 
253 
254 //-------------------------------------------------------------------
255 
256 
257 template <typename T, typename TKEY>
258 StatusCode StoreGateSvc::overwrite1(DataObject* obj, T* pObject,
259  const TKEY& key,
260  bool allowMods, bool noHist)
261 {
262  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
263  rememberBadRecord (ClassID_traits<T>::ID(), key);
264  }
265 
266 #ifndef __clang__
267  BOOST_CONCEPT_ASSERT( (KeyConcept<TKEY>) );
268 #endif
269  // make sure the BaseInfo(Base) structure is initialized
270  SG::BaseInfo<T>::baseinfo();
271 
272  // If s_isConst is set for this type, then we want to automatically
273  // make it const when recorded.
274  if (ClassID_traits<T>::s_isConst) allowMods = false;
275 
276  StatusCode sc = this->currentStore()->typeless_overwrite(ClassID_traits<T>::ID(),
277  obj, key,
278  pObject, allowMods, noHist,
279  &typeid(T));
280 #ifndef NDEBUG
281  if (sc.isSuccess()) {
282  SG_MSG_DEBUG(
283  "overwrite: Recorded object @" << pObject
284  << " with key " << (std::string)key
285  << " of type " << ClassID_traits<T>::typeName()
286  << "(CLID " << ClassID_traits<T>::ID()
287  << ")\n in DataObject @" << obj
288  << "\n object " << (allowMods ? "" : "not ")
289  << "modifiable when retrieved");
290  }
291 #endif
292  return sc;
293 }
294 
295 //////////////////////////////////////////////////////////////////
296 // Retrieve the default object (with no key) as a const pointer
297 //////////////////////////////////////////////////////////////////
298 template <typename T>
299 StatusCode StoreGateSvc::retrieve(const T*& ptr) const
300 {
301  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
302  rememberBadRetrieve (ClassID_traits<T>::ID(), "");
303  }
304 
305  SG::DataProxy* dp =proxy(ClassID_traits<T>::ID());
306  if (!dp || !dp->isValid()) {
307  warning()
308  << "retrieve(default): No valid proxy for default object \n"
309  << " of type " << ClassID_traits<T>::typeName() << "(CLID "
310  << ClassID_traits<T>::ID() << ')' << endmsg;
311  return StatusCode::FAILURE;
312  }
313  ptr = SG::DataProxy_cast<T> (dp);
314  if (!ptr) {
315  return StatusCode::FAILURE;
316  }
317 
318  //for types with an associated store, try to retrieve it and associate it
319  this->associateAux (ptr, SG::DEFAULTKEY);
320 #ifndef NDEBUG
321  SG_MSG_DEBUG("retrieve(default): Retrieved const pointer to default object \n"
322  << " of type " << ClassID_traits<T>::typeName()
323  << "(CLID " << ClassID_traits<T>::ID() << ')');
324 #endif
325 
326  return StatusCode::SUCCESS;
327 }
328 
329 //////////////////////////////////////////////////////////////////
330 // Retrieve the default object (with no key) as a pointer (non-const)
331 //////////////////////////////////////////////////////////////////
332 template <typename T>
333 StatusCode StoreGateSvc::retrieve(T*& ptr) const
334 {
335  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
336  rememberBadRetrieve (ClassID_traits<T>::ID(), "");
337  }
338 
339  SG::DataProxy* dp =proxy(ClassID_traits<T>::ID());
340  if (!dp || !dp->isValid() || dp->isConst()) {
341  warning()
342  << "retrieve(default): No valid proxy for default object "
343  << " of type " << ClassID_traits<T>::typeName() << "(CLID "
344  << ClassID_traits<T>::ID() << ")\n Try to use a const retrieve "
345  << endmsg;
346  return StatusCode::FAILURE;
347  }
348  ptr = SG::DataProxy_cast<T> (dp);
349  if (!ptr) {
350  return StatusCode::FAILURE;
351  }
352 
353  //for types with an associated store, try to retrieve it and associate it
354  this->associateAux (ptr, SG::DEFAULTKEY);
355 #ifndef NDEBUG
356  SG_MSG_DEBUG("retrieve(default): Retrieved non-const pointer to default object \n"
357  << " of type " << ClassID_traits<T>::typeName()
358  << "(CLID " << ClassID_traits<T>::ID() << ')');
359 #endif
360 
361  return StatusCode::SUCCESS;
362 }
363 
364 //////////////////////////////////////////////////////////////////
365 // Retrieve the keyed object as a const pointer
366 // Overload for std::string key type
367 //////////////////////////////////////////////////////////////////
368 template <typename T>
369 StatusCode StoreGateSvc::retrieve(const T*& ptr, const std::string& key) const
370 {
371  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
372  rememberBadRetrieve (ClassID_traits<T>::ID(), key);
373  }
374 
375  SG::DataProxy* dp =proxy (ClassID_traits<T>::ID(),
376  key,
377  false);
378  if (!dp || !dp->isValid()) {
379  warning()
380  << "retrieve(const): No valid proxy for object " << key << ' '
381  << " of type " << ClassID_traits<T>::typeName() << "(CLID "
382  << ClassID_traits<T>::ID() << ')' << endmsg;
383  return StatusCode::FAILURE;
384  }
385  ptr = SG::DataProxy_cast<T> (dp);
386  if (!ptr) {
387  return StatusCode::FAILURE;
388  }
389 
390  //for types with an associated store, try to retrieve it and associate it
391  this->associateAux (ptr, key);
392 #ifndef NDEBUG
393  SG_MSG_DEBUG( "Retrieved const pointer to object " << key << ' '
394  << " of type " << ClassID_traits<T>::typeName()
395  << "(CLID " << ClassID_traits<T>::ID() << ')');
396 #endif
397 
398  return StatusCode::SUCCESS;
399 }
400 
401 //////////////////////////////////////////////////////////////////
402 // Retrieve the keyed object as a const pointer
403 //////////////////////////////////////////////////////////////////
404 template <typename T, typename TKEY>
405 StatusCode StoreGateSvc::retrieve(const T*& ptr, const TKEY& key) const
406 {
407 #ifndef __clang__
408  BOOST_CONCEPT_ASSERT( (KeyConcept<TKEY>) );
409 #endif
410  return this->retrieve(ptr, static_cast<std::string>(key));
411 }
412 
413 //////////////////////////////////////////////////////////////////
414 // Retrieve the keyed object as a non-const pointer
415 // Overload for std::string key type
416 //////////////////////////////////////////////////////////////////
417 template <typename T>
418 StatusCode StoreGateSvc::retrieve(T*& ptr, const std::string& key) const
419 {
420  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
421  rememberBadRetrieve (ClassID_traits<T>::ID(), key);
422  }
423 
424  SG::DataProxy* dp =proxy (ClassID_traits<T>::ID(),
425  key,
426  false);
427  if (!dp || !dp->isValid() || dp->isConst()) {
428  SG_MSG_WARNING("retrieve(non-const): No valid proxy for object "
429  << key << ' '
430  << " of type " << ClassID_traits<T>::typeName() << "(CLID "
431  << ClassID_traits<T>::ID()
432  << ") \n Try to use a const retrieve" );
433  return StatusCode::FAILURE;
434  }
435  ptr = SG::DataProxy_cast<T> (dp);
436  if (!ptr) {
437  return StatusCode::FAILURE;
438  }
439 
440  //for types with an associated store, try to retrieve it and associate it
441  this->associateAux (ptr, key);
442 #ifndef NDEBUG
443  SG_MSG_DEBUG("Retrieved non-const pointer to object " << (std::string)key
444  << ' ' << " of type " << ClassID_traits<T>::typeName()
445  << "(CLID " << ClassID_traits<T>::ID() << ')');
446 #endif
447 
448  return StatusCode::SUCCESS;
449 }
450 
451 //////////////////////////////////////////////////////////////////
452 // Retrieve the keyed object as a non-const pointer
453 //////////////////////////////////////////////////////////////////
454 template <typename T, typename TKEY>
455 StatusCode StoreGateSvc::retrieve(T*& ptr, const TKEY& key) const
456 {
457 #ifndef __clang__
458  BOOST_CONCEPT_ASSERT( (KeyConcept<TKEY>) );
459 #endif
460  return this->retrieve(ptr, static_cast<std::string>(key));
461 }
462 
463 /// Retrieve all objects of type T: returns an SG::ConstIterator range
464 template <typename T>
465 StatusCode
466 StoreGateSvc::retrieve(SG::ConstIterator<T>& begin,
467  SG::ConstIterator<T>& end) const {
468  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
469  rememberBadRetrieve (ClassID_traits<T>::ID(), "(iterator)");
470  }
471  _SGXCALL(retrieve, (ClassID_traits<T>::ID(), begin, end), StatusCode::FAILURE);
472 }
473 
474 
475 /**
476  * @brief Retrieve an object of type @c T from StoreGate.
477  * Return 0 if not found.
478  **/
479 
480 template <typename T>
481 T* StoreGateSvc::retrieve () const
482 {
483  T* p = 0;
484  retrieve (p).ignore();
485  return p;
486 }
487 
488 /**`<
489  * @brief Retrieve an object of type @c T from StoreGate.
490  * Return 0 if not found.
491  * @param key The key to use for the lookup.
492  **/
493 template <typename T, class TKEY>
494 T* StoreGateSvc::retrieve (const TKEY& key) const
495 {
496  T* p = 0;
497  retrieve (p, key).ignore();
498  return p;
499 }
500 
501 /**
502  * @brief Retrieve an object of type @c T from StoreGate.
503  * Return 0 if not found.
504  **/
505 template <typename T>
506 T* StoreGateSvc::tryRetrieve () const
507 {
508  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
509  rememberBadRetrieve (ClassID_traits<T>::ID(), "");
510  }
511 
512  SG::DataProxy* dp = proxy (ClassID_traits<T>::ID());
513  if (dp && dp->isValid() && !dp->isConst()) {
514  T* ptr = SG::DataProxy_cast<T> (dp);
515  if (ptr) {
516  this->associateAux (ptr, SG::DEFAULTKEY);
517  return ptr;
518  }
519  }
520  return nullptr;
521 }
522 
523 template <typename T>
524 const T* StoreGateSvc::tryConstRetrieve() const
525 {
526  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
527  rememberBadRetrieve (ClassID_traits<T>::ID(), "");
528  }
529 
530  SG::DataProxy* dp = proxy (ClassID_traits<T>::ID());
531  if (dp && dp->isValid()) {
532  const T* ptr = SG::DataProxy_cast<T> (dp);
533  if (ptr) {
534  this->associateAux (ptr, SG::DEFAULTKEY);
535  return ptr;
536  }
537  }
538  return nullptr;
539 }
540 
541 /**
542  * @brief Retrieve an object of type @c T from StoreGate.
543  * Return 0 if not found. Don't print any WARNINGs
544  * @param key The key to use for the lookup.
545  **/
546 template <typename T, class TKEY>
547 T* StoreGateSvc::tryRetrieve (const TKEY& key) const
548 {
549  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
550  rememberBadRetrieve (ClassID_traits<T>::ID(), key);
551  }
552 #ifndef __clang__
553  BOOST_CONCEPT_ASSERT( (KeyConcept<TKEY>) );
554 #endif
555  SG::DataProxy* dp = proxy (ClassID_traits<T>::ID(),
556  static_cast<std::string> (key),
557  false);
558  if (dp && dp->isValid() && !dp->isConst()) {
559  T* ptr = SG::DataProxy_cast<T> (dp);
560  if (ptr) {
561  this->associateAux (ptr, key);
562  return ptr;
563  }
564  }
565  return nullptr;
566 }
567 
568 template <typename T, class TKEY>
569 const T* StoreGateSvc::tryConstRetrieve (const TKEY& key) const
570 {
571  if (m_storeID == StoreID::EVENT_STORE && currentSlot() != nullptr) {
572  rememberBadRetrieve (ClassID_traits<T>::ID(), key);
573  }
574 
575 #ifndef __clang__
576  BOOST_CONCEPT_ASSERT( (KeyConcept<TKEY>) );
577 #endif
578  SG::DataProxy* dp = proxy (ClassID_traits<T>::ID(),
579  static_cast<std::string> (key),
580  false);
581  if (dp && dp->isValid()) {
582  const T* ptr = SG::DataProxy_cast<T> (dp);
583  if (ptr) {
584  this->associateAux (ptr, key);
585  return ptr;
586  }
587  }
588  return nullptr;
589 }
590 
591 template <typename T>
592 int StoreGateSvc::typeCount() const
593 {
594  return typeCount(ClassID_traits<T>::ID());
595 }
596 
597 
598 template <typename T, typename TKEY>
599 bool
600 StoreGateSvc::contains(const TKEY& key) const
601 {
602  return this->contains(ClassID_traits<T>::ID(), key);
603 }
604 
605 template <typename TKEY>
606 bool
607 StoreGateSvc::contains(const CLID& clid, const TKEY& key) const
608 {
609  _SGXCALL( contains, (clid,key), false );
610 }
611 
612 template <typename T, typename TKEY>
613 bool
614 StoreGateSvc::transientContains(const TKEY& key) const
615 {
616  return transientContains(ClassID_traits<T>::ID(), key);
617 }
618 
619 
620 
621 template <typename TKEY>
622 bool
623 StoreGateSvc::transientContains(const CLID& id, const TKEY& key) const
624 {
625  _SGXCALL(transientContains, (id, key), false);
626 }
627 
628 //-------------------------end of contains methods--------------------
629 template <typename T>
630 void
631 StoreGateSvc::keys(std::vector<std::string>& vkeys,
632  bool includeAlias, bool onlyValid) const {
633  return this->keys(ClassID_traits<T>::ID(), vkeys, includeAlias, onlyValid);
634 }
635 
636 
637 template <typename T, typename TKEY>
638 StatusCode
639 StoreGateSvc::bind ATLAS_NOT_THREAD_SAFE (const DataHandle<T>& handle, const TKEY& key) {
640  CLID clid = ClassID_traits<T>::ID();
641  IResetable *ir = const_cast<IResetable*> (static_cast<const IResetable*> (&handle));
642  SG::DataProxy *dp = 0;
643  bool ret = this->currentStore()->bindHandleToProxy (clid, key, ir, dp);
644  if (!ret) {
645  return StatusCode::FAILURE;
646  }
647 
648  return handle.setState(dp); // FIXME - should be retrieve?
649 }
650 
651 //-------------------------------------------------------------------
652 template <typename T, typename TKEY>
653 StatusCode StoreGateSvc::record(std::unique_ptr<T> pUnique, const TKEY& key)
654 {
655  const bool ALLOWMODS(true);
656  return record(std::move(pUnique), key, ALLOWMODS); //allow mods by default
657 }
658 //-------------------------------------------------------------------
659 template <typename T, typename TKEY>
660 StatusCode StoreGateSvc::record(std::unique_ptr<const T> pUnique,
661  const TKEY& key)
662 {
663  const bool NOMODS(false);
664  // Ok --- we hold objects as non-const pointers internally, but mark
665  // them as const, so they can only be retrieved as const.
666  T* ptr ATLAS_THREAD_SAFE = const_cast<T*> (pUnique.release());
667  return record1(SG::asStorable (ptr), ptr,
668  key, NOMODS); // do not allow mods
669 }
670 
671 //-------------------------------------------------------------------
672 template <typename T, typename TKEY>
673 StatusCode StoreGateSvc::record(std::unique_ptr<T> pUnique, const TKEY& key,
674  bool allowMods, bool resetOnly, bool noHist)
675 {
676  T* ptr = pUnique.get();
677  return record1 (SG::asStorable<T>(std::move(pUnique)), ptr, key,
678  allowMods, resetOnly, noHist);
679 }
680 
681 template <typename T, typename TKEY>
682 StatusCode StoreGateSvc::overwrite(T* p2BRegistered, const TKEY& key)
683 {
684  const bool ALLOWMODS(true);
685  return overwrite(p2BRegistered, key, ALLOWMODS); //SG takes ownership
686 }
687 
688 template <typename T, typename TKEY>
689 StatusCode
690 StoreGateSvc::overwrite(T* pObject, const TKEY& key,
691  bool allowMods, bool noHist)
692 {
693  return overwrite1 (SG::asStorable<T>(pObject), pObject, key,
694  allowMods, noHist);
695 }
696 
697 template <typename T, typename TKEY>
698 StatusCode StoreGateSvc::overwrite(std::unique_ptr<T> pUnique, const TKEY& key)
699 {
700  const bool ALLOWMODS(true);
701  return overwrite(std::move(pUnique), key, ALLOWMODS); //allow mods by default
702 }
703 
704 template <typename T, typename TKEY>
705 StatusCode StoreGateSvc::overwrite(std::unique_ptr<T> pUnique, const TKEY& key,
706  bool allowMods, bool noHist)
707 {
708  T* ptr = pUnique.get();
709  return overwrite1 (SG::asStorable<T>(std::move(pUnique)), ptr, key,
710  allowMods, noHist);
711 }
712 
713 template <typename T, typename AKEY>
714 StatusCode StoreGateSvc::setAlias(const T* pObject, const AKEY& aKey)
715 {
716  boost::function_requires< KeyConcept<AKEY> > ();
717  _SGXCALL(setAlias, (pObject, aKey), StatusCode::FAILURE);
718 }
719 //-------------------------------------------------------------------
720 template <typename T, typename TKEY, typename AKEY>
721 StatusCode
722 StoreGateSvc::setAlias(const T* /*dummy*/,
723  const TKEY& key, const AKEY& aKey)
724 {
725 #ifndef __clang__
726  BOOST_CONCEPT_ASSERT( (KeyConcept<TKEY>) );
727  BOOST_CONCEPT_ASSERT( (KeyConcept<AKEY>) );
728 #endif
729  _SGXCALL(setAlias, (ClassID_traits<T>::ID(), key, aKey), StatusCode::FAILURE);
730 }
731 
732 inline
733 StatusCode
734 StoreGateSvc::setAlias(SG::DataProxy* proxy, const std::string& aliasKey)
735 {
736  _SGXCALL(setAlias, (proxy, aliasKey), StatusCode::FAILURE);
737 }
738 
739 //////////////////////////////////////////////////////////////////
740 // Make a soft link to the object with key: return non_const link
741 //////////////////////////////////////////////////////////////////
742 template <typename T, typename TLINK>
743 StatusCode
744 StoreGateSvc::symLink(const T* pObject, TLINK* /*dummy*/)
745 {
746  _SGXCALL(symLink, (pObject, ClassID_traits<TLINK>::ID()), StatusCode::FAILURE);
747 }
748 
749 //////////////////////////////////////////////////////////////////
750 // Make a soft link to the object with key: set const link
751 //////////////////////////////////////////////////////////////////
752 template <typename T, typename TLINK>
753 StatusCode
754 StoreGateSvc::symLink(const T* pObject, const TLINK* /*dummy*/)
755 {
756  _SGXCALL(symLink, (pObject, ClassID_traits<TLINK>::ID()), StatusCode::FAILURE);
757 }
758 
759 template <typename TKEY>
760 StatusCode
761 StoreGateSvc::symLink(const CLID id, const TKEY& key, const CLID linkid)
762 {
763 #ifndef __clang__
764  //FIXME we have no way to check that the type represented by ID (the primary)
765  //FIXME is convertible into the linkid type. VERY BAD. Need introspection???
766  BOOST_CONCEPT_ASSERT( (KeyConcept<TKEY>) );
767 #endif
768  _SGXCALL(symLink, (id, key, linkid), StatusCode::FAILURE);
769 }
770 
771 
772 /// Remove pObject, will remove its proxy if not reset only.
773 template <typename T>
774 StatusCode
775 StoreGateSvc::remove(const T* pObject) {
776  _SGXCALL(remove, (pObject), StatusCode::FAILURE);
777 }
778 
779 /// Remove pObject and its proxy no matter what.
780 template <typename T>
781 StatusCode
782 StoreGateSvc::removeDataAndProxy(const T* pObject) {
783  _SGXCALL(removeDataAndProxy, (pObject), StatusCode::FAILURE);
784 }
785 
786 template <typename T, class TKEY>
787 StatusCode
788 StoreGateSvc::retrieveHighestVersion(SG::ObjectWithVersion<T>& dobjWithVersion,
789  const TKEY& requestedKey) const
790 {
791  std::list< SG::ObjectWithVersion<T> > allVersions;
792  StatusCode sc(this->retrieveAllVersions(allVersions,requestedKey));
793  if (sc.isSuccess()) {
794  allVersions.sort(); // on highest version number
795  dobjWithVersion.versionedKey.copyVK(allVersions.back().versionedKey.rawVersionKey());
796  }
797  return sc;
798 }
799 
800 template <typename T, class TKEY>
801 StatusCode
802 StoreGateSvc::retrieveAllVersions(std::list< SG::ObjectWithVersion<T> >& allVersions,
803  const TKEY& requestedKey) const
804 {
805  StatusCode sc(StatusCode::FAILURE);
806  SG::ConstIterator<T> i,e;
807  if ((this->retrieve<T>(i,e)).isSuccess()){
808  SG::VersionedKey reqVK(requestedKey);
809  while (i != e) {
810  SG::VersionedKey vk(i.key());
811  if (reqVK.sameKey(vk)) {
812  sc = StatusCode::SUCCESS;
813  SG::ObjectWithVersion<T> okOWV(vk, i.proxy());
814  allVersions.push_back(okOWV);
815  }
816  ++i;
817  }
818  }
819  return sc;
820 }
821 
822 
823 template <typename T>
824 std::unique_ptr<T>
825 StoreGateSvc::retrieveUniquePrivateCopy (const std::string& key)
826 {
827  CLID clid = ClassID_traits<T>::ID();
828  DataObject* obj = this->currentStore()->typeless_retrievePrivateCopy(clid, key);
829  std::unique_ptr<T> ret (SG::Storable_cast<T>(obj));
830  if (DataBucketBase* dbb = dynamic_cast<DataBucketBase*> (obj))
831  {
832  dbb->relinquish();
833  }
834  obj->release();
835  return ret;
836 }
837 
838 //////////////////////////////////////////////////////////////////
839 // Retrieve the @c CLID of a given "key"
840 // WARNING: slow!
841 //////////////////////////////////////////////////////////////////
842 template<typename TKEY>
843 CLID
844 StoreGateSvc::clid( const TKEY& key ) const
845 {
846  _SGXCALL(clid, (key), CLID_NULL);
847 }
848 
849 //////////////////////////////////////////////////////////////////
850 // Retrieve the @c CLID s of a given "key"
851 // WARNING: slow!
852 //////////////////////////////////////////////////////////////////
853 template<typename TKEY>
854 std::vector<CLID>
855 StoreGateSvc::clids( const TKEY& key ) const
856 {
857  std::vector<CLID> nullV;
858  _SGXCALL(clids, (key), nullV);
859 }
860 
861 ///////////////////////////////////////////////////////////////////////////
862 
863 inline
864 void
865 StoreGateSvc::setProxyProviderSvc(IProxyProviderSvc* pPPSvc) {
866  _SGVOIDCALL(setProxyProviderSvc, (pPPSvc));
867 }
868 
869 
870 inline
871 IProxyProviderSvc*
872 StoreGateSvc::proxyProviderSvc() {
873  _SGXCALL(proxyProviderSvc, (), nullptr);
874 }
875 
876 
877 /**
878  * @brief Return the metadata source ID for the current event slot.
879  * @param key SG key of the DataHeader to query.
880  * Returns an empty string if no source has been set.
881  *
882  * The default version always returns an empty string.
883  */
884 inline
885 SG::SourceID
886 StoreGateSvc::sourceID (const std::string& key /*= "EventSelector"*/) const {
887  _SGXCALL(sourceID, (key), "");
888 }
889 
890 
891 template <class TKEY>
892 void
893 StoreGateSvc::remap (CLID clid,
894  const TKEY& source,
895  const TKEY& target,
896  off_t index_offset) {
897  _SGVOIDCALL(remap_impl, (this->stringToKey (source, clid),
898  this->stringToKey (target, clid),
899  index_offset));
900 }
901 
902 
903 /**
904  * @brief Remember that retrieve() was called for a MT store.
905  * @param clid CLID of the operation.
906  * @param key Key of the operation.
907  */
908 inline
909 void StoreGateSvc::rememberBadRetrieve (CLID clid, const std::string& key) const
910 {
911  rememberBad (m_badRetrieves, clid, key);
912 }
913 
914 
915 /**
916  * @brief Remember that retrieve() was called for a MT store.
917  * @param clid CLID of the operation.
918  * @param key Key of the operation.
919  */
920 inline
921 void StoreGateSvc::rememberBadRecord (CLID clid, const std::string& key) const
922 {
923  rememberBad (m_badRecords, clid, key);
924 }
925 
926 
927 template <class DOBJ, class AUXSTORE>
928 bool StoreGateSvc::associateAux_impl (DOBJ* ptr,
929  const std::string& key,
930  const AUXSTORE*) const
931 {
932  CLID auxclid = ClassID_traits<AUXSTORE>::ID();
933  _SGXCALL( associateAux_impl, (ptr, key, auxclid), false);
934 }
935 
936 
937 template <class DOBJ>
938 bool StoreGateSvc::associateAux_impl (DOBJ* /*ptr*/,
939  const std::string& /*key*/,
940  const SG::NoAuxStore*) const
941 {
942  return true;
943 }
944 
945 
946 /**
947  * @brief associate a data object to its auxiliary store
948  * Return false if the aux store is not found.
949  * @param key The key to use for the lookup.
950  **/
951 template <class DOBJ>
952 bool StoreGateSvc::associateAux (DOBJ* ptr,
953  const std::string& key,
954  bool ignoreMissing) const
955 {
956  typename SG::AuxStore_traits<DOBJ>::type* pDummy(0); //used to pass down auxstore type
957  bool hasAux=associateAux_impl(ptr, key, pDummy) || ignoreMissing;
958  if (!hasAux) SG_MSG_WARNING("associateAux const: Could not associate AuxStore of type "
959  << SG::AuxStore_traits<DOBJ>::const_typeName()
960  << "\n to object of type " << ClassID_traits<DOBJ>::typeName() << "(CLID "
961  << ClassID_traits<DOBJ>::ID() << ") with key " << key << endmsg);
962  return hasAux;
963 }
964 
965 
966 template <class DOBJ>
967 bool StoreGateSvc::associateAux (const DOBJ* ptr,
968  const std::string& key,
969  bool ignoreMissing) const
970 {
971  typename SG::AuxStore_traits<DOBJ>::const_type* pDummy(0); //used to pass down auxstore type
972  // Should generally be ok, since any actual modification is done
973  // inside the store lock. Still kind of a wart that we still do this, though.
974  DOBJ* ptr_nc ATLAS_THREAD_SAFE = const_cast<DOBJ*> (ptr);
975  bool hasAux=associateAux_impl(ptr_nc, key, pDummy) || ignoreMissing;
976  if (!hasAux) SG_MSG_WARNING("associateAux const: Could not associate AuxStore of type "
977  << SG::AuxStore_traits<DOBJ>::const_typeName()
978  << "\n to object of type " << ClassID_traits<DOBJ>::typeName() << "(CLID "
979  << ClassID_traits<DOBJ>::ID() << ") with key " << key << endmsg);
980  return hasAux;
981 }
982 
983 
984 #endif //STOREGATE_STOREGATESVC_ICC