Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
IdentContIndexingPolicy.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 /**
5  * @file AthLinks/tools/IdentContIndexingPolicy.icc
6  * @author scott snyder <snyder@bnl.gov>
7  * @date Apr, 2014
8  * @brief Indexing policy for an IdentifiableContainer.
9  */
10 
11 
12 #include <algorithm>
13 
14 
15 namespace SG {
16 
17 
18 /**
19  * @brief Test to see if an index is valid.
20  * @param index The index to test.
21  */
22 template <class CONT>
23 inline
24 bool IdentContIndexingPolicy<CONT>::isValid (stored_index_type index)
25 {
26  return IdentContIndex(index).isValid();
27 }
28 
29 
30 /**
31  * @brief Convert from stored to external index types.
32  * @param index The stored index.
33  */
34 template <class CONT>
35 inline
36 typename IdentContIndexingPolicy<CONT>::index_type
37 IdentContIndexingPolicy<CONT>::storedToExternal (stored_index_type index)
38 {
39  return index;
40 }
41 
42 
43 /**
44  * @brief Make an index invalid.
45  * @param index[out] The index to reset.
46  */
47 template <class CONT>
48 inline
49 void IdentContIndexingPolicy<CONT>::reset (stored_index_type& index)
50 {
51  index = IdentContIndex().hashAndIndex();
52 }
53 
54 
55 /**
56  * @brief Retrieve from a container the element corresponding to an index.
57  * @param index The index to fetch.
58  * @param data The container.
59  *
60  * Will throw SG::ExcInvalidIndex if the index is invalid and
61  * SG::ExcIndexNotFound if the index is not in the container.
62  */
63 template <class CONT>
64 typename IdentContIndexingPolicy<CONT>::ElementType
65 IdentContIndexingPolicy<CONT>::lookup (index_type index, const CONT& data)
66 {
67  if (!isValid(index))
68  SG::throwExcInvalidIndex ("IdentContIndexingPolicy");
69 
70  // Find object with hash and index in collection
71  IdentContIndex compIndex(index);
72  typename CONT::const_iterator it = data.indexFind (compIndex.collHash());
73  if (it != data.end()) {
74  // Found collection
75  // Check if objIndex was correctly set
76  if (compIndex.objIndex() < (*it)->size()) {
77  return ((**it)[compIndex.objIndex()]);
78  }
79  }
80  // No object found!
81  SG::throwExcIndexNotFound ("IdentContIndexingPolicy");
82 }
83 
84 
85 /**
86  * @brief Find the index of the (first) instance of ELEMENT in DATA.
87  * @param data The container to search.
88  * @param element The element to find.
89  * @param index[out] The index in the container of @c element.
90  *
91  * Throws SG::ExcElementNotFound if the element is not in the container.
92  */
93 template <class CONT>
94 void
95 IdentContIndexingPolicy<CONT>::reverseLookup(const CONT& data,
96  ElementConstReference element,
97  index_type& index)
98 {
99  // compiler checks we can compare elements
100  static_assert (std::equality_comparable<ElementType>);
101 
102  // The hash and possibly the object index may already have
103  // been set by the user. We verify that the index does
104  // correspond to the object, and otherwise we recalculate the
105  // index
106  IdentContIndex compIndex(index);
107  typename CONT::const_iterator it = data.indexFind (compIndex.collHash());
108  if (it != data.end()) {
109  // Found collection
110  // Check if objIndex was correctly set
111  if (compIndex.objIndex() < (*it)->size()) {
112  if ((**it)[compIndex.objIndex()] == element) {
113  return;
114  }
115  }
116  // objIndex was not correctly set, look for object
117  for (unsigned int i = 0; i < (*it)->size(); ++i) {
118  if ((**it)[i] == element) {
119  // Save index in collection to object
120  compIndex.setObjIndex(i);
121  index = compIndex.hashAndIndex();
122  return;
123  }
124  }
125  // Correct collection, but object not found
126  SG::throwExcElementNotFound ("IdentContIndexingPolicy: reverseLookup");
127  return; // Not reached
128  }
129 
130  // Neither hash, nor object index set, must find both - THIS
131  // IS SLOW!!
132  for (typename CONT::const_iterator it = data.begin();
133  it != data.end();
134  ++it) {
135  const coll_type* coll = *it;
136  if (coll) {
137  typename coll_type::const_iterator objIt =
138  std::find (coll->begin(), coll->end(),
139  element);
140  if (objIt != coll->end()) {
141  // Save collection hash and index to object in collection
142  compIndex.setCollHash(coll->identifyHash());
143  compIndex.setObjIndex(std::distance (coll->begin(), objIt));
144  index = compIndex.hashAndIndex();
145  return;
146  }
147  }
148  }
149  SG::throwExcElementNotFound ("IdentContIndexingPolicy: reverseLookup");
150 }
151 
152 
153 } // namespace SG
154 
155