2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 * @file D3PDMakerUtils/MultiAssociationToolMulti.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief A specialization of MultiAssociationTool that can accept one
13 //**************************************************************************
14 // Single-argument specialization
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.
27 template <class T0, class TO_T>
28 MultiAssociationTool<Types<T0>, TO_T>::MultiAssociationTool
29 (const std::string& type,
30 const std::string& name,
31 const IInterface* parent)
32 : MultiAssociationToolTo<TO_T> (type, name, parent),
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.
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.
47 template <class T0, class TO_T>
49 MultiAssociationTool<Types<T0>, TO_T>::configureD3PD
51 const std::type_info& ti)
53 std::vector<const std::type_info*> tis;
55 StatusCode sc = this->configureMulti (tree, ti, tis, m_which);
56 if (m_which < tis.size())
57 m_fromTypeinfo = tis[m_which];
63 * @brief Return the @c std::type_info for the source of the association.
65 template <class T0, class TO_T>
67 MultiAssociationTool<Types<T0>, TO_T>::fromTypeinfo() const
69 return *m_fromTypeinfo;
74 * @brief Return the target object.
75 * @param p The source object for the association.
77 * Return the target of the association, or 0.
78 * Should be of the type given by @c typeinfo.
80 template <class T0, class TO_T>
82 MultiAssociationTool<Types<T0>, TO_T>::resetUntyped
85 p = this->doConversion (p);
86 if (!p) return StatusCode::FAILURE;
87 return doResetUntyped (p, 0);
92 * @brief Helper to decide which which @c reset method to call.
94 * This either calls @c reset using the last type
95 * in our template argument list, or chains to the base class.
97 * It's virtual so that we can call the most-derived one from
98 * @c resetUntyped in the base class, but we also declare it as inline
99 * so that the base class chaining can be inlined.
101 template <class T0, class TO_T>
104 MultiAssociationTool<Types<T0>, TO_T>::doResetUntyped (const void* p, size_t /*count*/)
106 return this->reset (*reinterpret_cast<const T0*> (p));
111 * @brief Helper to collect the list of @c type_info's that we accept.
113 * This first chains to the base class to pick up its list.
114 * Then we add the @c type_info corresponding to the last type
115 * in the template argument list.
117 template <class T0, class TO_T>
119 MultiAssociationTool<Types<T0>, TO_T>::push_ti (std::vector<const std::type_info*>& tis)
122 tis.push_back (&typeid(T0));
127 * @brief Release an object retrieved from the association.
128 * @param p The object to release.
130 * Call this when you are done with the object returned by
131 * @c next(). The default implementation is a no-op,
132 * but if the association dynamically allocated the object which
133 * it returned, this gives it a chance to free it.
135 template <class T0, class U0>
138 MultiAssociationTool<Types<T0>, Types<U0> >::releaseElement
145 * @brief Release an object retrieved from the association.
146 * @param p The object to release.
148 * Call this when you are done with the object returned by
149 * @c nextUntyped(). The default implementation is a no-op,
150 * but if the association dynamically allocated the object which
151 * it returned, this gives it a chance to free it.
153 template <class T0, class U0>
156 MultiAssociationTool<Types<T0>, Types<U0> >::releaseElementUntyped (const void* p)
158 this->releaseElement (reinterpret_cast<const U0*> (p));
162 //**************************************************************************
166 * @brief Standard Gaudi tool constructor.
167 * @param type The name of the tool type.
168 * @param name The tool name.
169 * @param parent The tool's Gaudi parent.
171 template <class T0, class U0>
172 MultiAssociationTool<Types<T0>, Types<U0> >::MultiAssociationTool
173 (const std::string& type,
174 const std::string& name,
175 const IInterface* parent)
176 : MultiAssociationTool<Types<T0>, U0> (type, name, parent)
178 // cppcheck-suppress missingReturn; false positive
183 * @brief Return a pointer to the next element in the association.
185 * This overload is not used for the case where we can return multiple
186 * output types. In this case, @c next takes a dummy pointer to the
187 * input type in order to fix the type.
189 template <class T0, class U0>
191 MultiAssociationTool<Types<T0>, Types<U0> >::next()
198 * @brief Return the element type for the target of the association.
200 * I.e., @c nextUntyped returns a pointer to this type.
202 template <class T0, class U0>
203 const std::type_info&
204 MultiAssociationTool<Types<T0>, Types<U0> >::elementTypeinfo() const
211 * @brief Return a pointer to the next element in the association.
213 * Return 0 when the association has been exhausted.
215 template <class T0, class U0>
217 MultiAssociationTool<Types<T0>, Types<U0> >::nextUntyped ()
219 return next ((T0*)0);
223 //**************************************************************************
224 // Multiple-argument specializations
228 template <class T0, class TO_T>
236 template <class T0, class U0, class... TYPES>
237 class MaybeNext<T0, Types<U0, TYPES...> >
240 virtual const U0* next (const T0* dum) = 0;
245 * @brief A specialization of MultiAssociationTool that can accept one
248 * This specialization is for the case of more than one argument.
250 template <class TO_T, class T0, class... TYPES>
251 class MultiAssociationTool<Types<T0, TYPES...>, TO_T>
252 : public MultiAssociationTool<Types<TYPES...>, ButFirstType_t<TO_T> >,
253 public MaybeNext<T0, TO_T>
256 using Base = MultiAssociationTool<Types<TYPES...>, ButFirstType_t<TO_T> >;
260 virtual void push_ti (std::vector<const std::type_info*>& tis) override
262 tis.reserve (1 + sizeof... (TYPES));
263 tis.push_back (&typeid(T0));
268 virtual StatusCode reset (const T0& p) = 0;
271 using MaybeNext<T0, TO_T>::next;
273 virtual StatusCode doResetUntyped (const void* p, size_t count) override
275 if (this->m_which == count)
276 return this->reset (*reinterpret_cast<const T0*> (p));
277 return Base::doResetUntyped (p, count+1);