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  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.
337  this->clearAux();
338  }
339  else {
340  // Copying from an object with aux data.
341  // Copy the aux data too.
342  this->copyAux (other);
343  }
344  }
345  }
346  return *this;
347 }
348 
349 
350 /**
351  * @brief Destructor.
352  *
353  * Any private store is deleted.
354  */
355 inline
356 AuxElement::~AuxElement()
357 {
358 #ifdef ATHCONTAINERS_R21_COMPAT
359  if (ATHCONTAINERS_UNLIKELY (!noPrivateData()))
360  releasePrivateStoreForDtor();
361 #endif
362 }
363 
364 
365 /**
366  * @brief Return the container holding this element.
367  */
368 inline
369 const SG::AuxVectorData* AuxElement::container() const
370 {
371 #ifdef ATHCONTAINERS_R21_COMPAT
372  return m_container;
373 #else
374  return ConstAuxElement::container();
375 #endif
376 }
377 
378 
379 /**
380  * @brief Return the container holding this element.
381  */
382 inline
383 SG::AuxVectorData* AuxElement::container()
384 {
385 #ifdef ATHCONTAINERS_R21_COMPAT
386  return m_container;
387 #else
388  SG::AuxVectorData* cont ATLAS_THREAD_SAFE = const_cast<SG::AuxVectorData*> (ConstAuxElement::container());
389  return cont;
390 #endif
391 }
392 
393 
394 //******************************************************************************
395 
396 
397 /**
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.
401  *
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.
405  */
406 template <class T, class ALLOC>
407 typename Accessor<T, ALLOC>::reference_type
408 AuxElement::auxdata (const std::string& name)
409 {
410  return Accessor<T, ALLOC>(name, "")(*this);
411 }
412 
413 
414 /**
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.
418  *
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.
422  */
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)
427 {
428  return Accessor<T, ALLOC>(name, clsname)(*this);
429 }
430 
431 
432 /**
433  * @brief Fetch an aux data variable, as a const reference.
434  * @param name Name of the aux variable.
435  *
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.
440  */
441 template <class T, class ALLOC>
442 typename Accessor<T, ALLOC>::const_reference_type
443 AuxElement::auxdata (const std::string& name) const
444 {
445  return Accessor<T, ALLOC>(name, "")(*this);
446 }
447 
448 
449 /**
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.
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,
462  const std::string& clsname) const
463 {
464  return Accessor<T, ALLOC>(name, clsname)(*this);
465 }
466 
467 
468 /**
469  * @brief Fetch an aux data variable, as a const reference.
470  * @param name Name of the aux variable.
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 ConstAccessor class.
475  */
476 template <class T, class ALLOC>
477 typename Accessor<T, ALLOC>::const_reference_type
478 AuxElement::auxdataConst (const std::string& name) const
479 {
480  return Accessor<T, ALLOC>(name, "")(*this);
481 }
482 
483 
484 /**
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.
488  *
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.
492  */
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
497 {
498  return Accessor<T, ALLOC>(name, clsname)(*this);
499 }
500 
501 
502 /**
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.
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 Accessor class.
510  */
511 template <class T, class ALLOC>
512 bool AuxElement::isAvailable (const std::string& name,
513  const std::string& clsname /*= ""*/) const
514 {
515  return Accessor<T, ALLOC>(name, clsname).isAvailable(*this);
516 }
517 
518 
519 /**
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.
523  *
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.
527  */
528 template <class T, class ALLOC>
529 bool AuxElement::isAvailableWritable (const std::string& name,
530  const std::string& clsname /*= ""*/)
531 {
532  return Accessor<T, ALLOC>(name, clsname).isAvailableWritable(*this);
533 }
534 
535 
536 /**
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.
540  *
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.
544  */
545 template <class T, class ALLOC>
546 bool AuxElement::isAvailableWritableAsDecoration (const std::string& name,
547  const std::string& clsname /*= ""*/) const
548 {
549  return Decorator<T, ALLOC>(name, clsname).isAvailableWritable(*this);
550 }
551 
552 
553 /**
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.
557  *
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.
561  *
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.
565  */
566 template <class T, class ALLOC>
567 typename Decorator<T, ALLOC>::reference_type
568 AuxElement::auxdecor (const std::string& name) const
569 {
570  return Decorator<T, ALLOC>(name, "")(*this);
571 }
572 
573 
574 /**
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.
578  *
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.
582  *
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.
586  */
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
591 {
592  return Decorator<T, ALLOC>(name, clsname)(*this);
593 }
594 
595 
596 /**
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.
599  *
600  * @c ExcBadPrivateStore will be thrown if this object is already
601  * associated with a store.
602  *
603  * If @c other is an object that has aux data, then those data will
604  * be copied; otherwise, nothing will be done.
605  */
606 template <class U1>
607 inline
608 void AuxElement::makePrivateStore (const U1& other)
609 {
610  // Dispatch to the proper overload depending on whether or not
611  // other derives from AuxElement.
612  makePrivateStore1 (&other);
613 }
614 
615 
616 /**
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.
619  *
620  * @c ExcBadPrivateStore will be thrown if this object is already
621  * associated with a store.
622  *
623  * If @c other is an object that has aux data, then those data will
624  * be copied; otherwise, nothing will be done.
625  */
626 template <class U1>
627 inline
628 void AuxElement::makePrivateStore (const U1* other)
629 {
630  // Dispatch to the proper overload depending on whether or not
631  // other derives from AuxElement.
632  makePrivateStore1 (other);
633 }
634 
635 
636 /**
637  * @brief Synonym for @c setStore with @c IConstAuxStore.
638  * @param store The new store.
639  */
640 inline
641 void AuxElement::setConstStore (const SG::IConstAuxStore* store)
642 {
643  setStore (store);
644 }
645 
646 
647 /**
648  * @brief Synonym for @c setStore with @c IAuxStore.
649  * @param store The new store.
650  */
651 inline
652 void AuxElement::setNonConstStore (SG::IAuxStore* store)
653 {
654  setStore (store);
655 }
656 
657 
658 /**
659  * @brief Return true if index tracking is enabled for this object.
660  *
661  * Always returns true. Included here to be consistent with AuxVectorBase
662  * when standalone objects may be used as template parameters.
663  */
664 inline
665 bool AuxElement::trackIndices() const
666 {
667  return true;
668 }
669 
670 
671 /**
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
676  * from a container.
677  *
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.
683  */
684 inline
685 void AuxElement::setIndex (size_t index, SG::AuxVectorData* container)
686 {
687 #ifdef ATHCONTAINERS_R21_COMPAT
688  if (ATHCONTAINERS_UNLIKELY (!noPrivateData())) {
689  // out-of-line piece, dealing with private store.
690  setIndexPrivate (index, container);
691  return;
692  }
693 
694  IAuxElement::setIndex (index);
695  m_container = container;
696 #else
697  ConstAuxElement::setIndex (index, container);
698 #endif
699 }
700 
701 
702 /**
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.
705  *
706  * @c ExcBadPrivateStore will be thrown if this object is already
707  * associated with a store.
708  *
709  * This overload handles the case where @c other does not have aux data.
710  */
711 inline
712 void AuxElement::makePrivateStore1 (const void*)
713 {
714  makePrivateStore();
715 }
716 
717 
718 } // namespace SG