ATLAS Offline Software
AuxElement.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 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 override { return 1; }
34  virtual size_t capacity_v() const override { 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;
584 }
585 
586 
601  bool warnUnlocked /*= false*/)
602 {
603  if (!m_container) return;
604  copyAuxHelper (*container(), index(), other, warnUnlocked);
605 }
606 
607 
608 #ifdef ATHCONTAINERS_R21_COMPAT
609 
623  bool warnUnlocked /*= false*/)
624 {
625  if (!m_container) return;
626  copyAuxHelper (*container(), index(), other, warnUnlocked);
627 }
628 #endif
629 
630 
631 
640 {
641  if (!container.hasStore()) return;
642  if (!container.hasNonConstStore()) {
643  throw SG::ExcConstAuxData ("clearAux", SG::null_auxid);
644  }
645 
647  for (SG::auxid_t auxid : container.getWritableAuxIDs()) {
648  r.clear (auxid, container, index, 1);
649  }
650 }
651 
652 
668  size_t index,
669  const ConstAuxElement& other,
670  [[maybe_unused]] bool warnUnlocked)
671 {
672  if (!container.hasStore()) return;
674  throw SG::ExcConstAuxData ("copyAux");
675 
676  const SG::AuxVectorData* ocont = other.container();
677 
678  if (!ocont || !ocont->hasStore()) {
680  return;
681  }
682 
683 #ifndef XAOD_STANDALONE
684  const SG::auxid_set_t& other_decors = ocont->getDecorIDs();
685 #endif
686  SG::auxid_set_t other_ids = ocont->getAuxIDs();
687 
688  size_t oindex = other.index();
690 
691  for (SG::auxid_t auxid : other_ids) {
692 #ifndef XAOD_STANDALONE
693  if (other_decors.test (auxid)) {
694  // Don't copy decorations --- another thread may be modifying them.
695  other_ids.reset (auxid);
696  // Warn if we skip a decoration (except for mcEventWeights,
697  // for which this is expected).
698  if (warnUnlocked && r.getName(auxid) != "mcEventWeights") {
699  std::ostringstream ss;
700  ss << "skipped unlocked decoration " << r.getName(auxid)
701  << " (" << auxid << ")";
702  ATHCONTAINERS_WARNING("copyAux", ss.str());
703  }
704  }
705  else
706 #endif
707  if (!r.isLinked (auxid)) {
708  r.copy (auxid, container, index, *ocont, oindex, 1);
709  }
710  }
711 
712  for (SG::auxid_t auxid : container.getWritableAuxIDs()) {
713  if (!other_ids.test (auxid)) {
714  r.clear (auxid, container, index, 1);
715  }
716  }
717 }
718 
719 
720 #ifdef ATHCONTAINERS_R21_COMPAT
721 
736  size_t index,
737  const AuxElement& other,
738  [[maybe_unused]] bool warnUnlocked)
739 {
740  if (!container.hasStore()) return;
742  throw SG::ExcConstAuxData ("copyAux");
743 
744  const SG::AuxVectorData* ocont = other.container();
745 
746  if (!ocont || !ocont->hasStore()) {
748  return;
749  }
750 
751 #ifndef XAOD_STANDALONE
752  const SG::auxid_set_t& other_decors = ocont->getDecorIDs();
753 #endif
754  SG::auxid_set_t other_ids = ocont->getAuxIDs();
755 
756  size_t oindex = other.index();
758 
759  for (SG::auxid_t auxid : other_ids) {
760 #ifndef XAOD_STANDALONE
761  if (other_decors.test (auxid)) {
762  // Don't copy decorations --- another thread may be modifying them.
763  other_ids.reset (auxid);
764  // Warn if we skip a decoration (except for mcEventWeights,
765  // for which this is expected).
766  if (warnUnlocked && r.getName(auxid) != "mcEventWeights") {
767  std::ostringstream ss;
768  ss << "skipped unlocked decoration " << r.getName(auxid)
769  << " (" << auxid << ")";
770  ATHCONTAINERS_WARNING("copyAux", ss.str());
771  }
772  }
773  else
774 #endif
775  if (!r.isLinked (auxid)) {
776  r.copy (auxid, container, index, *ocont, oindex, 1);
777  }
778  }
779 
780  for (SG::auxid_t auxid : container.getWritableAuxIDs()) {
781  if (!other_ids.test (auxid)) {
782  r.clear (auxid, container, index, 1);
783  }
784  }
785 }
786 #endif
787 
788 
789 } // namespace SG
790 
791 
SG::AuxElementData::capacity_v
virtual size_t capacity_v() const override
Return the capacity of the container.
Definition: AuxElement.cxx:34
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:674
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::AuxElement::clearAuxHelper
static void clearAuxHelper(AuxVectorData &container, size_t index)
Clear all aux data associated with an element.
Definition: AuxElement.cxx:639
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::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::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:600
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::AuxElementData::size_v
virtual size_t size_v() const override
Return the size of the container.
Definition: AuxElement.cxx:33
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::AuxElement::copyAuxHelper
static void copyAuxHelper(AuxVectorData &container, size_t index, const ConstAuxElement &other, bool warnUnlocked)
Copy aux data from another object.
Definition: AuxElement.cxx:667
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.