ATLAS Offline Software
Loading...
Searching...
No Matches
ViewVectorBase.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4/**
5 * @file ViewVectorBase.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Sep, 2016
8 * @brief Hold the persistent representation for a ViewVector.
9 */
10
11
12#include "AthContainers/AuxElement.h"
13#include "AthContainers/CurrentContext.h"
14#include "CxxUtils/checker_macros.h"
15#include <type_traits>
16
17
18namespace {
19
20
21template <class T>
22inline
23SG::AuxVectorData* getContainer1 (T* p, const std::true_type&)
24{
25 return p->container();
26}
27template <class T>
28inline
29SG::AuxVectorData* getContainer1 (T*, const std::false_type&)
30{
31 return nullptr;
32}
33
34
35/**
36 * @brief Return the container for an element.
37 *
38 * Returns null if the element does not derive from AuxElement.
39 */
40template <class T>
41inline
42SG::AuxVectorData* getContainer (T* p)
43{
44 return getContainer1 (p, typename std::is_base_of<SG::AuxElement, T>::type());
45}
46
47
48} // anonymous namespace
49
50
51namespace SG {
52
53
54/**
55 * @brief Clear the persistent data.
56 */
57inline
58void ViewVectorBase::clearPersistent()
59{
60 m_persKey.clear();
61 m_persIndex.clear();
62}
63
64
65/**
66 * @brief Set a flag to declare that the vector should be cleared
67 * on the next call to toPersistent().
68 *
69 * This would be used in the case where we make a copy of the
70 * object being written.
71 */
72inline
73void ViewVectorBase::setClearOnPersistent()
74{
75 m_clearOnPersistent = true;
76}
77
78
79/**
80 * @brief Convert to persistent form.
81 * @param v The vector to convert.
82 *
83 * Called for classes that have a CLID.
84 */
85template <class DV>
86void
87ViewVectorBase::doToPersistent1 (DV& v, const std::true_type&)
88{
89 std::vector<ElementLink<DV> > elv = SG::dataVectorAsELV (v, Gaudi::Hive::currentContext());
90 m_persKey.clear();
91 m_persIndex.clear();
92 m_persKey.reserve (elv.size());
93 m_persIndex.reserve (elv.size());
94 for (ElementLinkBase& el : elv) {
95#ifdef XAOD_STANDALONE
96 m_persKey.push_back (el.persKey());
97 m_persIndex.push_back (el.persIndex());
98#else
99 el.thin();
100 m_persKey.push_back (el.key());
101 m_persIndex.push_back (el.index());
102#endif
103 }
104 if (m_clearOnPersistent) {
105 v.clear();
106 m_clearOnPersistent = false;
107 }
108}
109
110
111/**
112 * @brief Convert to persistent form.
113 * @param v The vector to convert.
114 *
115 * Called for classes that do not have a CLID.
116 * This will simply abort.
117 */
118template <class DV>
119inline
120void ViewVectorBase::doToPersistent1 (DV&, const std::false_type&)
121{
122 std::abort();
123}
124
125
126/**
127 * @brief Convert to persistent form.
128 * @param v The vector to convert.
129 *
130 * This will abort if called for a class with no CLID.
131 */
132template <class DV>
133inline
134void ViewVectorBase::doToPersistent (DV& v)
135{
136 // Dispatch depending on whether or not DV has a CLID.
137 doToPersistent1 (v,
138#ifdef XAOD_STANDALONE
139 std::true_type()
140#else
141 typename ClassID_traits<DV>::has_classID_tag()
142#endif
143 );
144}
145
146
147/**
148 * @brief Convert to transient form.
149 * @param v The vector to fill in.
150 *
151 * Called for classes that have a CLID if DV is not a ConstDataVector.
152 */
153template <class DV>
154void ViewVectorBase::doToTransient2 (DV& v, const std::true_type&)
155{
156 // The custom DataVector collection proxy will have created elements here,
157 // so we need to delete them to avoid a memory leak.
158 // FIXME: It should be possible to avoid creating the elements
159 // in the first place, at least for the usual case xAOD where the elements
160 // themselves have no persistent data.
161 if (v.ownPolicy() == SG::VIEW_ELEMENTS) {
162 for (typename DV::value_type p : v) {
163 // Try to protect against deleting an unowned object in the case
164 // where this gets called multiple times on the same object.
165 // The dummy elements will have null container pointers, while
166 // those that we've retrieved through EL resolution below should
167 // have the container pointer set. Can only do this check, though,
168 // for types with aux data.
169 if (getContainer(p) == nullptr)
170 delete p;
171 }
172 }
173 v.clear (SG::VIEW_ELEMENTS);
174 const EventContext& ctx = Gaudi::Hive::currentContext();
175
176 assert (m_persKey.size() == m_persIndex.size());
177 for (size_t i = 0; i < m_persKey.size(); i++) {
178 ElementLink<DV> el (m_persKey[i], m_persIndex[i], ctx);
179 // FIXME: const_cast
180 typename DV::value_type p ATLAS_THREAD_SAFE = const_cast<typename DV::value_type> (*el);
181 v.push_back (p);
182 }
183}
184
185
186} // namespace SG
187
188