2 Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
7 * @file ViewVectorBase.icc
8 * @author scott snyder <snyder@bnl.gov>
10 * @brief Hold the persistent representation for a ViewVector.
14 #include "AthContainers/AuxElement.h"
15 #include "CxxUtils/checker_macros.h"
16 #include <type_traits>
24 SG::AuxVectorData* getContainer1 (T* p, const std::true_type&)
26 return p->container();
30 SG::AuxVectorData* getContainer1 (T*, const std::false_type&)
37 * @brief Return the container for an element.
39 * Returns null if the element does not derive from AuxElement.
43 SG::AuxVectorData* getContainer (T* p)
45 return getContainer1 (p, typename std::is_base_of<SG::AuxElement, T>::type());
49 } // anonymous namespace
56 * @brief Clear the persistent data.
59 void ViewVectorBase::clearPersistent()
67 * @brief Set a flag to declare that the vector should be cleared
68 * on the next call to toPersistent().
70 * This would be used in the case where we make a copy of the
71 * object being written.
74 void ViewVectorBase::setClearOnPersistent()
76 m_clearOnPersistent = true;
81 * @brief Convert to persistent form.
82 * @param v The vector to convert.
84 * Called for classes that have a CLID.
88 ViewVectorBase::doToPersistent1 (DV& v, const std::true_type&)
90 IProxyDict* store = SG::CurrentEventStore::store();
91 std::vector<ElementLink<DV> > elv = SG::dataVectorAsELV (v, store);
94 m_persKey.reserve (elv.size());
95 m_persIndex.reserve (elv.size());
96 for (ElementLinkBase& el : elv) {
97 #ifdef XAOD_STANDALONE
98 m_persKey.push_back (el.persKey());
99 m_persIndex.push_back (el.persIndex());
102 m_persKey.push_back (el.key());
103 m_persIndex.push_back (el.index());
106 if (m_clearOnPersistent) {
108 m_clearOnPersistent = false;
114 * @brief Convert to persistent form.
115 * @param v The vector to convert.
117 * Called for classes that do not have a CLID.
118 * This will simply abort.
122 void ViewVectorBase::doToPersistent1 (DV&, const std::false_type&)
129 * @brief Convert to persistent form.
130 * @param v The vector to convert.
132 * This will abort if called for a class with no CLID.
136 void ViewVectorBase::doToPersistent (DV& v)
138 // Dispatch depending on whether or not DV has a CLID.
140 #ifdef XAOD_STANDALONE
143 typename ClassID_traits<DV>::has_classID_tag()
150 * @brief Convert to transient form.
151 * @param v The vector to fill in.
153 * Called for classes that have a CLID if DV is not a ConstDataVector.
156 void ViewVectorBase::doToTransient2 (DV& v, const std::true_type&)
158 // The custom DataVector collection proxy will have created elements here,
159 // so we need to delete them to avoid a memory leak.
160 // FIXME: It should be possible to avoid creating the elements
161 // in the first place, at least for the usual case xAOD where the elements
162 // themselves have no persistent data.
163 if (v.ownPolicy() == SG::VIEW_ELEMENTS) {
164 for (typename DV::value_type p : v) {
165 // Try to protect against deleting an unowned object in the case
166 // where this gets called multiple times on the same object.
167 // The dummy elements will have null container pointers, while
168 // those that we've retrieved through EL resolution below should
169 // have the container pointer set. Can only do this check, though,
170 // for types with aux data.
171 if (getContainer(p) == nullptr)
175 v.clear (SG::VIEW_ELEMENTS);
176 IProxyDict* store = SG::CurrentEventStore::store();
178 assert (m_persKey.size() == m_persIndex.size());
179 for (size_t i = 0; i < m_persKey.size(); i++) {
180 ElementLink<DV> el (m_persKey[i], m_persIndex[i], store);
182 typename DV::value_type p ATLAS_THREAD_SAFE = const_cast<typename DV::value_type> (*el);