2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 * @file D3PDMakerUtils/CollectionGetterTool.h
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Type-safe wrapper for collection getter tools.
12 #include <type_traits>
18 /****************************************************************************
19 * Helpers to deal with dereferencing container iterators.
21 * We want to return a pointer to an element. For an ordinary CONT<T>,
22 * it's easy, we just need &*it.
24 * However, a DataVector<T> actually contains T*'s, so in this case,
25 * we need to return the container element directly, not a pointer to it.
26 * (Note that null pointers in a DV will automatically be skipped in the
27 * iteration.) Similarly, if we have containers of @c ElementLink
28 * or @c DataLink, then we don't want to return a pointer to the link;
29 * we want to dereference the link and return a pointer to the target.
30 * ??? Is this really the proper behavior for a link?
34 template <class CONT, class T = typename CONT::value_type>
37 typedef typename CONT::const_iterator iterator;
39 static const type* deref (const iterator& it) { return &*it; }
42 template <class CONT, class T>
43 struct Deref<CONT, T*>
45 typedef typename CONT::const_iterator iterator;
47 static const type* deref (const iterator& p) { return *p; }
50 template <class CONT, class T>
51 struct Deref<CONT, ElementLink<T> >
53 typedef typename CONT::const_iterator iterator;
54 typedef typename ElementLink<T>::ElementType ElementType;
55 typedef typename std::remove_pointer<ElementType>::type type;
56 static const type* deref (const iterator& p) { return *(p->cptr()); }
59 template <class CONT, class T>
60 struct Deref<CONT, DataLink<T> >
62 typedef typename CONT::const_iterator iterator;
64 static const type* deref (const iterator& p) { return **p; }
68 /****************************************************************************/
72 * @brief Standard Gaudi tool constructor.
73 * @param type The name of the tool type.
74 * @param name The tool name.
75 * @param parent The tool's Gaudi parent.
78 CollectionGetterTool<CONT>::CollectionGetterTool (const std::string& type,
79 const std::string& name,
80 const IInterface* parent)
81 : CollectionGetterToolImpl (type, name, parent)
83 // cppcheck-suppress missingReturn; false positive
88 * @brief Return the target object.
89 * @param allowMissing If true, then we should not generate errors
90 * if the requested object is missing.
92 * Should be of the type given by @c typeinfo.
93 * Return 0 on failure.
95 * This is implemented by calling @c get().
99 CollectionGetterTool<CONT>::getUntyped (bool allowMissing /*= false*/)
101 return get (allowMissing);
106 * @brief Return the type of the collection object retrieved by this tool.
108 template <class CONT>
109 const std::type_info& CollectionGetterTool<CONT>::typeinfo() const
116 * @brief Return the element type of the collection.
118 * I.e., @c nextUntyped returns a pointer to this type.
120 template <class CONT>
121 const std::type_info&
122 CollectionGetterTool<CONT>::elementTypeinfo() const
124 return typeid(typename Deref<CONT>::type);
129 * @brief Reset the iteration to the start of the collection.
130 * @param allowMissing If true, then we should not generate errors
131 * if the requested object is missing.
133 * Return failure if the container cannot be retrieved.
135 template <class CONT>
136 StatusCode CollectionGetterTool<CONT>::reset (bool allowMissing /*= false*/)
138 const CONT* cont = get (allowMissing);
141 return allowMissing ? StatusCode::SUCCESS : StatusCode::FAILURE;
144 m_it = cont->begin();
146 return StatusCode::SUCCESS;
151 * @brief Return a pointer to the next element in the collection.
153 * Return 0 when the collection has been exhausted.
155 template <class CONT>
156 const void* CollectionGetterTool<CONT>::nextUntyped()
158 // Don't return 0 until we get to the end of the iteration.
159 while (m_it != m_end) {
160 const void* ret = Deref<CONT>::deref (m_it);
169 * @brief Return an estimate of the number of elements in the iteration.
170 * @param allowMissing If true, then we should not generate errors
171 * if the requested object is missing.
173 * This can be used to pre-allocate memory.
174 * (It's possible that this isn't known in advance of
175 * iterating over the entire collection, for example
176 * if a selection is being applied, so this is only a hint.)
178 template <class CONT>
179 size_t CollectionGetterTool<CONT>::sizeHint (bool allowMissing /*= false*/)
181 const CONT* cont = get (allowMissing);
189 * @brief Release an object retrieved from the getter.
190 * @param p The object to release.
192 * Call this when you are done with the object returned by
193 * @c get(). The default implementation is a no-op,
194 * but if the getter dynamically allocated the object which
195 * it returned, this gives it a chance to free it.
197 template <class CONT>
198 void CollectionGetterTool<CONT>::releaseObject (const CONT* /*p*/)
204 * @brief Release an object retrieved from the getter.
205 * @param p The object to release.
207 * Call this when you are done with the object returned by
208 * @c getUntyped(). The default implementation is a no-op,
209 * but if the getter dynamically allocated the object which
210 * it returned, this gives it a chance to free it.
212 template <class CONT>
213 void CollectionGetterTool<CONT>::releaseObjectUntyped (const void* p)
215 releaseObject (reinterpret_cast<const CONT*> (p));