ATLAS Offline Software
Loading...
Searching...
No Matches
SingleAssociationToolMulti.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4/**
5 * @file D3PDMakerUtils/SingleAssociationToolMulti.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Jun, 2012
8 * @brief A specialization of SingleAssociationTool that can accept one
9 * of several types.
10 */
11
12
13//**************************************************************************
14// Single-argument specialization
15//
16
17
18namespace D3PD {
19
20
21/**
22 * @brief Standard Gaudi tool constructor.
23 * @param type The name of the tool type.
24 * @param name The tool name.
25 * @param parent The tool's Gaudi parent.
26 */
27template <class T0, class TO_T>
28SingleAssociationTool<Types<T0>, TO_T>::SingleAssociationTool
29 (const std::string& type,
30 const std::string& name,
31 const IInterface* parent)
32 : SingleAssociationToolTo<TO_T> (type, name, parent),
33 m_which(0),
34 m_fromTypeinfo(0)
35{
36}
37
38
39/**
40 * @brief Configure during initialization: type-check.
41 * @param tree Our parent for tuple making.
42 * @param ti Gives the type of the object being passed to @c fillUntyped.
43 *
44 * @c configureD3PD should check that the type of the object coming as input
45 * is compatible with what it expects, and raise an error otherwise.
46 */
47template <class T0, class TO_T>
48StatusCode
49SingleAssociationTool<Types<T0>, TO_T>::configureD3PD
50 (IAddVariable* tree,
51 const std::type_info& ti)
52{
53 std::vector<const std::type_info*> tis;
54 push_ti (tis);
55 StatusCode sc = this->configureMulti (tree, ti, tis, m_which);
56 if (m_which < tis.size())
57 m_fromTypeinfo = tis[m_which];
58 return sc;
59}
60
61
62/**
63 * @brief Return the @c std::type_info for the source of the association.
64 */
65template <class T0, class TO_T>
66const std::type_info&
67SingleAssociationTool<Types<T0>, TO_T>::fromTypeinfo() const
68{
69 return *m_fromTypeinfo;
70}
71
72
73/**
74 * @brief Return the @c std::type_info for the source of the association.
75 */
76template <class T0, class TO_T>
77const std::type_info&
78SingleAssociationTool<Types<T0>, TO_T>::typeinfo() const
79{
80 return doTypeinfo (0);
81}
82
83
84template <class T0, class TO_T>
85const std::type_info&
86SingleAssociationTool<Types<T0>, TO_T>::doTypeinfo (size_t /*count*/) const
87{
88 return typeid (typename SelectType<TO_T, 0>::type);
89}
90
91
92/**
93 * @brief Release an object retrieved from the association.
94 * @param p The object to release.
95 *
96 * Call this when you are done with the object returned by
97 * @c get(). The default implementation is a no-op,
98 * but if the association dynamically allocated the object which
99 * it returned, this gives it a chance to free it.
100 */
101template <class T0, class TO_T>
102inline
103void
104SingleAssociationTool<Types<T0>, TO_T>::releaseObject
105 (const typename SelectType<TO_T, 0>::type* /*p*/)
106{
107}
108
109
110/**
111 * @brief Release an object retrieved from the association.
112 * @param p The object to release.
113 *
114 * Call this when you are done with the object returned by
115 * @c getUntyped(). The default implementation is a no-op,
116 * but if the association dynamically allocated the object which
117 * it returned, this gives it a chance to free it.
118 */
119template <class T0, class TO_T>
120inline
121void
122SingleAssociationTool<Types<T0>, TO_T>::releaseObjectUntyped (const void* p)
123{
124 this->doReleaseObjectUntyped (p, 0);
125}
126
127
128template <class T0, class TO_T>
129inline
130void
131SingleAssociationTool<Types<T0>, TO_T>::doReleaseObjectUntyped (const void* p, size_t /*count*/)
132{
133 this->releaseObject (reinterpret_cast<const typename SelectType<TO_T, 0>::type*> (p));
134}
135
136
137/**
138 * @brief Return the target object.
139 * @param p The source object for the association.
140 *
141 * Return the target of the association, or 0.
142 * Should be of the type given by @c typeinfo.
143 */
144template <class T0, class TO_T>
145const void*
146SingleAssociationTool<Types<T0>, TO_T>::getUntyped
147 (const void* p)
148{
149 p = this->doConversion (p);
150 if (!p) return 0;
151 return doGetUntyped (p, 0);
152}
153
154
155/**
156 * @brief Helper to decide which which @c get method to call.
157 *
158 * This either calls @c get using the last type
159 * in our template argument list, or chains to the base class.
160 *
161 * It's virtual so that we can call the most-derived one from
162 * @c getUntyped in the base class, but we also declare it as inline
163 * so that the base class chaining can be inlined.
164 */
165template <class T0, class TO_T>
166inline
167const void*
168SingleAssociationTool<Types<T0>, TO_T>::doGetUntyped (const void* p, size_t count)
169{
170 if (this->m_which == count)
171 return this->get (*reinterpret_cast<const T0*> (p));
172 std::abort();
173}
174
175
176/**
177 * @brief Helper to collect the list of @c type_info's that we accept.
178 *
179 * This first chains to the base class to pick up its list.
180 * Then we add the @c type_info corresponding to the last type
181 * in the template argument list.
182 */
183template <class T0, class TO_T>
184void
185SingleAssociationTool<Types<T0>, TO_T>::push_ti (std::vector<const std::type_info*>& tis)
186{
187 tis.reserve (1);
188 tis.push_back (&typeid(T0));
189}
190
191
192/**
193 * @brief A specialization of SingleAssociationTool that can accept one
194 * of several types.
195 *
196 * This specialization is for the case of more than one argument.
197 */
198template <class TO_T, class T0, class... TYPES>
199class SingleAssociationTool<Types<T0, TYPES...>, TO_T>
200 : public SingleAssociationTool<Types<TYPES...>, ButFirstType_t<TO_T> >
201{
202public:
203 using Base = SingleAssociationTool<Types<TYPES...>, ButFirstType_t<TO_T> >;
204
205 using Base::Base;
206
207 virtual void push_ti (std::vector<const std::type_info*>& tis) override
208 {
209 tis.reserve (1 + sizeof... (TYPES));
210 tis.push_back (&typeid(T0));
211 Base::push_ti (tis);
212 }
213
214 using Base::get;
215 virtual const typename SelectType<TO_T, 0>::type* get (const T0& p) = 0;
216
217 virtual const void* doGetUntyped (const void* p, size_t count) override
218 {
219 if (this->m_which == count)
220 return this->get (*reinterpret_cast<const T0*> (p));
221 return Base::doGetUntyped (p, count+1);
222 }
223
224
225#ifdef __clang__
226#pragma GCC diagnostic push
227#pragma GCC diagnostic ignored "-Winconsistent-missing-override"
228#endif
229 using Base::releaseObject;
230 virtual void releaseObject (const typename SelectType<TO_T, 0>::type* /*p*/) /*override*/ {}
231#ifdef __clang__
232#pragma GCC diagnostic pop
233#endif
234
235 virtual void doReleaseObjectUntyped (const void* p, size_t count) override
236 {
237 if (this->m_which == count) {
238 this->releaseObject (reinterpret_cast<const typename SelectType<TO_T, 0>::type*>(p));
239 return;
240 }
241 Base::doReleaseObjectUntyped (p, count+1);
242 }
243
244
245 virtual const std::type_info&
246 doTypeinfo (size_t count) const override
247 {
248 if (count == this->m_which)
249 return typeid (typename SelectType<TO_T, 0>::type);
250 return Base::doTypeinfo (count+1);
251 }
252};
253
254
255} // namespace D3PD