ATLAS Offline Software
AuxElement.icc
Go to the documentation of this file.
1 // Dear emacs, this is -*- c++ -*-
2 /*
3  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4 */
5 /**
6  * @file AthContainers/AuxElement.icc
7  * @author scott snyder <snyder@bnl.gov>
8  * @date Sep, 2013
9  * @brief Base class for elements of a container that can have aux data.
10  */
11 
12 
13 #include "AthContainers/tools/likely.h"
14 #include "CxxUtils/checker_macros.h"
15 #include <cassert>
16 
17 
18 namespace SG {
19 
20 
21 /**
22  * @brief Default constructor.
23  */
24 inline
25 ConstAuxElement::ConstAuxElement()
26  : m_container (nullptr)
27 {
28 }
29 
30 
31 /**
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.
35  *
36  * This does not make any changes to aux data.
37  */
38 inline
39 ConstAuxElement::ConstAuxElement (const SG::AuxVectorData* container,
40  size_t index)
41  : IAuxElement (index),
42  m_container (container)
43 {
44 }
45 
46 
47 /**
48  * @brief Copy Constructor.
49  * @param other Object being copied.
50  *
51  * We do not copy the container/index --- the new object is not yet
52  * in a container!
53  *
54  * In the case of constructing an object with a private store,
55  * @c makePrivateStore will take care of copying the aux data.
56  */
57 inline
58 ConstAuxElement::ConstAuxElement (const ConstAuxElement& /*other*/)
59  : IAuxElement(),
60  m_container (nullptr)
61 {
62 }
63 
64 
65 /**
66  * @brief Destructor.
67  *
68  * Any private store is deleted.
69  */
70 inline
71 ConstAuxElement::~ConstAuxElement()
72 {
73  if (ATHCONTAINERS_UNLIKELY (!noPrivateData()))
74  releasePrivateStoreForDtor();
75 }
76 
77 
78 /**
79  * @brief Return the container holding this element.
80  */
81 inline
82 const SG::AuxVectorData* ConstAuxElement::container() const
83 {
84  return m_container;
85 }
86 
87 
88 /**
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
93  * from a container.
94  *
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.
100  */
101 inline
102 void ConstAuxElement::setIndex (size_t index,
103  const SG::AuxVectorData* container)
104 {
105  if (ATHCONTAINERS_UNLIKELY (!noPrivateData())) {
106  // out-of-line piece, dealing with private store.
107  setIndexPrivate (index, container);
108  return;
109  }
110 
111  IAuxElement::setIndex (index);
112  m_container = container;
113 }
114 
115 
116 /**
117  * @brief Fetch an aux data variable, as a const reference.
118  * @param name Name of the aux variable.
119  *
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.
124  */
125 template <class T, class ALLOC>
126 typename ConstAccessor<T, ALLOC>::const_reference_type
127 ConstAuxElement::auxdata (const std::string& name) const
128 {
129  return ConstAccessor<T, ALLOC>(name, "")(*this);
130 }
131 
132 
133 /**
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.
137  *
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.
142  */
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
147 {
148  return ConstAccessor<T, ALLOC>(name, clsname)(*this);
149 }
150 
151 
152 /**
153  * @brief Fetch an aux data variable, as a const reference.
154  * @param name Name of the aux variable.
155  *
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.
159  */
160 template <class T, class ALLOC>
161 typename ConstAccessor<T, ALLOC>::const_reference_type
162 ConstAuxElement::auxdataConst (const std::string& name) const
163 {
164  return ConstAccessor<T, ALLOC>(name, "")(*this);
165 }
166 
167 
168 /**
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.
172  *
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.
176  */
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
181 {
182  return ConstAccessor<T, ALLOC>(name, clsname)(*this);
183 }
184 
185 
186 /**
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.
190  *
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.
194  */
195 template <class T, class ALLOC>
196 bool ConstAuxElement::isAvailable (const std::string& name,
197  const std::string& clsname /*= ""*/) const
198 {
199  return ConstAccessor<T, ALLOC>(name, clsname).isAvailable(*this);
200 }
201 
202 
203 /**
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.
207  *
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.
211  */
212 template <class T, class ALLOC>
213 bool ConstAuxElement::isAvailableWritableAsDecoration (const std::string& name,
214  const std::string& clsname /*= ""*/) const
215 {
216  return Decorator<T, ALLOC>(name, clsname).isAvailableWritable(*this);
217 }
218 
219 
220 /**
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.
224  *
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.
228  *
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.
232  */
233 template <class T, class ALLOC>
234 typename Decorator<T, ALLOC>::reference_type
235 ConstAuxElement::auxdecor (const std::string& name) const
236 {
237  return Decorator<T, ALLOC>(name, "")(*this);
238 }
239 
240 
241 /**
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.
245  *
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.
249  *
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.
253  */
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
258 {
259  return Decorator<T, ALLOC>(name, clsname)(*this);
260 }
261 
262 
263 //******************************************************************************
264 
265 
266 /**
267  * @brief Default constructor.
268  */
269 inline
270 AuxElement::AuxElement()
271 #ifdef ATHCONTAINERS_R21_COMPAT
272  : m_container(0)
273 #endif
274 {
275 }
276 
277 
278 /**
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.
282  *
283  * This does not make any changes to aux data.
284  */
285 inline
286 AuxElement::AuxElement (SG::AuxVectorData* container,
287  size_t index)
288 #ifdef ATHCONTAINERS_R21_COMPAT
289  : IAuxElement(index),
290  m_container (container)
291 #else
292  : ConstAuxElement(container, index)
293 #endif
294 {
295 }
296 
297 
298 /**
299  * @brief Copy Constructor.
300  * @param other Object being copied.
301  *
302  * We do not copy the container/index --- the new object is not yet
303  * in a container!
304  *
305  * In the case of constructing an object with a private store,
306  * @c makePrivateStore will take care of copying the aux data.
307  */
308 inline
309 AuxElement::AuxElement ([[maybe_unused]] const AuxElement& other)
310 #ifdef ATHCONTAINERS_R21_COMPAT
311  : IAuxElement(),
312  m_container(0)
313 #else
314  : ConstAuxElement (other)
315 #endif
316 {
317 }
318 
319 
320 /**
321  * @brief Assignment.
322  * @param other The object from which we're assigning.
323  *
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.
328  */
329 inline
330 AuxElement& AuxElement::operator= (const AuxElement& other)
331 {
332  this->assign (other);
333  return *this;
334 }
335 
336 
337 /**
338  * @brief Assignment.
339  * @param other The object from which we're assigning.
340  * @param warnUnlocked If true, then warn when we skip unlocked decorations.
341  *
342  * We don't copy container/index, as assignment doesn't change where
343  * this object is. However, if we have aux data, then we copy aux data
344  * if we're copying from an object that also has it; otherwise,
345  * if we're copying from an object with no aux data, then we clear ours.
346  */
347 inline
348 void AuxElement::assign (const AuxElement& other,
349  bool warnUnlocked /*= false*/)
350 {
351  if (this != &other) {
352  if (this->container()) {
353  if (!other.container()) {
354  // Copying from an object with no aux data.
355  // Clear our aux data.
356  this->clearAux();
357  }
358  else {
359  // Copying from an object with aux data.
360  // Copy the aux data too.
361  this->copyAux (other, warnUnlocked);
362  }
363  }
364  }
365 }
366 
367 
368 /**
369  * @brief Destructor.
370  *
371  * Any private store is deleted.
372  */
373 inline
374 AuxElement::~AuxElement()
375 {
376 #ifdef ATHCONTAINERS_R21_COMPAT
377  if (ATHCONTAINERS_UNLIKELY (!noPrivateData()))
378  releasePrivateStoreForDtor();
379 #endif
380 }
381 
382 
383 /**
384  * @brief Return the container holding this element.
385  */
386 inline
387 const SG::AuxVectorData* AuxElement::container() const
388 {
389 #ifdef ATHCONTAINERS_R21_COMPAT
390  return m_container;
391 #else
392  return ConstAuxElement::container();
393 #endif
394 }
395 
396 
397 /**
398  * @brief Return the container holding this element.
399  */
400 inline
401 SG::AuxVectorData* AuxElement::container()
402 {
403 #ifdef ATHCONTAINERS_R21_COMPAT
404  return m_container;
405 #else
406  SG::AuxVectorData* cont ATLAS_THREAD_SAFE = const_cast<SG::AuxVectorData*> (ConstAuxElement::container());
407  return cont;
408 #endif
409 }
410 
411 
412 //******************************************************************************
413 
414 
415 /**
416  * @brief Fetch an aux data variable, as a non-const reference.
417  * @param name Name of the aux variable.
418  * @param clsname The name of the associated class. May be blank.
419  *
420  * This method has to translate from the aux data name to the internal
421  * representation each time it is called. Using this method
422  * inside of loops is discouraged; instead use the @c Accessor class.
423  */
424 template <class T, class ALLOC>
425 typename Accessor<T, ALLOC>::reference_type
426 AuxElement::auxdata (const std::string& name)
427 {
428  return Accessor<T, ALLOC>(name, "")(*this);
429 }
430 
431 
432 /**
433  * @brief Fetch an aux data variable, as a non-const reference.
434  * @param name Name of the aux variable.
435  * @param clsname The name of the associated class. May be blank.
436  *
437  * This method has to translate from the aux data name to the internal
438  * representation each time it is called. Using this method
439  * inside of loops is discouraged; instead use the @c Accessor class.
440  */
441 template <class T, class ALLOC>
442 typename Accessor<T, ALLOC>::reference_type
443 AuxElement::auxdata (const std::string& name,
444  const std::string& clsname)
445 {
446  return Accessor<T, ALLOC>(name, clsname)(*this);
447 }
448 
449 
450 /**
451  * @brief Fetch an aux data variable, as a const reference.
452  * @param name Name of the aux variable.
453  *
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.
458  */
459 template <class T, class ALLOC>
460 typename Accessor<T, ALLOC>::const_reference_type
461 AuxElement::auxdata (const std::string& name) const
462 {
463  return Accessor<T, ALLOC>(name, "")(*this);
464 }
465 
466 
467 /**
468  * @brief Fetch an aux data variable, as a const reference.
469  * @param name Name of the aux variable.
470  * @param clsname The name of the associated class. May be blank.
471  *
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 Accessor
475  * or @c ConstAccessor classes.
476  */
477 template <class T, class ALLOC>
478 typename Accessor<T, ALLOC>::const_reference_type
479 AuxElement::auxdata (const std::string& name,
480  const std::string& clsname) const
481 {
482  return Accessor<T, ALLOC>(name, clsname)(*this);
483 }
484 
485 
486 /**
487  * @brief Fetch an aux data variable, as a const reference.
488  * @param name Name of the aux variable.
489  *
490  * This method has to translate from the aux data name to the internal
491  * representation each time it is called. Using this method
492  * inside of loops is discouraged; instead use the @c ConstAccessor class.
493  */
494 template <class T, class ALLOC>
495 typename Accessor<T, ALLOC>::const_reference_type
496 AuxElement::auxdataConst (const std::string& name) const
497 {
498  return Accessor<T, ALLOC>(name, "")(*this);
499 }
500 
501 
502 /**
503  * @brief Fetch an aux data variable, as a const reference.
504  * @param name Name of the aux variable.
505  * @param clsname The name of the associated class. May be blank.
506  *
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 ConstAccessor class.
510  */
511 template <class T, class ALLOC>
512 typename Accessor<T, ALLOC>::const_reference_type
513 AuxElement::auxdataConst (const std::string& name,
514  const std::string& clsname) const
515 {
516  return Accessor<T, ALLOC>(name, clsname)(*this);
517 }
518 
519 
520 /**
521  * @brief Check if an aux variable is available for reading
522  * @param name Name of the aux variable.
523  * @param clsname The name of the associated class. May be blank.
524  *
525  * This method has to translate from the aux data name to the internal
526  * representation each time it is called. Using this method
527  * inside of loops is discouraged; instead use the @c Accessor class.
528  */
529 template <class T, class ALLOC>
530 bool AuxElement::isAvailable (const std::string& name,
531  const std::string& clsname /*= ""*/) const
532 {
533  return Accessor<T, ALLOC>(name, clsname).isAvailable(*this);
534 }
535 
536 
537 /**
538  * @brief Check if an aux variable is available for writing
539  * @param name Name of the aux variable.
540  * @param clsname The name of the associated class. May be blank.
541  *
542  * This method has to translate from the aux data name to the internal
543  * representation each time it is called. Using this method
544  * inside of loops is discouraged; instead use the @c Accessor class.
545  */
546 template <class T, class ALLOC>
547 bool AuxElement::isAvailableWritable (const std::string& name,
548  const std::string& clsname /*= ""*/)
549 {
550  return Accessor<T, ALLOC>(name, clsname).isAvailableWritable(*this);
551 }
552 
553 
554 /**
555  * @brief Check if an aux variable is available for writing as a decoration.
556  * @param name Name of the aux variable.
557  * @param clsname The name of the associated class. May be blank.
558  *
559  * This method has to translate from the aux data name to the internal
560  * representation each time it is called. Using this method
561  * inside of loops is discouraged; instead use the @c Accessor class.
562  */
563 template <class T, class ALLOC>
564 bool AuxElement::isAvailableWritableAsDecoration (const std::string& name,
565  const std::string& clsname /*= ""*/) const
566 {
567  return Decorator<T, ALLOC>(name, clsname).isAvailableWritable(*this);
568 }
569 
570 
571 /**
572  * @brief Fetch an aux decoration, as a non-const reference.
573  * @param name Name of the aux variable.
574  * @param clsname The name of the associated class. May be blank.
575  *
576  * This method has to translate from the aux data name to the internal
577  * representation each time it is called. Using this method
578  * inside of loops is discouraged; instead use the @c Accessor class.
579  *
580  * If the container is locked, this will allow fetching only variables
581  * that do not yet exist (in which case they will be marked as decorations)
582  * or variables already marked as decorations.
583  */
584 template <class T, class ALLOC>
585 typename Decorator<T, ALLOC>::reference_type
586 AuxElement::auxdecor (const std::string& name) const
587 {
588  return Decorator<T, ALLOC>(name, "")(*this);
589 }
590 
591 
592 /**
593  * @brief Fetch an aux decoration, as a non-const reference.
594  * @param name Name of the aux variable.
595  * @param clsname The name of the associated class. May be blank.
596  *
597  * This method has to translate from the aux data name to the internal
598  * representation each time it is called. Using this method
599  * inside of loops is discouraged; instead use the @c Accessor class.
600  *
601  * If the container is locked, this will allow fetching only variables
602  * that do not yet exist (in which case they will be marked as decorations)
603  * or variables already marked as decorations.
604  */
605 template <class T, class ALLOC>
606 typename Decorator<T, ALLOC>::reference_type
607 AuxElement::auxdecor (const std::string& name,
608  const std::string& clsname) const
609 {
610  return Decorator<T, ALLOC>(name, clsname)(*this);
611 }
612 
613 
614 /**
615  * @brief Create a new private store for this object and copy aux data.
616  * @param other The object from which aux data should be copied.
617  * @param warnUnlocked If true, then warn when we skip unlocked decorations.
618  *
619  * @c ExcBadPrivateStore will be thrown if this object is already
620  * associated with a store.
621  *
622  * If @c other is an object that has aux data, then those data will
623  * be copied; otherwise, nothing will be done.
624  */
625 template <class U1>
626 inline
627 void AuxElement::makePrivateStore (const U1& other,
628  bool warnUnlocked /*=false*/)
629 {
630  // Dispatch to the proper overload depending on whether or not
631  // other derives from AuxElement.
632  makePrivateStore1 (&other, warnUnlocked);
633 }
634 
635 
636 /**
637  * @brief Create a new private store for this object and copy aux data.
638  * @param other The object from which aux data should be copied.
639  * @param warnUnlocked If true, then warn when we skip unlocked decorations.
640  *
641  * @c ExcBadPrivateStore will be thrown if this object is already
642  * associated with a store.
643  *
644  * If @c other is an object that has aux data, then those data will
645  * be copied; otherwise, nothing will be done.
646  */
647 template <class U1>
648 inline
649 void AuxElement::makePrivateStore (const U1* other,
650  bool warnUnlocked /*=false*/)
651 {
652  // Dispatch to the proper overload depending on whether or not
653  // other derives from AuxElement.
654  makePrivateStore1 (other, warnUnlocked);
655 }
656 
657 
658 /**
659  * @brief Synonym for @c setStore with @c IConstAuxStore.
660  * @param store The new store.
661  */
662 inline
663 void AuxElement::setConstStore (const SG::IConstAuxStore* store)
664 {
665  setStore (store);
666 }
667 
668 
669 /**
670  * @brief Synonym for @c setStore with @c IAuxStore.
671  * @param store The new store.
672  */
673 inline
674 void AuxElement::setNonConstStore (SG::IAuxStore* store)
675 {
676  setStore (store);
677 }
678 
679 
680 /**
681  * @brief Return true if index tracking is enabled for this object.
682  *
683  * Always returns true. Included here to be consistent with AuxVectorBase
684  * when standalone objects may be used as template parameters.
685  */
686 inline
687 bool AuxElement::trackIndices() const
688 {
689  return true;
690 }
691 
692 
693 /**
694  * @brief Set the index/container for this element.
695  * @param index The index of this object within the container.
696  * @param container The container holding this object.
697  * May be null if this object is being removed
698  * from a container.
699  *
700  * Usually this simply sets the index and container members
701  * of this object. However, in the case where this object has
702  * an associated private store, then we need to deal with
703  * releasing the store if the object is being added to a container,
704  * or making a new store if the object is being removed from a container.
705  */
706 inline
707 void AuxElement::setIndex (size_t index, SG::AuxVectorData* container)
708 {
709 #ifdef ATHCONTAINERS_R21_COMPAT
710  if (ATHCONTAINERS_UNLIKELY (!noPrivateData())) {
711  // out-of-line piece, dealing with private store.
712  setIndexPrivate (index, container);
713  return;
714  }
715 
716  IAuxElement::setIndex (index);
717  m_container = container;
718 #else
719  ConstAuxElement::setIndex (index, container);
720 #endif
721 }
722 
723 
724 /**
725  * @brief Create a new private store for this object and copy aux data.
726  * @param other The object from which aux data should be copied.
727  *
728  * @c ExcBadPrivateStore will be thrown if this object is already
729  * associated with a store.
730  *
731  * This overload handles the case where @c other does not have aux data.
732  */
733 inline
734 void AuxElement::makePrivateStore1 (const void*, bool)
735 {
736  makePrivateStore();
737 }
738 
739 
740 } // namespace SG