2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
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!");
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;
30 template <typename Iterator>
31 bool ProductItr<Iterator>::exhausted() const {
32 // Exhausted if the first iterator has been left in an exhausted
34 return nItrs() == 0 || m_currentItrs[0] == m_endItrs[0];
37 template <typename Iterator>
38 typename ProductItr<Iterator>::reference ProductItr<Iterator>::operator*() const {
40 throw std::runtime_error("Cannot dereference exhausted iterator!");
44 template <typename Iterator>
45 typename ProductItr<Iterator>::pointer ProductItr<Iterator>::operator->() const {
47 throw std::runtime_error("Cannot dereference exhausted iterator!");
48 return &m_currentItrs;
51 template <typename Iterator>
52 ProductItr<Iterator> &ProductItr<Iterator>::operator++() {
54 // Don't iterate an iterator that is already past the end
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];
70 template <typename Iterator>
71 ProductItr<Iterator> ProductItr<Iterator>::operator++(int) {
72 ProductItr itr = *this;
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())
82 return m_currentItrs == other.m_currentItrs;
85 template <typename Iterator>
86 bool ProductItr<Iterator>::operator!=(const ProductItr &other) const {
87 return !(*this == other);
90 } // namespace TrigCompositeUtils