ATLAS Offline Software
Loading...
Searching...
No Matches
DVLDataBucket.icc
Go to the documentation of this file.
1// This file's extension implies that it's C, but it's really -*- C++ -*-.
2
3/*
4 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
5*/
6/**
7 * @file AthContainers/tools/DVLDataBucket.icc
8 * @author scott snyder
9 * @date Mar 2008
10 * @brief A @c DataBucket specialized for @c DataVector/@c DataList.
11 *
12 * Template and inline implementations.
13 */
14
15
16#include "AthContainers/exceptions.h"
17#include "AthenaKernel/IRegisterTransient.h"
18
19
20namespace SG {
21
22
23/**
24 * @brief Is a @c DataVector we're trying to record actually a @c ViewVector?
25 * @param data Object being recorded.
26 * @param[out] clid If the object is a @c ViewVector, set to the CLID
27 * of that class. Otherwise unchanged.
28 * @returns The @c type_info for the object being recorded, either the
29 * @c DataVector or a @c ViewVector that derives from it.
30 */
31template <class T>
32const std::type_info* testViewVector (const DataVector<T>& data,
33 CLID& clid)
34{
35 // If this is a view container, test for @c ViewVector.
36 if (data.ownPolicy() == SG::VIEW_ELEMENTS) {
37 // See if we actually have a @c ViewVector.
38 // FIXME: This doesn't work if @c ViewVector is templated on an intermediate
39 // class rather than @c DataVector directly.
40 if (dynamic_cast<const ViewVector<DataVector<T> >*> (&data)) {
41 const std::type_info& ti = typeid(ViewVector<DataVector<T> >);
42 const SG::BaseInfoBase* bib = SG::BaseInfoBase::find (ti);
43 if (bib) {
44 clid = bib->clid();
45 if (clid == CLID_NULL)
46 SG::throwExcMissingViewVectorCLID (ti);
47 return &ti;
48 }
49 else {
50 SG::throwExcMissingBaseInfo (ti);
51 }
52 }
53 }
54 return &typeid(DataVector<T>);
55}
56
57
58/**
59 * @brief Is a @c DataVector we're trying to record actually a @c ViewVector?
60 *
61 * Handle the case where the object being recorded is not a @c DataVector.
62 */
63template <class T>
64const std::type_info* testViewVector (const T& ,
65 CLID& )
66{
67 return &typeid(T);
68}
69
70
71/**
72 * @brief Constructor from a payload object.
73 * @param data Object to hold in the bucket.
74 */
75template <class T>
76DVLDataBucket<T>::DVLDataBucket (T* data)
77 : DataBucket<T> (data)
78{
79 // cppcheck-suppress useInitializationList
80 m_clid = DataBucket<T>::classID();
81 m_ti = testViewVector (*this->ptr(), m_clid);
82}
83
84
85/**
86 * @brief Constructor from a payload object.
87 * @param data Object to hold in the bucket.
88 */
89template <class T>
90template <class U>
91DVLDataBucket<T>::DVLDataBucket (std::unique_ptr<U> data)
92 : DataBucket<T> (std::move (data))
93{
94 // cppcheck-suppress useInitializationList
95 m_clid = DataBucket<T>::classID();
96 // cppcheck-suppress missingReturn; false positive
97 m_ti = testViewVector (*this->ptr(), m_clid);
98}
99
100
101/**
102 * @brief Copy constructor.
103 * @param other Bucket to copy.
104 */
105template <typename T>
106DVLDataBucket<T>::DVLDataBucket (const DVLDataBucket& other)
107 : SG::DataBucket<T> (new T (*other.cptr())),
108 m_copies (other.m_copies),
109 m_ti (other.m_ti),
110 m_clid (other.m_clid)
111{
112 // Make a copy of each of the copies.
113 vec_t::iterator end = m_copies.end();
114 for (vec_t::iterator it = m_copies.begin(); it != end; ++it) {
115 it->second = it->first->clone (it->second);
116 }
117}
118
119
120/**
121 * @brief Destructor.
122 */
123template <typename T>
124DVLDataBucket<T>::~DVLDataBucket()
125{
126 // Delete any copies.
127 vec_t::iterator end = m_copies.end();
128 for (vec_t::iterator it = m_copies.begin(); it != end; ++it) {
129 it->first->del (it->second);
130 }
131}
132
133
134/**
135 * @brief Return the contents of the @c DataBucket,
136 * converted to type given by @a clid. Note that only
137 * derived->base conversions are allowed here.
138 * @param clid The class ID to which to convert.
139 * @param irt To be called if we make a new instance.
140 * @param isConst True if the object being converted is regarded as const.
141 */
142template <typename T>
143void*
144DVLDataBucket<T>::cast (CLID clid, IRegisterTransient* irt /*= 0*/,
145 bool /*isConst = true*/)
146{
147 // Test for trivial conversion.
148 // FIXME: Assumes we can reinterpret_cast between DV* and ViewVector<DV>*.
149 if ((clid == m_clid) || clid == DataBucket<T>::classID()) [[likely]]
150 return this->ptr();
151
152 // Try looking for a true base conversion,
153 // first using static SG_BASES information.
154 // This can all be unfolded at compile time, so is fast, but
155 // doesn't take into account SG_ADD_BASES.
156 void* ret = this->tryStaticConversion (clid);
157 if (ret) {
158 return ret;
159 }
160
161 T* ptr = this->ptr();
162
163 // Then try using BaseInfo, in case of SG_ADD_BASES.
164 ret = SG::BaseInfo<T>::cast (ptr, clid);
165 if (ret) {
166 return ret;
167 }
168
169 // See if we've already made an instance for this type.
170 // We don't expect to have more than a few, so no point in doing
171 // anything more complicated than a linear search.
172 vec_t::iterator end = m_copies.end();
173 for (vec_t::iterator it = m_copies.begin(); it != end; ++it) {
174 if (clid == it->first->clid()) {
175 // Recopy the elements if the container size has changed.
176 if (it->first->size (it->second) != ptr->size()) {
177 dvl_update (*ptr, it->second, it->first);
178 }
179 return it->second;
180 }
181 }
182
183 // Try to do a copying conversion.
184 DataModel_detail::DVLInfoBase* info;
185 void* newcont = dvl_convert (*ptr, clid, info);
186 if (newcont) {
187 m_copies.push_back (std::make_pair (info, newcont));
188 irt->registerTransient (newcont);
189 }
190
191 return newcont;
192}
193
194
195/**
196 * @brief Return the contents of the @c DataBucket,
197 * converted to type given by @a std::type_info. Note that only
198 * derived->base conversions are allowed here.
199 * @param clid The @a std::type_info of the type to which to convert.
200 * @param irt To be called if we make a new instance.
201 * @param isConst True if the object being converted is regarded as const.
202 */
203template <typename T>
204void*
205DVLDataBucket<T>::cast (const std::type_info& tinfo,
206 IRegisterTransient* irt /*= 0*/,
207 bool /*isConst = true*/)
208{
209 // Test for trivial conversion.
210 // FIXME: Assumes we can reinterpret_cast between DV* and ViewVector<DV>*.
211 if ((&tinfo == m_ti) || tinfo == DataBucket<T>::tinfo()) [[likely]]
212 return this->ptr();
213
214 // Try looking for a true base conversion,
215 // first using static SG_BASES information.
216 // This can all be unfolded at compile time, so is fast, but
217 // doesn't take into account SG_ADD_BASES.
218 void* ret = this->tryStaticConversion (tinfo);
219 if (ret) {
220 return ret;
221 }
222
223 T* ptr = this->ptr();
224
225 // Try looking for a true base conversion.
226 ret = SG::BaseInfo<T>::cast (ptr, tinfo);
227 if (ret) {
228 return ret;
229 }
230
231 // See if we've already made an instance for this type.
232 // We don't expect to have more than a few, so no point in doing
233 // anything more complicated than a linear search.
234 vec_t::iterator end = m_copies.end();
235 for (vec_t::iterator it = m_copies.begin(); it != end; ++it) {
236 if (tinfo == it->first->tinfo()) {
237 // Recopy the elements if the container size has changed.
238 if (it->first->size (it->second) != ptr->size()) {
239 dvl_update (*ptr, it->second, it->first);
240 }
241 return it->second;
242 }
243 }
244
245 // Try to do a copying conversion.
246 DataModel_detail::DVLInfoBase* info;
247 void* newcont = dvl_convert (*ptr, tinfo, info);
248 if (newcont) {
249 m_copies.push_back (std::make_pair (info, newcont));
250 irt->registerTransient (newcont);
251 }
252
253 return newcont;
254}
255
256
257/**
258 * @brief Return the contents of the @c DataBucket,
259 * converted to type given by @a clid. Note that only
260 * derived->base conversions are allowed here.
261 * @param clid The class ID to which to convert.
262 * @param tinfo The @a std::type_info of the type to which to convert.
263 * @param irt To be called if we make a new instance.
264 * @param isConst True if the object being converted is regarded as const.
265 *
266 * This allows the callee to choose whether to use clid or tinfo.
267 * Here we use clid.
268 */
269template <typename T>
270inline
271void* DVLDataBucket<T>::cast (CLID clid,
272 const std::type_info& /*tinfo*/,
273 SG::IRegisterTransient* irt /*= 0*/,
274 bool isConst /*= true*/)
275{
276 return DVLDataBucket::cast (clid, irt, isConst);
277}
278
279
280/**
281 * @brief The CLID for the class of object we're holding.
282 *
283 * May be different from that of the base @c DataVector in the case
284 * of a @c ViewVector.
285 */
286template <typename T>
287const CLID& DVLDataBucket<T>::clID() const
288{
289 return m_clid;
290}
291
292
293/**
294 * @brief The std::type_info for the class of object we're holding.
295 *
296 * May be different from that of the base @c DataVector in the case
297 * of a @c ViewVector.
298 */
299template <typename T>
300const std::type_info& DVLDataBucket<T>::tinfo() const
301{
302 return *m_ti;
303}
304
305
306} // namespace SG