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 Return the target object.
73 * @param allowMissing If true, then we should not generate errors
74 * if the requested object is missing.
76 * Should be of the type given by @c typeinfo.
77 * Return 0 on failure.
79 * This is implemented by calling @c get().
83 CollectionGetterTool<CONT>::getUntyped (bool allowMissing /*= false*/)
85 return get (allowMissing);
90 * @brief Return the type of the collection object retrieved by this tool.
93 const std::type_info& CollectionGetterTool<CONT>::typeinfo() const
100 * @brief Return the element type of the collection.
102 * I.e., @c nextUntyped returns a pointer to this type.
104 template <class CONT>
105 const std::type_info&
106 CollectionGetterTool<CONT>::elementTypeinfo() const
108 return typeid(typename Deref<CONT>::type);
113 * @brief Reset the iteration to the start of the collection.
114 * @param allowMissing If true, then we should not generate errors
115 * if the requested object is missing.
117 * Return failure if the container cannot be retrieved.
119 template <class CONT>
120 StatusCode CollectionGetterTool<CONT>::reset (bool allowMissing /*= false*/)
122 const CONT* cont = get (allowMissing);
125 return allowMissing ? StatusCode::SUCCESS : StatusCode::FAILURE;
128 m_it = cont->begin();
130 return StatusCode::SUCCESS;
135 * @brief Return a pointer to the next element in the collection.
137 * Return 0 when the collection has been exhausted.
139 template <class CONT>
140 const void* CollectionGetterTool<CONT>::nextUntyped()
142 // Don't return 0 until we get to the end of the iteration.
143 while (m_it != m_end) {
144 const void* ret = Deref<CONT>::deref (m_it);
153 * @brief Return an estimate of the number of elements in the iteration.
154 * @param allowMissing If true, then we should not generate errors
155 * if the requested object is missing.
157 * This can be used to pre-allocate memory.
158 * (It's possible that this isn't known in advance of
159 * iterating over the entire collection, for example
160 * if a selection is being applied, so this is only a hint.)
162 template <class CONT>
163 size_t CollectionGetterTool<CONT>::sizeHint (bool allowMissing /*= false*/)
165 const CONT* cont = get (allowMissing);
173 * @brief Release an object retrieved from the getter.
174 * @param p The object to release.
176 * Call this when you are done with the object returned by
177 * @c get(). The default implementation is a no-op,
178 * but if the getter dynamically allocated the object which
179 * it returned, this gives it a chance to free it.
181 template <class CONT>
182 void CollectionGetterTool<CONT>::releaseObject (const CONT* /*p*/)
188 * @brief Release an object retrieved from the getter.
189 * @param p The object to release.
191 * Call this when you are done with the object returned by
192 * @c getUntyped(). The default implementation is a no-op,
193 * but if the getter dynamically allocated the object which
194 * it returned, this gives it a chance to free it.
196 template <class CONT>
197 void CollectionGetterTool<CONT>::releaseObjectUntyped (const void* p)
199 releaseObject (reinterpret_cast<const CONT*> (p));