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),
36 // cppcheck-suppress missingReturn; false positive
41 * @brief Configure during initialization: type-check.
42 * @param tree Our parent for tuple making.
43 * @param ti Gives the type of the object being passed to @c fillUntyped.
45 * @c configureD3PD should check that the type of the object coming as input
46 * is compatible with what it expects, and raise an error otherwise.
48 template <class T0, class TO_T>
50 MultiAssociationTool<Types<T0>, TO_T>::configureD3PD
52 const std::type_info& ti)
54 std::vector<const std::type_info*> tis;
56 StatusCode sc = this->configureMulti (tree, ti, tis, m_which);
57 if (m_which < tis.size())
58 m_fromTypeinfo = tis[m_which];
64 * @brief Return the @c std::type_info for the source of the association.
66 template <class T0, class TO_T>
68 MultiAssociationTool<Types<T0>, TO_T>::fromTypeinfo() const
70 return *m_fromTypeinfo;
75 * @brief Return the target object.
76 * @param p The source object for the association.
78 * Return the target of the association, or 0.
79 * Should be of the type given by @c typeinfo.
81 template <class T0, class TO_T>
83 MultiAssociationTool<Types<T0>, TO_T>::resetUntyped
86 p = this->doConversion (p);
87 if (!p) return StatusCode::FAILURE;
88 return doResetUntyped (p, 0);
93 * @brief Helper to decide which which @c reset method to call.
95 * This either calls @c reset using the last type
96 * in our template argument list, or chains to the base class.
98 * It's virtual so that we can call the most-derived one from
99 * @c resetUntyped in the base class, but we also declare it as inline
100 * so that the base class chaining can be inlined.
102 template <class T0, class TO_T>
105 MultiAssociationTool<Types<T0>, TO_T>::doResetUntyped (const void* p, size_t /*count*/)
107 return this->reset (*reinterpret_cast<const T0*> (p));
112 * @brief Helper to collect the list of @c type_info's that we accept.
114 * This first chains to the base class to pick up its list.
115 * Then we add the @c type_info corresponding to the last type
116 * in the template argument list.
118 template <class T0, class TO_T>
120 MultiAssociationTool<Types<T0>, TO_T>::push_ti (std::vector<const std::type_info*>& tis)
123 tis.push_back (&typeid(T0));
128 * @brief Release an object retrieved from the association.
129 * @param p The object to release.
131 * Call this when you are done with the object returned by
132 * @c next(). The default implementation is a no-op,
133 * but if the association dynamically allocated the object which
134 * it returned, this gives it a chance to free it.
136 template <class T0, class U0>
139 MultiAssociationTool<Types<T0>, Types<U0> >::releaseElement
146 * @brief Release an object retrieved from the association.
147 * @param p The object to release.
149 * Call this when you are done with the object returned by
150 * @c nextUntyped(). The default implementation is a no-op,
151 * but if the association dynamically allocated the object which
152 * it returned, this gives it a chance to free it.
154 template <class T0, class U0>
157 MultiAssociationTool<Types<T0>, Types<U0> >::releaseElementUntyped (const void* p)
159 this->releaseElement (reinterpret_cast<const U0*> (p));
163 //**************************************************************************
167 * @brief Return a pointer to the next element in the association.
169 * This overload is not used for the case where we can return multiple
170 * output types. In this case, @c next takes a dummy pointer to the
171 * input type in order to fix the type.
173 template <class T0, class U0>
175 MultiAssociationTool<Types<T0>, Types<U0> >::next()
182 * @brief Return the element type for the target of the association.
184 * I.e., @c nextUntyped returns a pointer to this type.
186 template <class T0, class U0>
187 const std::type_info&
188 MultiAssociationTool<Types<T0>, Types<U0> >::elementTypeinfo() const
195 * @brief Return a pointer to the next element in the association.
197 * Return 0 when the association has been exhausted.
199 template <class T0, class U0>
201 MultiAssociationTool<Types<T0>, Types<U0> >::nextUntyped ()
203 return next ((T0*)0);
207 //**************************************************************************
208 // Multiple-argument specializations
212 template <class T0, class TO_T>
220 template <class T0, class U0, class... TYPES>
221 class MaybeNext<T0, Types<U0, TYPES...> >
224 virtual const U0* next (const T0* dum) = 0;
229 * @brief A specialization of MultiAssociationTool that can accept one
232 * This specialization is for the case of more than one argument.
234 template <class TO_T, class T0, class... TYPES>
235 class MultiAssociationTool<Types<T0, TYPES...>, TO_T>
236 : public MultiAssociationTool<Types<TYPES...>, ButFirstType_t<TO_T> >,
237 public MaybeNext<T0, TO_T>
240 using Base = MultiAssociationTool<Types<TYPES...>, ButFirstType_t<TO_T> >;
244 virtual void push_ti (std::vector<const std::type_info*>& tis) override
246 tis.reserve (1 + sizeof... (TYPES));
247 tis.push_back (&typeid(T0));
252 virtual StatusCode reset (const T0& p) = 0;
255 using MaybeNext<T0, TO_T>::next;
257 virtual StatusCode doResetUntyped (const void* p, size_t count) override
259 if (this->m_which == count)
260 return this->reset (*reinterpret_cast<const T0*> (p));
261 return Base::doResetUntyped (p, count+1);