ATLAS Offline Software
AuxElement.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
17 #include <sstream>
18 
19 
20 namespace SG {
21 
22 
30  : public AuxVectorData
31 {
32 public:
33  virtual size_t size_v() const { return 1; }
34  virtual size_t capacity_v() const { return 1; }
35 };
36 
37 
45  : public AuxElementData
46 {
47 public:
49  {
50  this->setStore (&m_store);
51  }
52 
53 
54 private:
56 };
57 
58 
65  : public AuxElementData
66 {
67 public:
69 };
70 
71 
72 //************************************************************************
73 
74 
81 {
82  if (havePrivateData()) {
83  delete m_container;
84  }
85 }
86 
87 
98  const SG::AuxVectorData* container)
99 {
100  if (hadPrivateData()) {
101  // We had a private store, but it was released because we were added
102  // to a container.
103 
104  if (container == 0) {
105  // We're being moved out of the container. Make a new private
106  // store, copy the data, and switch to it.
107  auto privateData = new SG::AuxElementPrivateData;
108  AuxElement to (privateData, 0);
109  to.copyAux (*this);
112  m_container = privateData;
113  return true;
114  }
115  }
116  else if (havePrivateData() &&
117  typeid(*m_container) == typeid(AuxElementPrivateData))
118  {
119  // We currently have a private store.
120 
121  if (container != 0 && container != m_container) {
122  // We're being added to a container.
123  // Aux data has already been copied.
124  // Release private store.
127  delete m_container;
129  return false;
130  }
131  }
132  else {
133  // We have a standalone store.
134  throw SG::ExcBadPrivateStore ("Attempt to add/remove a standalone object "
135  "from a container.");
136  }
137 
140  return false;
141 }
142 
143 
154 {
155  if (havePrivateData())
156  return m_container->getConstStore()->getAuxIDs();
157  if (container())
158  return container()->getAuxIDs();
159  static const SG::auxid_set_t null_set;
160  return null_set;
161 }
162 
163 
173 {
174  if (havePrivateData())
176  if (container())
177  return container()->getDecorIDs();
178  static const SG::auxid_set_t null_set;
179  return null_set;
180 }
181 
182 
183 //************************************************************************
184 
185 
193 {
194  if (m_container) {
195  throw SG::ExcBadPrivateStore ("store already exists");
196  }
197 
201 }
202 
203 
211 {
212  if (hadPrivateData()) {
213  // We had a private store, but it was released because this object
214  // was added to a container. Just forget about it.
216  return;
217  }
218 
219  if (!havePrivateData() ||
220  !m_container ||
221  typeid(*m_container) != typeid(AuxElementPrivateData))
222  {
223  throw SG::ExcBadPrivateStore ("no private store exists");
224  }
225 
228  delete m_container;
229  m_container = 0;
230 }
231 
232 
242 {
244  if (store)
245  data->setStore (store);
246 }
247 
248 
258 {
260  if (store)
261  data->setStore (store);
262 }
263 
264 
270 {
272  if (store)
273  data->setStore (store);
274 }
275 
276 
281 {
282  return havePrivateData() &&
283  typeid(*m_container) == typeid(AuxElementPrivateData);
284 }
285 
286 
291 {
292  return havePrivateData() &&
293  typeid(*m_container) == typeid(AuxElementStandaloneData);
294 }
295 
296 
305 {
306  if (havePrivateData()) {
307  return m_container->getConstStore();
308  }
309  return 0;
310 }
311 
312 
320 {
321  if (havePrivateData()) {
322 #ifdef ATHCONTAINERS_R21_COMPAT
324 #else
325  SG::AuxVectorData* container_nc ATLAS_THREAD_SAFE = const_cast<SG::AuxVectorData*>(container());
326 #endif
327  return container_nc->getStore();
328  }
329  return 0;
330 }
331 
332 
340 {
341  if (container())
342  container()->clearCache();
343 }
344 
345 
356 {
357 #ifdef ATHCONTAINERS_R21_COMPAT
358  if (havePrivateData())
359  return m_container->getConstStore()->getAuxIDs();
360  if (container())
361  return container()->getAuxIDs();
362  static const SG::auxid_set_t null_set;
363  return null_set;
364 #else
366 #endif
367 }
368 
369 
379 {
380 #ifdef ATHCONTAINERS_R21_COMPAT
381  if (havePrivateData())
383  if (container())
384  return container()->getDecorIDs();
385  static const SG::auxid_set_t null_set;
386  return null_set;
387 #else
389 #endif
390 }
391 
392 
399 {
400  if (havePrivateData())
401  return m_container->hasStore();
402  return false;
403 }
404 
405 
412 {
413  if (havePrivateData())
414  return m_container->hasNonConstStore();
415  return false;
416 }
417 
418 
429 {
430  if (havePrivateData())
431  return m_container->clearDecorations();
432  return false;
433 }
434 
435 
442 {
443 #ifdef ATHCONTAINERS_R21_COMPAT
444  if (havePrivateData()) {
445  delete m_container;
446  }
447 #else
449 #endif
450 }
451 
452 
462 {
463  if (store) {
464  // Want this object be standalone.
465  if (!m_container) {
466  // Not in a container (and no private store). Make a new object.
469  m_container = data;
470  return data;
471  }
472  if (usingStandaloneStore()) {
473  // Standalone --- return existing object.
474  return static_cast<AuxElementStandaloneData*> (container());
475  }
476  // Otherwise, it's an error.
477  throw ExcBadPrivateStore ("Attempt to attach a standalone store to an "
478  "object in a container or with a private store.");
479  }
480 
481  else {
482  // Getting rid of a standalone store.
483  if (usingStandaloneStore()) {
485  delete m_container;
486  m_container = 0;
487  }
488  else if (m_container != 0)
489  throw ExcBadPrivateStore ("Attempt to remove a standalone store from an "
490  "object in a container or with a private store.");
491  return 0;
492  }
493 }
494 
495 
506 {
507 #ifdef ATHCONTAINERS_R21_COMPAT
508  if (hadPrivateData()) {
509  // We had a private store, but it was released because we were added
510  // to a container.
511 
512  if (container == 0) {
513  // We're being moved out of the container. Make a new private
514  // store, copy the data, and switch to it.
515  auto privateData = new SG::AuxElementPrivateData;
516  AuxElement to (privateData, 0);
517  to.copyAux (*this);
520  m_container = privateData;
521  return true;
522  }
523  }
524  else if (havePrivateData() &&
525  typeid(*m_container) == typeid(AuxElementPrivateData))
526  {
527  // We currently have a private store.
528 
529  if (container != 0 && container != m_container) {
530  // We're being added to a container.
531  // Aux data has already been copied.
532  // Release private store.
535  delete m_container;
537  return false;
538  }
539  }
540  else {
541  // We have a standalone store.
542  throw SG::ExcBadPrivateStore ("Attempt to add/remove a standalone object "
543  "from a container.");
544  }
545 
548  return false;
549 #else
551 #endif
552 }
553 
554 
566  bool warnUnlocked)
567 {
569  if (other)
570  this->copyAux (*other, warnUnlocked);
571 }
572 
573 
581 {
582  if (!m_container) return;
583  if (!m_container->hasStore()) return;
585  throw SG::ExcConstAuxData ("clearAux", SG::null_auxid);
586 
588  for (SG::auxid_t auxid : m_container->getWritableAuxIDs()) {
589  r.clear (auxid, *container(), index(), 1);
590  }
591 }
592 
593 
608  [[maybe_unused]] bool warnUnlocked /*= false*/)
609 {
610  if (!m_container) return;
611  if (!m_container->hasStore()) return;
613  throw SG::ExcConstAuxData ("copyAux");
614 
615  const SG::AuxVectorData* ocont = other.container();
616 
617  if (!ocont || !ocont->hasStore()) {
618  this->clearAux();
619  return;
620  }
621 
622  size_t oindex = other.index();
623  SG::auxid_set_t other_ids = ocont->getAuxIDs();
624 #ifndef XAOD_STANDALONE
625  SG::auxid_set_t other_decors = ocont->getDecorIDs();
626 #endif
627 
629 
630  SG::AuxVectorData& cont = *container();
631  for (SG::auxid_t auxid : other_ids) {
632 #ifndef XAOD_STANDALONE
633  if (other_decors.test (auxid)) {
634  // Don't copy decorations --- another thread may be modifying them.
635  other_ids.reset (auxid);
636  // Warn if we skip a decoration (except for mcEventWeights,
637  // for which this is expected).
638  if (warnUnlocked && r.getName(auxid) != "mcEventWeights") {
639  std::ostringstream ss;
640  ss << "skipped unlocked decoration " << r.getName(auxid)
641  << " (" << auxid << ")";
642  ATHCONTAINERS_WARNING("copyAux", ss.str());
643  }
644  }
645  else
646 #endif
647  if (!r.isLinked (auxid)) {
648  r.copy (auxid, cont, index(), *ocont, oindex, 1);
649  }
650  }
651 
652  for (SG::auxid_t auxid : m_container->getWritableAuxIDs()) {
653  if (!other_ids.test (auxid)) {
654  r.clear (auxid, cont, index(), 1);
655  }
656  }
657 }
658 
659 
660 #ifdef ATHCONTAINERS_R21_COMPAT
661 
675  [[maybe_unused]] bool warnUnlocked /*= false*/)
676 {
677  if (!m_container) return;
678  if (!m_container->hasStore()) return;
680  throw SG::ExcConstAuxData ("copyAux");
681 
682  const SG::AuxVectorData* ocont = other.container();
683 
684  if (!ocont || !ocont->hasStore()) {
685  this->clearAux();
686  return;
687  }
688 
689  size_t oindex = other.index();
690  SG::auxid_set_t other_ids = ocont->getAuxIDs();
691 #ifndef XAOD_STANDALONE
692  SG::auxid_set_t other_decors = ocont->getDecorIDs();
693 #endif
694 
696 
697  AuxVectorData& cont = *container();
698  for (SG::auxid_t auxid : other_ids) {
699 #ifndef XAOD_STANDALONE
700  if (other_decors.test (auxid)) {
701  // Don't copy decorations --- another thread may be modifying them.
702  other_ids.reset (auxid);
703  // Warn if we skip a decoration (except for mcEventWeights,
704  // for which this is expected).
705  if (warnUnlocked && r.getName(auxid) != "mcEventWeights") {
706  std::ostringstream ss;
707  ss << "skipped unlocked decoration " << r.getName(auxid)
708  << " (" << auxid << ")";
709  ATHCONTAINERS_WARNING("copyAux", ss.str());
710  }
711  }
712  else
713 #endif
714  if (!r.isLinked (auxid)) {
715  r.copy (auxid, cont, index(), *ocont, oindex, 1);
716  }
717  }
718 
719  for (SG::auxid_t auxid : m_container->getWritableAuxIDs()) {
720  if (!other_ids.test (auxid)) {
721  r.clear (auxid, cont, index(), 1);
722  }
723  }
724 }
725 #endif
726 
727 
728 } // namespace SG
729 
730 
SG::AuxVectorData::getConstStore
const SG::IConstAuxStore * getConstStore() const
Return the current store, as a const interface.
SGTest::store
TestStore store
Definition: TestStore.cxx:23
beamspotman.r
def r
Definition: beamspotman.py:676
SG::ConstAuxElement::getAuxIDs
const SG::auxid_set_t & getAuxIDs() const
Return a set of identifiers for existing data items for this object.
Definition: AuxElement.cxx:153
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:639
SG::AuxVectorData::getDecorIDs
const SG::auxid_set_t & getDecorIDs() const
Return a set of identifiers for decorations for this object.
Definition: AuxVectorData.cxx:215
SG::ConstAuxElement::container
const SG::AuxVectorData * container() const
Return the container holding this element.
SG::AuxVectorData::getWritableAuxIDs
const SG::auxid_set_t & getWritableAuxIDs() const
Return a set of identifiers for writable data items in this store.
Definition: AuxVectorData.cxx:231
index
Definition: index.py:1
SG::AuxElement
Base class for elements of a container that can have aux data.
Definition: AuxElement.h:483
SG::ConstAuxElement::m_container
const SG::AuxVectorData * m_container
The container of which this object is an element.
Definition: AuxElement.h:335
exceptions.h
Exceptions that can be thrown from AthContainers.
SG::AuxVectorData::hasNonConstStore
bool hasNonConstStore() const
Return true if this object has an associated non-const store.
SG::AuxElement::hasNonConstStore
bool hasNonConstStore() const
Return true if this object has an associated non-const store.
Definition: AuxElement.cxx:411
SG::AuxElement::usingStandaloneStore
bool usingStandaloneStore() const
Test to see if this object is currently using a standalone store.
Definition: AuxElement.cxx:290
SG::ConstAuxElement::setIndexPrivate
bool setIndexPrivate(size_t index, const SG::AuxVectorData *container)
Set the index/container for this element.
Definition: AuxElement.cxx:97
SG::ExcConstAuxData
Exception — Non-const operation performed on const aux data.
Definition: Control/AthContainers/AthContainers/exceptions.h:77
SG::AuxElementData::capacity_v
virtual size_t capacity_v() const
Return the capacity of the container.
Definition: AuxElement.cxx:34
SG::IAuxElement::setNoPrivateData
void setNoPrivateData()
Record that this element does not have private data.
SG::AuxElement::getStore
SG::IAuxStore * getStore() const
Return the current store, as a non-const interface.
Definition: AuxElement.cxx:319
SG::AuxVectorData::getAuxIDs
const SG::auxid_set_t & getAuxIDs() const
Return a set of identifiers for existing data items in store associated with this object.
Definition: AuxVectorData.cxx:203
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
SG::AuxElementData::size_v
virtual size_t size_v() const
Return the size of the container.
Definition: AuxElement.cxx:33
SG::AuxVectorData::setStore
void setStore(SG::IAuxStore *store)
Set the store associated with this object.
Definition: AuxVectorData.cxx:116
SG::IAuxElement::index
size_t index() const
Return the index of this element within its container.
SG::IAuxElement::setHadPrivateData
void setHadPrivateData()
Record that this element used to have private data.
SG::AuxElement::releasePrivateStoreForDtor
void releasePrivateStoreForDtor()
Out-of-line portion of destructor.
Definition: AuxElement.cxx:441
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
SG::AuxElementPrivateData::m_store
AuxStoreStandalone m_store
Definition: AuxElement.cxx:55
SG::AuxElement::setStore
void setStore(const SG::IConstAuxStore *store)
Set the store associated with this object.
Definition: AuxElement.cxx:241
SG::AuxElement::copyAux
void copyAux(const ConstAuxElement &other, bool warnUnlocked=false)
Copy aux data from another object.
Definition: AuxElement.cxx:607
SG::AuxElement::clearAux
void clearAux()
Clear all aux data associated with this element.
Definition: AuxElement.cxx:580
SG::IAuxElement::havePrivateData
bool havePrivateData() const
True if this element currently has private data.
ATHCONTAINERS_WARNING
#define ATHCONTAINERS_WARNING(ctx, msg)
Definition: error.h:57
SG::AuxElement::usingPrivateStore
bool usingPrivateStore() const
Test to see if this object is currently using a private store.
Definition: AuxElement.cxx:280
SG::AuxVectorData::getStore
SG::IAuxStore * getStore()
Return the current store, as a non-const interface.
SG::AuxElement::setIndexPrivate
bool setIndexPrivate(size_t index, SG::AuxVectorData *container)
Set the index/container for this element.
Definition: AuxElement.cxx:505
SG::ConstAuxElement::getDecorIDs
const SG::auxid_set_t & getDecorIDs() const
Return a set of identifiers for decorations for this object.
Definition: AuxElement.cxx:172
SG::AuxElementData
Internal data container.
Definition: AuxElement.cxx:31
SG::AuxElement::releasePrivateStore
void releasePrivateStore()
Release and free any private store associated with this object.
Definition: AuxElement.cxx:210
error.h
Helper for emitting error messages.
SG::AuxStoreStandalone
Auxiliary data store for standalone objects.
Definition: AuxStoreStandalone.h:41
SG::AuxElementPrivateData
Internal data container for private store.
Definition: AuxElement.cxx:46
SG::AuxElement::clearDecorations
bool clearDecorations() const
Clear all decorations.
Definition: AuxElement.cxx:428
SG::AuxElement::getAuxIDs
const SG::auxid_set_t & getAuxIDs() const
Return a set of identifiers for existing data items for this object.
Definition: AuxElement.cxx:355
SG::AuxVectorData::hasStore
bool hasStore() const
Return true if this object has an associated store.
SG::ConstAuxElement
Const part of AuxElement.
Definition: AuxElement.h:71
SG::AuxElement::clearCache
void clearCache()
Clear the cached aux data pointers.
Definition: AuxElement.cxx:339
SG::IAuxElement::setHavePrivateData
void setHavePrivateData()
Record that this element currently has private data.
SG::AuxVectorData::clearCache
void clearCache()
Clear the cached aux data pointers.
SG::AuxElement::makePrivateStore
void makePrivateStore()
Create a new (empty) private store for this object.
Definition: AuxElement.cxx:192
SG::AuxElement::makePrivateStore1
void makePrivateStore1(const void *other, bool warnUnlocked)
Create a new private store for this object and copy aux data.
SG::AuxElementStandaloneData
Internal data container for standalone store.
Definition: AuxElement.cxx:66
SG::AuxElement::getConstStore
const SG::IConstAuxStore * getConstStore() const
Return the current store, as a const interface.
Definition: AuxElement.cxx:304
CxxUtils::to
CONT to(RANGE &&r)
Definition: ranges.h:39
SG::IAuxStore
Interface for non-const operations on an auxiliary store.
Definition: IAuxStore.h:48
SG::AuxElement::getDecorIDs
const SG::auxid_set_t & getDecorIDs() const
Return a set of identifiers for decorations for this object.
Definition: AuxElement.cxx:378
SG::AuxElement::hasStore
bool hasStore() const
Return true if this object has an associated store.
Definition: AuxElement.cxx:398
SG::IAuxElement::setIndex
void setIndex(size_t index)
Set the index of this element within its container.
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
SG::AuxElementPrivateData::AuxElementPrivateData
AuxElementPrivateData()
Definition: AuxElement.cxx:48
SG::AuxVectorData::clearDecorations
bool clearDecorations() const
Clear all decorations.
Definition: AuxVectorData.cxx:653
AuxStoreStandalone.h
Auxiliary data store for standalone objects.
SG::ExcBadPrivateStore
Exception — Bad use of private store.
Definition: Control/AthContainers/AthContainers/exceptions.h:113
SG::IConstAuxStore::getDecorIDs
virtual const SG::auxid_set_t & getDecorIDs() const =0
Return a set of identifiers for decorations in this store.
SG::auxid_set_t
A set of aux data identifiers.
Definition: AuxTypes.h:47
SG::AuxVectorData
Manage lookup of vectors of auxiliary data.
Definition: AuxVectorData.h:168
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
SG::ConstAuxElement::releasePrivateStoreForDtor
void releasePrivateStoreForDtor()
Out-of-line portion of destructor.
Definition: AuxElement.cxx:80
SG::AuxElement::container
const SG::AuxVectorData * container() const
Return the container holding this element.
SG::IConstAuxStore
Interface for const operations on an auxiliary store.
Definition: IConstAuxStore.h:64
checker_macros.h
Define macros for attributes used to control the static checker.
SG::IAuxElement::hadPrivateData
bool hadPrivateData() const
True if this element had private data before it was added to its current container.
SG::IConstAuxStore::getAuxIDs
virtual const SG::auxid_set_t & getAuxIDs() const =0
Return a set of identifiers for existing data items in this store.
SG::AuxElement::setStore1
AuxElementStandaloneData * setStore1(const SG::IConstAuxStore *store)
Set the store associated with this object.
Definition: AuxElement.cxx:461
AuxElement.h
Base class for elements of a container that can have aux data.
CxxUtils::ConcurrentBitset::test
bool test(bit_t bit) const
Test to see if a bit is set.