2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 * @file D3PDMakerUtils/BlockFillerToolMulti.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief A specialization of BlockFillerTool 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.
28 BlockFillerTool<Types<T0> >::BlockFillerTool
29 (const std::string& type,
30 const std::string& name,
31 const IInterface* parent)
32 : BlockFillerToolImpl (type, name, parent),
35 // cppcheck-suppress missingReturn; false positive
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.
49 BlockFillerTool<Types<T0> >::configureD3PD
51 const std::type_info& ti)
53 std::vector<const std::type_info*> tis;
55 return this->configureImpl (tree, ti, tis, m_which);
60 * @brief Helper to decide which which @c fill method to call.
62 * This either calls @c fill / @c fillAgain using the last type
63 * in our template argument list, or chains to the base class.
65 * It's virtual so that we can call the most-derived one from
66 * @c fillUntyped in the base class, but we also declare it as inline
67 * so that the base class chaining can be inlined.
72 BlockFillerTool<Types<T0> >::doFillUntyped (const void* p, bool again, size_t count)
74 if (m_which == count) {
76 return this->fillAgain (*reinterpret_cast<const T0*> (p));
77 return this->fill (*reinterpret_cast<const T0*> (p));
84 * @brief Fill one block.
85 * @param p The input object.
86 * @param again Set if this is a subsequent call requested by an AGAIN return
88 * This is called once per object. The type of the object at which @c p
89 * points is given by the @c ti argument to @c configureD3PD. The caller
90 * is responsible for arranging that all the pointers for booked variables
91 * are set appropriately upon entry.
93 * If the return status is the special code @c AGAIN (defined above),
94 * then this filler tool wants to make multiple entries.
95 * The parent should set up to capture a new `row' and run
96 * through the list of block filler
97 * tools again, but for this tool call @c fillAgainUntyped
98 * instead of @c fillUntyped. This should be repeated as long
99 * as @c fillAgainUntyped returns @c AGAIN.
101 * Once @c fillUntyped returns @c AGAIN, the parent should
102 * call @c fillUntyped with the same @a p argument and @c again
103 * set to @c true. This continues until @c fillUntyped returns something
104 * other than @c AGAIN.
106 * Not all parents may support this. In that case, returning
107 * @c AGAIN will be treated as an error.
111 BlockFillerTool<Types<T0> >::fillUntyped (const void* p, bool again /*= false*/)
113 if (!p) return StatusCode::SUCCESS;
114 StatusCode stat = convert (p);
115 if (stat.isFailure())
117 return doFillUntyped (p, again, 0);
122 * @brief Helper to collect the list of @c type_info's that we accept.
124 * This first chains to the base class to pick up its list.
125 * Then we add the @c type_info corresponding to the last type
126 * in the template argument list.
130 BlockFillerTool<Types<T0> >::push_ti (std::vector<const std::type_info*>& tis)
133 tis.push_back (&typeid(T0));
138 * @brief A specialization of BlockFillerTool that can accept one
141 * This specialization is for the case of more than one argument.
143 template <class T0, class... TYPES>
144 class BlockFillerTool<Types<T0, TYPES...> >
145 : public BlockFillerTool<Types<TYPES...> >
148 using Base = BlockFillerTool<Types<TYPES...> >;
152 virtual void push_ti (std::vector<const std::type_info*>& tis) override
154 tis.reserve (1 + sizeof... (TYPES));
155 tis.push_back (&typeid(T0));
160 virtual StatusCode fill (const T0& /*p*/) = 0;
162 using Base::fillAgain;
163 virtual StatusCode fillAgain (const T0& p) { return this->fill(p); }
165 virtual StatusCode doFillUntyped (const void* p, bool again, size_t count) override
167 if (this->m_which == count) {
169 return this->fillAgain (*reinterpret_cast<const T0*> (p));
170 return this->fill (*reinterpret_cast<const T0*> (p));
172 return Base::doFillUntyped (p, again, count+1);