ATLAS Offline Software
Loading...
Searching...
No Matches
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
18namespace SG {
19
20
21/**
22 * @brief Default constructor.
23 */
24inline
25ConstAuxElement::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 */
38inline
39ConstAuxElement::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 */
57inline
58ConstAuxElement::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 */
70inline
71ConstAuxElement::~ConstAuxElement()
72{
73 if (ATHCONTAINERS_UNLIKELY (!noPrivateData()))
74 releasePrivateStoreForDtor();
75}
76
77
78/**
79 * @brief Return the container holding this element.
80 */
81inline
82const 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 */
101inline
102void 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 */
125template <class T, class ALLOC>
126typename ConstAccessor<T, ALLOC>::const_reference_type
127ConstAuxElement::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 */
143template <class T, class ALLOC>
144typename ConstAccessor<T, ALLOC>::const_reference_type
145ConstAuxElement::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 */
160template <class T, class ALLOC>
161typename ConstAccessor<T, ALLOC>::const_reference_type
162ConstAuxElement::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 */
177template <class T, class ALLOC>
178typename ConstAccessor<T, ALLOC>::const_reference_type
179ConstAuxElement::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 */
195template <class T, class ALLOC>
196bool 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 */
212template <class T, class ALLOC>
213bool 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 */
233template <class T, class ALLOC>
234typename Decorator<T, ALLOC>::reference_type
235ConstAuxElement::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 */
254template <class T, class ALLOC>
255typename Decorator<T, ALLOC>::reference_type
256ConstAuxElement::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 */
269inline
270AuxElement::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 */
285inline
286AuxElement::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 */
308inline
309AuxElement::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 */
329inline
330AuxElement& 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 */
347inline
348void 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 */
373inline
374AuxElement::~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 */
386inline
387const 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 */
400inline
401SG::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 */
424template <class T, class ALLOC>
425typename Accessor<T, ALLOC>::reference_type
426AuxElement::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 */
441template <class T, class ALLOC>
442typename Accessor<T, ALLOC>::reference_type
443AuxElement::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 */
459template <class T, class ALLOC>
460typename Accessor<T, ALLOC>::const_reference_type
461AuxElement::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 */
477template <class T, class ALLOC>
478typename Accessor<T, ALLOC>::const_reference_type
479AuxElement::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 */
494template <class T, class ALLOC>
495typename Accessor<T, ALLOC>::const_reference_type
496AuxElement::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 */
511template <class T, class ALLOC>
512typename Accessor<T, ALLOC>::const_reference_type
513AuxElement::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 */
529template <class T, class ALLOC>
530bool 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 */
546template <class T, class ALLOC>
547bool 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 */
563template <class T, class ALLOC>
564bool 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 */
584template <class T, class ALLOC>
585typename Decorator<T, ALLOC>::reference_type
586AuxElement::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 */
605template <class T, class ALLOC>
606typename Decorator<T, ALLOC>::reference_type
607AuxElement::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 */
625template <class U1>
626inline
627void 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 */
647template <class U1>
648inline
649void 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 */
662inline
663void 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 */
673inline
674void 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 */
686inline
687bool 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 */
706inline
707void 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 */
733inline
734void AuxElement::makePrivateStore1 (const void*, bool)
735{
736 makePrivateStore();
737}
738
739
740} // namespace SG