1 // Dear emacs, this is -*- c++ -*-
3 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
6 * @file AthContainers/AuxElement.icc
7 * @author scott snyder <snyder@bnl.gov>
9 * @brief Base class for elements of a container that can have aux data.
13 #include "AthContainers/tools/likely.h"
14 #include "CxxUtils/checker_macros.h"
22 * @brief Default constructor.
25 ConstAuxElement::ConstAuxElement()
26 : m_container (nullptr)
32 * @brief Constructor with explicit container / index.
33 * @param container Container of which this element will be a part.
34 * @param index Index of this element within the container.
36 * This does not make any changes to aux data.
39 ConstAuxElement::ConstAuxElement (const SG::AuxVectorData* container,
41 : IAuxElement (index),
42 m_container (container)
48 * @brief Copy Constructor.
49 * @param other Object being copied.
51 * We do not copy the container/index --- the new object is not yet
54 * In the case of constructing an object with a private store,
55 * @c makePrivateStore will take care of copying the aux data.
58 ConstAuxElement::ConstAuxElement (const ConstAuxElement& /*other*/)
68 * Any private store is deleted.
71 ConstAuxElement::~ConstAuxElement()
73 if (ATHCONTAINERS_UNLIKELY (!noPrivateData()))
74 releasePrivateStoreForDtor();
79 * @brief Return the container holding this element.
82 const SG::AuxVectorData* ConstAuxElement::container() const
89 * @brief Set the index/container for this element.
90 * @param index The index of this object within the container.
91 * @param container The container holding this object.
92 * May be null if this object is being removed
95 * Usually this simply sets the index and container members
96 * of this object. However, in the case where this object has
97 * an associated private store, then we need to deal with
98 * releasing the store if the object is being added to a container,
99 * or making a new store if the object is being removed from a container.
102 void ConstAuxElement::setIndex (size_t index,
103 const SG::AuxVectorData* container)
105 if (ATHCONTAINERS_UNLIKELY (!noPrivateData())) {
106 // out-of-line piece, dealing with private store.
107 setIndexPrivate (index, container);
111 IAuxElement::setIndex (index);
112 m_container = container;
117 * @brief Fetch an aux data variable, as a const reference.
118 * @param name Name of the aux variable.
120 * This method has to translate from the aux data name to the internal
121 * representation each time it is called. Using this method
122 * inside of loops is discouraged; instead use the @c Accessor
123 * or @c ConstAccessor classes.
125 template <class T, class ALLOC>
126 typename ConstAccessor<T, ALLOC>::const_reference_type
127 ConstAuxElement::auxdata (const std::string& name) const
129 return ConstAccessor<T, ALLOC>(name, "")(*this);
134 * @brief Fetch an aux data variable, as a const reference.
135 * @param name Name of the aux variable.
136 * @param clsname The name of the associated class. May be blank.
138 * This method has to translate from the aux data name to the internal
139 * representation each time it is called. Using this method
140 * inside of loops is discouraged; instead use the @c Accessor
141 * or @c ConstAccessor classes.
143 template <class T, class ALLOC>
144 typename ConstAccessor<T, ALLOC>::const_reference_type
145 ConstAuxElement::auxdata (const std::string& name,
146 const std::string& clsname) const
148 return ConstAccessor<T, ALLOC>(name, clsname)(*this);
153 * @brief Fetch an aux data variable, as a const reference.
154 * @param name Name of the aux variable.
156 * This method has to translate from the aux data name to the internal
157 * representation each time it is called. Using this method
158 * inside of loops is discouraged; instead use the @c ConstAccessor class.
160 template <class T, class ALLOC>
161 typename ConstAccessor<T, ALLOC>::const_reference_type
162 ConstAuxElement::auxdataConst (const std::string& name) const
164 return ConstAccessor<T, ALLOC>(name, "")(*this);
169 * @brief Fetch an aux data variable, as a const reference.
170 * @param name Name of the aux variable.
171 * @param clsname The name of the associated class. May be blank.
173 * This method has to translate from the aux data name to the internal
174 * representation each time it is called. Using this method
175 * inside of loops is discouraged; instead use the @c ConstAccessor class.
177 template <class T, class ALLOC>
178 typename ConstAccessor<T, ALLOC>::const_reference_type
179 ConstAuxElement::auxdataConst (const std::string& name,
180 const std::string& clsname) const
182 return ConstAccessor<T, ALLOC>(name, clsname)(*this);
187 * @brief Check if an aux variable is available for reading
188 * @param name Name of the aux variable.
189 * @param clsname The name of the associated class. May be blank.
191 * This method has to translate from the aux data name to the internal
192 * representation each time it is called. Using this method
193 * inside of loops is discouraged; instead use the @c Accessor class.
195 template <class T, class ALLOC>
196 bool ConstAuxElement::isAvailable (const std::string& name,
197 const std::string& clsname /*= ""*/) const
199 return ConstAccessor<T, ALLOC>(name, clsname).isAvailable(*this);
204 * @brief Check if an aux variable is available for writing as a decoration.
205 * @param name Name of the aux variable.
206 * @param clsname The name of the associated class. May be blank.
208 * This method has to translate from the aux data name to the internal
209 * representation each time it is called. Using this method
210 * inside of loops is discouraged; instead use the @c Accessor class.
212 template <class T, class ALLOC>
213 bool ConstAuxElement::isAvailableWritableAsDecoration (const std::string& name,
214 const std::string& clsname /*= ""*/) const
216 return Decorator<T, ALLOC>(name, clsname).isAvailableWritable(*this);
221 * @brief Fetch an aux decoration, as a non-const reference.
222 * @param name Name of the aux variable.
223 * @param clsname The name of the associated class. May be blank.
225 * This method has to translate from the aux data name to the internal
226 * representation each time it is called. Using this method
227 * inside of loops is discouraged; instead use the @c Accessor class.
229 * If the container is locked, this will allow fetching only variables
230 * that do not yet exist (in which case they will be marked as decorations)
231 * or variables already marked as decorations.
233 template <class T, class ALLOC>
234 typename Decorator<T, ALLOC>::reference_type
235 ConstAuxElement::auxdecor (const std::string& name) const
237 return Decorator<T, ALLOC>(name, "")(*this);
242 * @brief Fetch an aux decoration, as a non-const reference.
243 * @param name Name of the aux variable.
244 * @param clsname The name of the associated class. May be blank.
246 * This method has to translate from the aux data name to the internal
247 * representation each time it is called. Using this method
248 * inside of loops is discouraged; instead use the @c Accessor class.
250 * If the container is locked, this will allow fetching only variables
251 * that do not yet exist (in which case they will be marked as decorations)
252 * or variables already marked as decorations.
254 template <class T, class ALLOC>
255 typename Decorator<T, ALLOC>::reference_type
256 ConstAuxElement::auxdecor (const std::string& name,
257 const std::string& clsname) const
259 return Decorator<T, ALLOC>(name, clsname)(*this);
263 //******************************************************************************
267 * @brief Default constructor.
270 AuxElement::AuxElement()
271 #ifdef ATHCONTAINERS_R21_COMPAT
279 * @brief Constructor with explicit container / index.
280 * @param container Container of which this element will be a part.
281 * @param index Index of this element within the container.
283 * This does not make any changes to aux data.
286 AuxElement::AuxElement (SG::AuxVectorData* container,
288 #ifdef ATHCONTAINERS_R21_COMPAT
289 : IAuxElement(index),
290 m_container (container)
292 : ConstAuxElement(container, index)
299 * @brief Copy Constructor.
300 * @param other Object being copied.
302 * We do not copy the container/index --- the new object is not yet
305 * In the case of constructing an object with a private store,
306 * @c makePrivateStore will take care of copying the aux data.
309 AuxElement::AuxElement ([[maybe_unused]] const AuxElement& other)
310 #ifdef ATHCONTAINERS_R21_COMPAT
314 : ConstAuxElement (other)
322 * @param other The object from which we're assigning.
324 * We don't copy container/index, as assignment doesn't change where
325 * this object is. However, if we have aux data, then we copy aux data
326 * if we're copying from an object that also has it; otherwise,
327 * if we're copying from an object with no aux data, then we clear ours.
330 AuxElement& AuxElement::operator= (const AuxElement& other)
332 if (this != &other) {
333 if (this->container()) {
334 if (!other.container()) {
335 // Copying from an object with no aux data.
336 // Clear our aux data.
340 // Copying from an object with aux data.
341 // Copy the aux data too.
342 this->copyAux (other);
353 * Any private store is deleted.
356 AuxElement::~AuxElement()
358 #ifdef ATHCONTAINERS_R21_COMPAT
359 if (ATHCONTAINERS_UNLIKELY (!noPrivateData()))
360 releasePrivateStoreForDtor();
366 * @brief Return the container holding this element.
369 const SG::AuxVectorData* AuxElement::container() const
371 #ifdef ATHCONTAINERS_R21_COMPAT
374 return ConstAuxElement::container();
380 * @brief Return the container holding this element.
383 SG::AuxVectorData* AuxElement::container()
385 #ifdef ATHCONTAINERS_R21_COMPAT
388 SG::AuxVectorData* cont ATLAS_THREAD_SAFE = const_cast<SG::AuxVectorData*> (ConstAuxElement::container());
394 //******************************************************************************
398 * @brief Fetch an aux data variable, as a non-const reference.
399 * @param name Name of the aux variable.
400 * @param clsname The name of the associated class. May be blank.
402 * This method has to translate from the aux data name to the internal
403 * representation each time it is called. Using this method
404 * inside of loops is discouraged; instead use the @c Accessor class.
406 template <class T, class ALLOC>
407 typename Accessor<T, ALLOC>::reference_type
408 AuxElement::auxdata (const std::string& name)
410 return Accessor<T, ALLOC>(name, "")(*this);
415 * @brief Fetch an aux data variable, as a non-const reference.
416 * @param name Name of the aux variable.
417 * @param clsname The name of the associated class. May be blank.
419 * This method has to translate from the aux data name to the internal
420 * representation each time it is called. Using this method
421 * inside of loops is discouraged; instead use the @c Accessor class.
423 template <class T, class ALLOC>
424 typename Accessor<T, ALLOC>::reference_type
425 AuxElement::auxdata (const std::string& name,
426 const std::string& clsname)
428 return Accessor<T, ALLOC>(name, clsname)(*this);
433 * @brief Fetch an aux data variable, as a const reference.
434 * @param name Name of the aux variable.
436 * This method has to translate from the aux data name to the internal
437 * representation each time it is called. Using this method
438 * inside of loops is discouraged; instead use the @c Accessor
439 * or @c ConstAccessor classes.
441 template <class T, class ALLOC>
442 typename Accessor<T, ALLOC>::const_reference_type
443 AuxElement::auxdata (const std::string& name) const
445 return Accessor<T, ALLOC>(name, "")(*this);
450 * @brief Fetch an aux data variable, as a const reference.
451 * @param name Name of the aux variable.
452 * @param clsname The name of the associated class. May be blank.
454 * This method has to translate from the aux data name to the internal
455 * representation each time it is called. Using this method
456 * inside of loops is discouraged; instead use the @c Accessor
457 * or @c ConstAccessor classes.
459 template <class T, class ALLOC>
460 typename Accessor<T, ALLOC>::const_reference_type
461 AuxElement::auxdata (const std::string& name,
462 const std::string& clsname) const
464 return Accessor<T, ALLOC>(name, clsname)(*this);
469 * @brief Fetch an aux data variable, as a const reference.
470 * @param name Name of the aux variable.
472 * This method has to translate from the aux data name to the internal
473 * representation each time it is called. Using this method
474 * inside of loops is discouraged; instead use the @c ConstAccessor class.
476 template <class T, class ALLOC>
477 typename Accessor<T, ALLOC>::const_reference_type
478 AuxElement::auxdataConst (const std::string& name) const
480 return Accessor<T, ALLOC>(name, "")(*this);
485 * @brief Fetch an aux data variable, as a const reference.
486 * @param name Name of the aux variable.
487 * @param clsname The name of the associated class. May be blank.
489 * This method has to translate from the aux data name to the internal
490 * representation each time it is called. Using this method
491 * inside of loops is discouraged; instead use the @c ConstAccessor class.
493 template <class T, class ALLOC>
494 typename Accessor<T, ALLOC>::const_reference_type
495 AuxElement::auxdataConst (const std::string& name,
496 const std::string& clsname) const
498 return Accessor<T, ALLOC>(name, clsname)(*this);
503 * @brief Check if an aux variable is available for reading
504 * @param name Name of the aux variable.
505 * @param clsname The name of the associated class. May be blank.
507 * This method has to translate from the aux data name to the internal
508 * representation each time it is called. Using this method
509 * inside of loops is discouraged; instead use the @c Accessor class.
511 template <class T, class ALLOC>
512 bool AuxElement::isAvailable (const std::string& name,
513 const std::string& clsname /*= ""*/) const
515 return Accessor<T, ALLOC>(name, clsname).isAvailable(*this);
520 * @brief Check if an aux variable is available for writing
521 * @param name Name of the aux variable.
522 * @param clsname The name of the associated class. May be blank.
524 * This method has to translate from the aux data name to the internal
525 * representation each time it is called. Using this method
526 * inside of loops is discouraged; instead use the @c Accessor class.
528 template <class T, class ALLOC>
529 bool AuxElement::isAvailableWritable (const std::string& name,
530 const std::string& clsname /*= ""*/)
532 return Accessor<T, ALLOC>(name, clsname).isAvailableWritable(*this);
537 * @brief Check if an aux variable is available for writing as a decoration.
538 * @param name Name of the aux variable.
539 * @param clsname The name of the associated class. May be blank.
541 * This method has to translate from the aux data name to the internal
542 * representation each time it is called. Using this method
543 * inside of loops is discouraged; instead use the @c Accessor class.
545 template <class T, class ALLOC>
546 bool AuxElement::isAvailableWritableAsDecoration (const std::string& name,
547 const std::string& clsname /*= ""*/) const
549 return Decorator<T, ALLOC>(name, clsname).isAvailableWritable(*this);
554 * @brief Fetch an aux decoration, as a non-const reference.
555 * @param name Name of the aux variable.
556 * @param clsname The name of the associated class. May be blank.
558 * This method has to translate from the aux data name to the internal
559 * representation each time it is called. Using this method
560 * inside of loops is discouraged; instead use the @c Accessor class.
562 * If the container is locked, this will allow fetching only variables
563 * that do not yet exist (in which case they will be marked as decorations)
564 * or variables already marked as decorations.
566 template <class T, class ALLOC>
567 typename Decorator<T, ALLOC>::reference_type
568 AuxElement::auxdecor (const std::string& name) const
570 return Decorator<T, ALLOC>(name, "")(*this);
575 * @brief Fetch an aux decoration, as a non-const reference.
576 * @param name Name of the aux variable.
577 * @param clsname The name of the associated class. May be blank.
579 * This method has to translate from the aux data name to the internal
580 * representation each time it is called. Using this method
581 * inside of loops is discouraged; instead use the @c Accessor class.
583 * If the container is locked, this will allow fetching only variables
584 * that do not yet exist (in which case they will be marked as decorations)
585 * or variables already marked as decorations.
587 template <class T, class ALLOC>
588 typename Decorator<T, ALLOC>::reference_type
589 AuxElement::auxdecor (const std::string& name,
590 const std::string& clsname) const
592 return Decorator<T, ALLOC>(name, clsname)(*this);
597 * @brief Create a new private store for this object and copy aux data.
598 * @param other The object from which aux data should be copied.
600 * @c ExcBadPrivateStore will be thrown if this object is already
601 * associated with a store.
603 * If @c other is an object that has aux data, then those data will
604 * be copied; otherwise, nothing will be done.
608 void AuxElement::makePrivateStore (const U1& other)
610 // Dispatch to the proper overload depending on whether or not
611 // other derives from AuxElement.
612 makePrivateStore1 (&other);
617 * @brief Create a new private store for this object and copy aux data.
618 * @param other The object from which aux data should be copied.
620 * @c ExcBadPrivateStore will be thrown if this object is already
621 * associated with a store.
623 * If @c other is an object that has aux data, then those data will
624 * be copied; otherwise, nothing will be done.
628 void AuxElement::makePrivateStore (const U1* other)
630 // Dispatch to the proper overload depending on whether or not
631 // other derives from AuxElement.
632 makePrivateStore1 (other);
637 * @brief Synonym for @c setStore with @c IConstAuxStore.
638 * @param store The new store.
641 void AuxElement::setConstStore (const SG::IConstAuxStore* store)
648 * @brief Synonym for @c setStore with @c IAuxStore.
649 * @param store The new store.
652 void AuxElement::setNonConstStore (SG::IAuxStore* store)
659 * @brief Return true if index tracking is enabled for this object.
661 * Always returns true. Included here to be consistent with AuxVectorBase
662 * when standalone objects may be used as template parameters.
665 bool AuxElement::trackIndices() const
672 * @brief Set the index/container for this element.
673 * @param index The index of this object within the container.
674 * @param container The container holding this object.
675 * May be null if this object is being removed
678 * Usually this simply sets the index and container members
679 * of this object. However, in the case where this object has
680 * an associated private store, then we need to deal with
681 * releasing the store if the object is being added to a container,
682 * or making a new store if the object is being removed from a container.
685 void AuxElement::setIndex (size_t index, SG::AuxVectorData* container)
687 #ifdef ATHCONTAINERS_R21_COMPAT
688 if (ATHCONTAINERS_UNLIKELY (!noPrivateData())) {
689 // out-of-line piece, dealing with private store.
690 setIndexPrivate (index, container);
694 IAuxElement::setIndex (index);
695 m_container = container;
697 ConstAuxElement::setIndex (index, container);
703 * @brief Create a new private store for this object and copy aux data.
704 * @param other The object from which aux data should be copied.
706 * @c ExcBadPrivateStore will be thrown if this object is already
707 * associated with a store.
709 * This overload handles the case where @c other does not have aux data.
712 void AuxElement::makePrivateStore1 (const void*)