ATLAS Offline Software
Loading...
Searching...
No Matches
AuxElement.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
10
11
17#include <sstream>
18
19
20namespace SG {
21
22
30 : public AuxVectorData
31{
32public:
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{
47public:
49 {
50 this->setStore (&m_store);
51 }
52
53
54private:
56};
57
58
64class AuxElementStandaloneData
65 : public AuxElementData
66{
67public:
69};
70
71
72//************************************************************************
73
74
86
87
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);
110 IAuxElement::setIndex (0);
111 IAuxElement::setHavePrivateData();
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.
125 IAuxElement::setIndex (index);
126 IAuxElement::setHadPrivateData();
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
138 IAuxElement::setIndex (index);
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())
175 return m_container->getConstStore()->getDecorIDs();
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
192void AuxElement::makePrivateStore()
193{
194 if (m_container) {
195 throw SG::ExcBadPrivateStore ("store already exists");
196 }
197
198 m_container = new SG::AuxElementPrivateData;
199 IAuxElement::setIndex (0);
200 IAuxElement::setHavePrivateData();
201}
202
203
210void AuxElement::releasePrivateStore()
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.
215 IAuxElement::setNoPrivateData();
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
226 IAuxElement::setIndex (0);
227 IAuxElement::setNoPrivateData();
228 delete m_container;
229 m_container = 0;
230}
231
232
241void AuxElement::setStore (const SG::IConstAuxStore* store)
242{
243 AuxElementStandaloneData* data = setStore1 (store);
244 if (store)
245 data->setStore (store);
246}
247
248
257void AuxElement::setStore (SG::IAuxStore* store)
258{
259 AuxElementStandaloneData* data = setStore1 (store);
260 if (store)
261 data->setStore (store);
262}
263
264
269void AuxElement::setStore (const DataLink< SG::IConstAuxStore >& store)
270{
271 AuxElementStandaloneData* data = setStore1 (store);
272 if (store)
273 data->setStore (store);
274}
275
276
280bool AuxElement::usingPrivateStore() const
281{
282 return havePrivateData() &&
283 typeid(*m_container) == typeid(AuxElementPrivateData);
284}
285
286
290bool AuxElement::usingStandaloneStore() const
291{
292 return havePrivateData() &&
293 typeid(*m_container) == typeid(AuxElementStandaloneData);
294}
295
296
304const SG::IConstAuxStore* AuxElement::getConstStore() const
305{
306 if (havePrivateData()) {
307 return m_container->getConstStore();
308 }
309 return 0;
310}
311
312
319SG::IAuxStore* AuxElement::getStore() const
320{
321 if (havePrivateData()) {
322#ifdef ATHCONTAINERS_R21_COMPAT
323 SG::AuxVectorData* container_nc ATLAS_THREAD_SAFE = m_container;
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
339void AuxElement::clearCache()
340{
341 if (container())
343}
344
345
355const SG::auxid_set_t& AuxElement::getAuxIDs() const
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
378const SG::auxid_set_t& AuxElement::getDecorIDs() const
379{
380#ifdef ATHCONTAINERS_R21_COMPAT
381 if (havePrivateData())
382 return m_container->getConstStore()->getDecorIDs();
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
398bool AuxElement::hasNonConstStore() const
399{
400 if (havePrivateData())
401 return m_container->hasNonConstStore();
402 return false;
403}
404
405
415bool AuxElement::clearDecorations() const
416{
417 if (havePrivateData())
418 return m_container->clearDecorations();
419 return false;
420}
421
422
428void AuxElement::releasePrivateStoreForDtor()
429{
430#ifdef ATHCONTAINERS_R21_COMPAT
431 if (havePrivateData()) {
432 delete m_container;
433 }
434#else
436#endif
437}
438
439
447AuxElementStandaloneData*
448AuxElement::setStore1 (const SG::IConstAuxStore* store)
449{
450 if (store) {
451 // Want this object be standalone.
452 if (!m_container) {
453 // Not in a container (and no private store). Make a new object.
454 AuxElementStandaloneData* data = new AuxElementStandaloneData;
455 IAuxElement::setHavePrivateData();
456 m_container = data;
457 return data;
458 }
459 if (usingStandaloneStore()) {
460 // Standalone --- return existing object.
461 return static_cast<AuxElementStandaloneData*> (container());
462 }
463 // Otherwise, it's an error.
464 throw ExcBadPrivateStore ("Attempt to attach a standalone store to an "
465 "object in a container or with a private store.");
466 }
467
468 else {
469 // Getting rid of a standalone store.
470 if (usingStandaloneStore()) {
471 IAuxElement::setNoPrivateData();
472 delete m_container;
473 m_container = 0;
474 }
475 else if (m_container != 0)
476 throw ExcBadPrivateStore ("Attempt to remove a standalone store from an "
477 "object in a container or with a private store.");
478 return 0;
479 }
480}
481
482
492bool AuxElement::setIndexPrivate (size_t index, SG::AuxVectorData* container)
493{
494#ifdef ATHCONTAINERS_R21_COMPAT
495 if (hadPrivateData()) {
496 // We had a private store, but it was released because we were added
497 // to a container.
498
499 if (container == 0) {
500 // We're being moved out of the container. Make a new private
501 // store, copy the data, and switch to it.
502 auto privateData = new SG::AuxElementPrivateData;
503 AuxElement to (privateData, 0);
504 to.copyAux (*this);
505 IAuxElement::setIndex (0);
506 IAuxElement::setHavePrivateData();
507 m_container = privateData;
508 return true;
509 }
510 }
511 else if (havePrivateData() &&
512 typeid(*m_container) == typeid(AuxElementPrivateData))
513 {
514 // We currently have a private store.
515
516 if (container != 0 && container != m_container) {
517 // We're being added to a container.
518 // Aux data has already been copied.
519 // Release private store.
520 IAuxElement::setIndex (index);
521 IAuxElement::setHadPrivateData();
522 delete m_container;
523 m_container = container;
524 return false;
525 }
526 }
527 else {
528 // We have a standalone store.
529 throw SG::ExcBadPrivateStore ("Attempt to add/remove a standalone object "
530 "from a container.");
531 }
532
533 IAuxElement::setIndex (index);
534 m_container = container;
535 return false;
536#else
538#endif
539}
540
541
552void AuxElement::makePrivateStore1 (const AuxElement* other,
553 bool warnUnlocked)
554{
556 if (other)
557 this->copyAux (*other, warnUnlocked);
558}
559
560
567void AuxElement::clearAux()
568{
569 if (!m_container) return;
571}
572
573
587void AuxElement::copyAux (const ConstAuxElement& other,
588 bool warnUnlocked /*= false*/)
589{
590 if (!m_container) return;
591 copyAuxHelper (*container(), index(), other, warnUnlocked);
592}
593
594
595#ifdef ATHCONTAINERS_R21_COMPAT
609void AuxElement::copyAux (const AuxElement& other,
610 bool warnUnlocked /*= false*/)
611{
612 if (!m_container) return;
613 copyAuxHelper (*container(), index(), other, warnUnlocked);
614}
615#endif
616
617
618
626void AuxElement::clearAuxHelper (AuxVectorData& container, size_t index)
627{
628 if (!container.hasStore()) return;
629 if (!container.hasNonConstStore()) {
630 throw SG::ExcConstAuxData ("clearAux", SG::null_auxid);
631 }
632
634 for (SG::auxid_t auxid : container.getWritableAuxIDs()) {
635 r.clear (auxid, container, index, 1);
636 }
637}
638
639
654void AuxElement::copyAuxHelper (AuxVectorData& container,
655 size_t index,
656 const ConstAuxElement& other,
657 [[maybe_unused]] bool warnUnlocked)
658{
659 if (!container.hasStore()) return;
660 if (!container.hasNonConstStore())
661 throw SG::ExcConstAuxData ("copyAux");
662
663 const SG::AuxVectorData* ocont = other.container();
664
665 if (!ocont || !ocont->hasStore()) {
666 AuxElement::clearAuxHelper (container, index);
667 return;
668 }
669
670#ifndef XAOD_STANDALONE
671 const SG::auxid_set_t& other_decors = ocont->getDecorIDs();
672#endif
673 SG::auxid_set_t other_ids = ocont->getAuxIDs();
674
675 size_t oindex = other.index();
677
678 for (SG::auxid_t auxid : other_ids) {
679#ifndef XAOD_STANDALONE
680 if (other_decors.test (auxid)) {
681 // Don't copy decorations --- another thread may be modifying them.
682 other_ids.reset (auxid);
683 // Warn if we skip a decoration (except for mcEventWeights,
684 // for which this is expected).
685 if (warnUnlocked && r.getName(auxid) != "mcEventWeights") {
686 std::ostringstream ss;
687 ss << "skipped unlocked decoration " << r.getName(auxid)
688 << " (" << auxid << ")";
689 ATHCONTAINERS_WARNING("copyAux", ss.str());
690 }
691 }
692 else
693#endif
694 if (!r.isLinked (auxid)) {
695 r.copy (auxid, container, index, *ocont, oindex, 1);
696 }
697 }
698
699 for (SG::auxid_t auxid : container.getWritableAuxIDs()) {
700 if (!other_ids.test (auxid)) {
701 r.clear (auxid, container, index, 1);
702 }
703 }
704}
705
706
707#ifdef ATHCONTAINERS_R21_COMPAT
722void AuxElement::copyAuxHelper (AuxVectorData& container,
723 size_t index,
724 const AuxElement& other,
725 [[maybe_unused]] bool warnUnlocked)
726{
727 if (!container.hasStore()) return;
729 throw SG::ExcConstAuxData ("copyAux");
730
731 const SG::AuxVectorData* ocont = other.container();
732
733 if (!ocont || !ocont->hasStore()) {
734 AuxElement::clearAuxHelper (container, index);
735 return;
736 }
737
738#ifndef XAOD_STANDALONE
739 const SG::auxid_set_t& other_decors = ocont->getDecorIDs();
740#endif
741 SG::auxid_set_t other_ids = ocont->getAuxIDs();
742
743 size_t oindex = other.index();
744 SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
745
746 for (SG::auxid_t auxid : other_ids) {
747#ifndef XAOD_STANDALONE
748 if (other_decors.test (auxid)) {
749 // Don't copy decorations --- another thread may be modifying them.
750 other_ids.reset (auxid);
751 // Warn if we skip a decoration (except for mcEventWeights,
752 // for which this is expected).
753 if (warnUnlocked && r.getName(auxid) != "mcEventWeights") {
754 std::ostringstream ss;
755 ss << "skipped unlocked decoration " << r.getName(auxid)
756 << " (" << auxid << ")";
757 ATHCONTAINERS_WARNING("copyAux", ss.str());
758 }
759 }
760 else
761#endif
762 if (!r.isLinked (auxid)) {
763 r.copy (auxid, container, index, *ocont, oindex, 1);
764 }
765 }
766
768 if (!other_ids.test (auxid)) {
769 r.clear (auxid, container, index, 1);
770 }
771 }
772}
773#endif
774
775
776} // namespace SG
777
778
Base class for elements of a container that can have aux data.
Auxiliary data store for standalone objects.
Exceptions that can be thrown from AthContainers.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t ss
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
Internal data container.
virtual size_t size_v() const override
Return the size of the container.
virtual size_t capacity_v() const override
Return the capacity of the container.
Internal data container for private store.
AuxStoreStandalone m_store
Auxiliary data store for standalone objects.
Handle mappings between names and auxid_t.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Manage lookup of vectors of auxiliary data.
const SG::auxid_set_t & getAuxIDs() const
Return a set of identifiers for existing data items in store associated with this object.
void setStore(SG::IAuxStore *store)
Set the store associated with this object.
const SG::auxid_set_t & getDecorIDs() const
Return a set of identifiers for decorations for this object.
bool hasNonConstStore() const
Return true if this object has an associated non-const store.
void clearCache()
Clear the cached aux data pointers.
AuxVectorData()
Constructor.
const SG::auxid_set_t & getWritableAuxIDs() const
Return a set of identifiers for writable data items in this store.
bool hasStore() const
Return true if this object has an associated store.
Const part of AuxElement.
Definition AuxElement.h:71
const SG::AuxVectorData * m_container
The container of which this object is an element.
Definition AuxElement.h:335
friend class AuxElement
Definition AuxElement.h:292
const SG::auxid_set_t & getDecorIDs() const
Return a set of identifiers for decorations for this object.
bool setIndexPrivate(size_t index, const SG::AuxVectorData *container)
Set the index/container for this element.
const SG::AuxVectorData * container() const
Return the container holding this element.
void releasePrivateStoreForDtor()
Out-of-line portion of destructor.
const SG::auxid_set_t & getAuxIDs() const
Return a set of identifiers for existing data items for this object.
Exception — Bad use of private store.
Exception — Non-const operation performed on const aux data.
A set of aux data identifiers.
Definition AuxTypes.h:47
Helper for emitting error messages.
#define ATHCONTAINERS_WARNING(ctx, msg)
Definition error.h:57
int r
Definition globals.cxx:22
Forward declaration.
AuxElementStandaloneData * setStore1(const SG::IConstAuxStore *store)
Set the store associated with this object.
void makePrivateStore()
Create a new (empty) private store for this object.
void copyAux(const ConstAuxElement &other, bool warnUnlocked=false)
Copy aux data from another object.
static const auxid_t null_auxid
To signal no aux data item.
Definition AuxTypes.h:30
AuxElement(SG::AuxVectorData *container, size_t index)
Base class for elements of a container that can have aux data.
bool havePrivateData() const
True if this element currently has private data.
SG::auxid_t auxid() const
Return the aux id for this variable.
static void clearAuxHelper(AuxVectorData &container, size_t index)
Clear all aux data associated with an element.
bool usingStandaloneStore() const
Test to see if this object is currently using a standalone store.
bool hadPrivateData() const
True if this element had private data before it was added to its current container.
size_t index() const
Return the index of this element within its container.
const SG::AuxVectorData * container() const
Return the container holding this element.
static void copyAuxHelper(AuxVectorData &container, size_t index, const ConstAuxElement &other, bool warnUnlocked)
Copy aux data from another object.
void setStore(const SG::IConstAuxStore *store)
Set the store associated with this object.
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
Definition index.py:1