ATLAS Offline Software
Loading...
Searching...
No Matches
CollectionGetterTool.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4/**
5 * @file D3PDMakerUtils/CollectionGetterTool.h
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Aug, 2009
8 * @brief Type-safe wrapper for collection getter tools.
9 */
10
11
12#include <type_traits>
13
14
15namespace D3PD {
16
17
18/****************************************************************************
19 * Helpers to deal with dereferencing container iterators.
20 *
21 * We want to return a pointer to an element. For an ordinary CONT<T>,
22 * it's easy, we just need &*it.
23 *
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?
31 */
32
33
34template <class CONT, class T = typename CONT::value_type>
35struct Deref
36{
37 typedef typename CONT::const_iterator iterator;
38 typedef T type;
39 static const type* deref (const iterator& it) { return &*it; }
40};
41
42template <class CONT, class T>
43struct Deref<CONT, T*>
44{
45 typedef typename CONT::const_iterator iterator;
46 typedef T type;
47 static const type* deref (const iterator& p) { return *p; }
48};
49
50template <class CONT, class T>
51struct Deref<CONT, ElementLink<T> >
52{
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()); }
57};
58
59template <class CONT, class T>
60struct Deref<CONT, DataLink<T> >
61{
62 typedef typename CONT::const_iterator iterator;
63 typedef T type;
64 static const type* deref (const iterator& p) { return **p; }
65};
66
67
68/****************************************************************************/
69
70
71/**
72 * @brief Return the target object.
73 * @param allowMissing If true, then we should not generate errors
74 * if the requested object is missing.
75 *
76 * Should be of the type given by @c typeinfo.
77 * Return 0 on failure.
78 *
79 * This is implemented by calling @c get().
80 */
81template <class CONT>
82const void*
83CollectionGetterTool<CONT>::getUntyped (bool allowMissing /*= false*/)
84{
85 return get (allowMissing);
86}
87
88
89/**
90 * @brief Return the type of the collection object retrieved by this tool.
91 */
92template <class CONT>
93const std::type_info& CollectionGetterTool<CONT>::typeinfo() const
94{
95 return typeid(CONT);
96}
97
98
99/**
100 * @brief Return the element type of the collection.
101 *
102 * I.e., @c nextUntyped returns a pointer to this type.
103 */
104template <class CONT>
105const std::type_info&
106CollectionGetterTool<CONT>::elementTypeinfo() const
107{
108 return typeid(typename Deref<CONT>::type);
109}
110
111
112/**
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.
116 *
117 * Return failure if the container cannot be retrieved.
118 */
119template <class CONT>
120StatusCode CollectionGetterTool<CONT>::reset (bool allowMissing /*= false*/)
121{
122 const CONT* cont = get (allowMissing);
123 if (!cont) {
124 m_it = m_end;
125 return allowMissing ? StatusCode::SUCCESS : StatusCode::FAILURE;
126 }
127
128 m_it = cont->begin();
129 m_end = cont->end();
130 return StatusCode::SUCCESS;
131}
132
133
134/**
135 * @brief Return a pointer to the next element in the collection.
136 *
137 * Return 0 when the collection has been exhausted.
138 */
139template <class CONT>
140const void* CollectionGetterTool<CONT>::nextUntyped()
141{
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);
145 ++m_it;
146 if (ret) return ret;
147 }
148 return 0;
149}
150
151
152/**
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.
156 *
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.)
161 */
162template <class CONT>
163size_t CollectionGetterTool<CONT>::sizeHint (bool allowMissing /*= false*/)
164{
165 const CONT* cont = get (allowMissing);
166 if (cont)
167 return cont->size();
168 return 0;
169}
170
171
172/**
173 * @brief Release an object retrieved from the getter.
174 * @param p The object to release.
175 *
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.
180 */
181template <class CONT>
182void CollectionGetterTool<CONT>::releaseObject (const CONT* /*p*/)
183{
184}
185
186
187/**
188 * @brief Release an object retrieved from the getter.
189 * @param p The object to release.
190 *
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.
195 */
196template <class CONT>
197void CollectionGetterTool<CONT>::releaseObjectUntyped (const void* p)
198{
199 releaseObject (reinterpret_cast<const CONT*> (p));
200}
201
202
203} // namespace D3PD