ATLAS Offline Software
Loading...
Searching...
No Matches
ViewVectorBase.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
3*/
4
5// $Id$
6/**
7 * @file ViewVectorBase.icc
8 * @author scott snyder <snyder@bnl.gov>
9 * @date Sep, 2016
10 * @brief Hold the persistent representation for a ViewVector.
11 */
12
13
14#include "AthContainers/AuxElement.h"
15#include "CxxUtils/checker_macros.h"
16#include <type_traits>
17
18
19namespace {
20
21
22template <class T>
23inline
24SG::AuxVectorData* getContainer1 (T* p, const std::true_type&)
25{
26 return p->container();
27}
28template <class T>
29inline
30SG::AuxVectorData* getContainer1 (T*, const std::false_type&)
31{
32 return nullptr;
33}
34
35
36/**
37 * @brief Return the container for an element.
38 *
39 * Returns null if the element does not derive from AuxElement.
40 */
41template <class T>
42inline
43SG::AuxVectorData* getContainer (T* p)
44{
45 return getContainer1 (p, typename std::is_base_of<SG::AuxElement, T>::type());
46}
47
48
49} // anonymous namespace
50
51
52namespace SG {
53
54
55/**
56 * @brief Clear the persistent data.
57 */
58inline
59void ViewVectorBase::clearPersistent()
60{
61 m_persKey.clear();
62 m_persIndex.clear();
63}
64
65
66/**
67 * @brief Set a flag to declare that the vector should be cleared
68 * on the next call to toPersistent().
69 *
70 * This would be used in the case where we make a copy of the
71 * object being written.
72 */
73inline
74void ViewVectorBase::setClearOnPersistent()
75{
76 m_clearOnPersistent = true;
77}
78
79
80/**
81 * @brief Convert to persistent form.
82 * @param v The vector to convert.
83 *
84 * Called for classes that have a CLID.
85 */
86template <class DV>
87void
88ViewVectorBase::doToPersistent1 (DV& v, const std::true_type&)
89{
90 IProxyDict* store = SG::CurrentEventStore::store();
91 std::vector<ElementLink<DV> > elv = SG::dataVectorAsELV (v, store);
92 m_persKey.clear();
93 m_persIndex.clear();
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());
100#else
101 el.thin();
102 m_persKey.push_back (el.key());
103 m_persIndex.push_back (el.index());
104#endif
105 }
106 if (m_clearOnPersistent) {
107 v.clear();
108 m_clearOnPersistent = false;
109 }
110}
111
112
113/**
114 * @brief Convert to persistent form.
115 * @param v The vector to convert.
116 *
117 * Called for classes that do not have a CLID.
118 * This will simply abort.
119 */
120template <class DV>
121inline
122void ViewVectorBase::doToPersistent1 (DV&, const std::false_type&)
123{
124 std::abort();
125}
126
127
128/**
129 * @brief Convert to persistent form.
130 * @param v The vector to convert.
131 *
132 * This will abort if called for a class with no CLID.
133 */
134template <class DV>
135inline
136void ViewVectorBase::doToPersistent (DV& v)
137{
138 // Dispatch depending on whether or not DV has a CLID.
139 doToPersistent1 (v,
140#ifdef XAOD_STANDALONE
141 std::true_type()
142#else
143 typename ClassID_traits<DV>::has_classID_tag()
144#endif
145 );
146}
147
148
149/**
150 * @brief Convert to transient form.
151 * @param v The vector to fill in.
152 *
153 * Called for classes that have a CLID if DV is not a ConstDataVector.
154 */
155template <class DV>
156void ViewVectorBase::doToTransient2 (DV& v, const std::true_type&)
157{
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)
172 delete p;
173 }
174 }
175 v.clear (SG::VIEW_ELEMENTS);
176 IProxyDict* store = SG::CurrentEventStore::store();
177
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);
181 // FIXME: const_cast
182 typename DV::value_type p ATLAS_THREAD_SAFE = const_cast<typename DV::value_type> (*el);
183 v.push_back (p);
184 }
185}
186
187
188} // namespace SG
189
190