2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 * @file D3PDMakerUtils/SingleAssociationToolMulti.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief A specialization of SingleAssociationTool 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 SingleAssociationTool<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),
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 SingleAssociationTool<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 SingleAssociationTool<Types<T0>, TO_T>::fromTypeinfo() const
69 return *m_fromTypeinfo;
74 * @brief Return the @c std::type_info for the source of the association.
76 template <class T0, class TO_T>
78 SingleAssociationTool<Types<T0>, TO_T>::typeinfo() const
80 return doTypeinfo (0);
84 template <class T0, class TO_T>
86 SingleAssociationTool<Types<T0>, TO_T>::doTypeinfo (size_t /*count*/) const
88 return typeid (typename SelectType<TO_T, 0>::type);
93 * @brief Release an object retrieved from the association.
94 * @param p The object to release.
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.
101 template <class T0, class TO_T>
104 SingleAssociationTool<Types<T0>, TO_T>::releaseObject
105 (const typename SelectType<TO_T, 0>::type* /*p*/)
111 * @brief Release an object retrieved from the association.
112 * @param p The object to release.
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.
119 template <class T0, class TO_T>
122 SingleAssociationTool<Types<T0>, TO_T>::releaseObjectUntyped (const void* p)
124 this->doReleaseObjectUntyped (p, 0);
128 template <class T0, class TO_T>
131 SingleAssociationTool<Types<T0>, TO_T>::doReleaseObjectUntyped (const void* p, size_t /*count*/)
133 this->releaseObject (reinterpret_cast<const typename SelectType<TO_T, 0>::type*> (p));
138 * @brief Return the target object.
139 * @param p The source object for the association.
141 * Return the target of the association, or 0.
142 * Should be of the type given by @c typeinfo.
144 template <class T0, class TO_T>
146 SingleAssociationTool<Types<T0>, TO_T>::getUntyped
149 p = this->doConversion (p);
151 return doGetUntyped (p, 0);
156 * @brief Helper to decide which which @c get method to call.
158 * This either calls @c get using the last type
159 * in our template argument list, or chains to the base class.
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.
165 template <class T0, class TO_T>
168 SingleAssociationTool<Types<T0>, TO_T>::doGetUntyped (const void* p, size_t count)
170 if (this->m_which == count)
171 return this->get (*reinterpret_cast<const T0*> (p));
177 * @brief Helper to collect the list of @c type_info's that we accept.
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.
183 template <class T0, class TO_T>
185 SingleAssociationTool<Types<T0>, TO_T>::push_ti (std::vector<const std::type_info*>& tis)
188 tis.push_back (&typeid(T0));
193 * @brief A specialization of SingleAssociationTool that can accept one
196 * This specialization is for the case of more than one argument.
198 template <class TO_T, class T0, class... TYPES>
199 class SingleAssociationTool<Types<T0, TYPES...>, TO_T>
200 : public SingleAssociationTool<Types<TYPES...>, ButFirstType_t<TO_T> >
203 using Base = SingleAssociationTool<Types<TYPES...>, ButFirstType_t<TO_T> >;
207 virtual void push_ti (std::vector<const std::type_info*>& tis) override
209 tis.reserve (1 + sizeof... (TYPES));
210 tis.push_back (&typeid(T0));
215 virtual const typename SelectType<TO_T, 0>::type* get (const T0& p) = 0;
217 virtual const void* doGetUntyped (const void* p, size_t count) override
219 if (this->m_which == count)
220 return this->get (*reinterpret_cast<const T0*> (p));
221 return Base::doGetUntyped (p, count+1);
226 #pragma GCC diagnostic push
227 #pragma GCC diagnostic ignored "-Winconsistent-missing-override"
229 using Base::releaseObject;
230 virtual void releaseObject (const typename SelectType<TO_T, 0>::type* /*p*/) /*override*/ {}
232 #pragma GCC diagnostic pop
235 virtual void doReleaseObjectUntyped (const void* p, size_t count) override
237 if (this->m_which == count) {
238 this->releaseObject (reinterpret_cast<const typename SelectType<TO_T, 0>::type*>(p));
241 Base::doReleaseObjectUntyped (p, count+1);
245 virtual const std::type_info&
246 doTypeinfo (size_t count) const override
248 if (count == this->m_which)
249 return typeid (typename SelectType<TO_T, 0>::type);
250 return Base::doTypeinfo (count+1);