ATLAS Offline Software
ProductItr.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <stdexcept>
6 
7 namespace TrigCompositeUtils {
8  template <typename Iterator>
9  ProductItr<Iterator>::ProductItr(const std::vector<Iterator> &itrs,
10  const std::vector<Iterator> &endItrs)
11  : m_startItrs(itrs), m_endItrs(endItrs) {
12  if (itrs.size() != endItrs.size())
13  throw std::invalid_argument("Provided start and end iterators have different sizes!");
14  reset();
15  }
16 
17  template <typename Iterator>
18  void ProductItr<Iterator>::reset() {
19  // Reset the start iterators
20  m_currentItrs = m_startItrs;
21  for (std::size_t idx = 0; idx < nItrs(); ++idx) {
22  if (m_currentItrs[idx] == m_endItrs[idx]) {
23  // Exhausted iterator - exhaust the entire lot
24  m_currentItrs = m_endItrs;
25  break;
26  }
27  }
28  }
29 
30  template <typename Iterator>
31  bool ProductItr<Iterator>::exhausted() const {
32  // Exhausted if the first iterator has been left in an exhausted
33  // position
34  return nItrs() == 0 || m_currentItrs[0] == m_endItrs[0];
35  }
36 
37  template <typename Iterator>
38  typename ProductItr<Iterator>::reference ProductItr<Iterator>::operator*() const {
39  if (exhausted())
40  throw std::runtime_error("Cannot dereference exhausted iterator!");
41  return m_currentItrs;
42  }
43 
44  template <typename Iterator>
45  typename ProductItr<Iterator>::pointer ProductItr<Iterator>::operator->() const {
46  if (exhausted())
47  throw std::runtime_error("Cannot dereference exhausted iterator!");
48  return &m_currentItrs;
49  }
50 
51  template <typename Iterator>
52  ProductItr<Iterator> &ProductItr<Iterator>::operator++() {
53  if (exhausted())
54  // Don't iterate an iterator that is already past the end
55  return *this;
56  for (std::size_t idx = nItrs() - 1; idx != static_cast<std::size_t>(-1); --idx) {
57  Iterator &itr = m_currentItrs[idx];
58  if (++itr != m_endItrs[idx]) {
59  // Iterator isn't exhausted! Update the combination
60  // Any iterators we passed by up to this point were exhausted so we have
61  // to reset them before we use their values
62  for (std::size_t idx2 = idx + 1; idx2 < nItrs(); ++idx2)
63  m_currentItrs[idx2] = m_startItrs[idx2];
64  break;
65  }
66  }
67  return *this;
68  }
69 
70  template <typename Iterator>
71  ProductItr<Iterator> ProductItr<Iterator>::operator++(int) {
72  ProductItr itr = *this;
73  this->operator++();
74  return itr;
75  }
76 
77  template <typename Iterator>
78  bool ProductItr<Iterator>::operator==(const ProductItr &other) const {
79  // All past-the-end iterators compare equal
80  if (exhausted() && other.exhausted())
81  return true;
82  return m_currentItrs == other.m_currentItrs;
83  }
84 
85  template <typename Iterator>
86  bool ProductItr<Iterator>::operator!=(const ProductItr &other) const {
87  return !(*this == other);
88  }
89 
90 } // namespace TrigCompositeUtils