CompoundIterator.h
Go to the documentation of this file.
1 #pragma once
2 #include <algorithm>
3 #include <boost/iterator/iterator_adaptor.hpp>
4 #include <iostream>
5 
6 namespace lanelet {
7 namespace internal {
8 
18 template <typename ContainerT>
20  : public boost::iterator_facade<UniqueCompoundIterator<ContainerT>,
21  std::remove_reference_t<decltype(*ContainerT().begin()->begin())>,
22  std::random_access_iterator_tag> {
23  using Base = boost::iterator_facade<UniqueCompoundIterator<ContainerT>,
24  std::remove_reference_t<decltype(*ContainerT().begin()->begin())>,
25  std::random_access_iterator_tag>;
26 
27  public:
28  using ItOuter = std::decay_t<decltype(ContainerT().begin())>;
29  using ItInner = std::decay_t<decltype(ItOuter()->begin())>;
30  UniqueCompoundIterator() = default;
31  static UniqueCompoundIterator begin(ContainerT& c) {
32  auto itBegin = firstNonempty(c);
33  if (itBegin != c.end()) {
34  return UniqueCompoundIterator(c, itBegin, itBegin->begin());
35  }
36  return UniqueCompoundIterator(c, itBegin, ItInner());
37  }
38  static UniqueCompoundIterator end(ContainerT& c) { return UniqueCompoundIterator(c, c.end(), {}); }
39 
40  private:
42  UniqueCompoundIterator(ContainerT& c, ItOuter itOuter, ItInner itInner)
43  : c_{&c}, itOuter_{itOuter}, itInner_{itInner} {}
44  static ItOuter firstNonempty(ContainerT& c) {
45  return std::find_if(c.begin(), c.end(), [](auto& c) { return !c.empty(); });
46  }
47 
48  void increment() {
49  auto& old = *(*this);
50  auto endIt = end(*c_);
51  do {
52  incrementOne();
53  } while ((*this) != endIt && old == *(*this));
54  }
55 
56  void decrement() {
57  decrementOne();
58  const auto startIt = begin(*c_);
59  if (*this == startIt) {
60  return;
61  }
62  auto next = *this;
63  do {
64  *this = next;
65  next.decrementOne();
66  if (*next != *(*this)) {
67  return;
68  }
69  } while (next != startIt);
70  *this = next;
71  }
72 
73  void incrementOne() {
74  if (itOuter_->end() == std::next(itInner_)) {
75  do {
76  ++itOuter_;
77  } while (itOuter_ != c_->end() && itOuter_->empty());
78  if (itOuter_ == c_->end()) {
79  itInner_ = ItInner();
80  } else {
81  itInner_ = itOuter_->begin();
82  }
83  } else {
84  ++itInner_;
85  }
86  }
87 
88  void decrementOne() {
89  if (itOuter_ == c_->end() || itInner_ == itOuter_->begin()) {
90  const auto begin = firstNonempty(*c_);
91  do {
92  --itOuter_;
93  } while (itOuter_ != begin && itOuter_->empty());
94  itInner_ = std::prev(itOuter_->end());
95  } else {
96  --itInner_;
97  }
98  }
99 
100  void advance(typename Base::difference_type d) {
101  if (d > 0) {
102  for (; d != 0; d--) {
103  increment();
104  }
105  } else {
106  for (; d != 0; d++) {
107  decrement();
108  }
109  }
110  }
111 
112  typename Base::difference_type distance_to( // NOLINT
113  UniqueCompoundIterator other) const {
114  typename Base::difference_type d{};
115  auto cp = *this;
116  if (other.itOuter_ > itOuter_ || (other.itOuter_ == itOuter_ && other.itInner_ > itInner_)) {
117  while (!cp.equal(other)) {
118  cp.increment();
119  d++;
120  }
121  } else {
122  while (!cp.equal(other)) {
123  other.increment();
124  d--;
125  }
126  }
127  return d;
128  }
129 
130  bool equal(UniqueCompoundIterator other) const { return itOuter_ == other.itOuter_ && itInner_ == other.itInner_; }
131 
132  decltype(auto) dereference() const { return *itInner_; }
133 
134  ContainerT* c_{nullptr};
137 };
138 
139 } // namespace internal
140 } // namespace lanelet
bool equal(UniqueCompoundIterator other) const
Base::difference_type distance_to(UniqueCompoundIterator other) const
static UniqueCompoundIterator begin(ContainerT &c)
static UniqueCompoundIterator end(ContainerT &c)
This iterator iterates over a container of containers as if it was one single container. Succeeding elements that are equal are ignored.
boost::iterator_facade< UniqueCompoundIterator< ContainerT >, std::remove_reference_t< decltype(*ContainerT().begin() ->begin())>, std::random_access_iterator_tag > Base
UniqueCompoundIterator(ContainerT &c, ItOuter itOuter, ItInner itInner)
std::decay_t< decltype(ContainerT().begin())> ItOuter
std::decay_t< decltype(ItOuter() ->begin())> ItInner
static ItOuter firstNonempty(ContainerT &c)
void advance(typename Base::difference_type d)


lanelet2_core
Author(s): Fabian Poggenhans
autogenerated on Tue Jun 6 2023 02:23:32