2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
5 * @file ViewVectorBase.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Hold the persistent representation for a ViewVector.
12#include "AthContainers/AuxElement.h"
13#include "AthContainers/CurrentContext.h"
14#include "CxxUtils/checker_macros.h"
23SG::AuxVectorData* getContainer1 (T* p, const std::true_type&)
25 return p->container();
29SG::AuxVectorData* getContainer1 (T*, const std::false_type&)
36 * @brief Return the container for an element.
38 * Returns null if the element does not derive from AuxElement.
42SG::AuxVectorData* getContainer (T* p)
44 return getContainer1 (p, typename std::is_base_of<SG::AuxElement, T>::type());
48} // anonymous namespace
55 * @brief Clear the persistent data.
58void ViewVectorBase::clearPersistent()
66 * @brief Set a flag to declare that the vector should be cleared
67 * on the next call to toPersistent().
69 * This would be used in the case where we make a copy of the
70 * object being written.
73void ViewVectorBase::setClearOnPersistent()
75 m_clearOnPersistent = true;
80 * @brief Convert to persistent form.
81 * @param v The vector to convert.
83 * Called for classes that have a CLID.
87ViewVectorBase::doToPersistent1 (DV& v, const std::true_type&)
89 std::vector<ElementLink<DV> > elv = SG::dataVectorAsELV (v, Gaudi::Hive::currentContext());
92 m_persKey.reserve (elv.size());
93 m_persIndex.reserve (elv.size());
94 for (ElementLinkBase& el : elv) {
96 m_persKey.push_back (el.persKey());
97 m_persIndex.push_back (el.persIndex());
100 m_persKey.push_back (el.key());
101 m_persIndex.push_back (el.index());
104 if (m_clearOnPersistent) {
106 m_clearOnPersistent = false;
112 * @brief Convert to persistent form.
113 * @param v The vector to convert.
115 * Called for classes that do not have a CLID.
116 * This will simply abort.
120void ViewVectorBase::doToPersistent1 (DV&, const std::false_type&)
127 * @brief Convert to persistent form.
128 * @param v The vector to convert.
130 * This will abort if called for a class with no CLID.
134void ViewVectorBase::doToPersistent (DV& v)
136 // Dispatch depending on whether or not DV has a CLID.
138#ifdef XAOD_STANDALONE
141 typename ClassID_traits<DV>::has_classID_tag()
148 * @brief Convert to transient form.
149 * @param v The vector to fill in.
151 * Called for classes that have a CLID if DV is not a ConstDataVector.
154void ViewVectorBase::doToTransient2 (DV& v, const std::true_type&)
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)
173 v.clear (SG::VIEW_ELEMENTS);
174 const EventContext& ctx = Gaudi::Hive::currentContext();
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);
180 typename DV::value_type p ATLAS_THREAD_SAFE = const_cast<typename DV::value_type> (*el);