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