BeeeOn Gateway  v2020.3.1-2-g6f737dc
Platform to interconnect the IoT world
ZipIterator.h
1 #pragma once
2 
3 #include <iterator>
4 
5 namespace BeeeOn {
6 
43 template <typename Container1, typename Container2>
44 class Zip {
45 public:
46  using Iterator1 = decltype(std::declval<Container1&>().begin());
47  using Iterator2 = decltype(std::declval<Container2&>().begin());
48  using Value1 = decltype(*std::declval<Iterator1>());
49  using Value2 = decltype(*std::declval<Iterator2>());
50 
51  Zip(Container1 &container1, Container2 &container2) {
52  m_beginC1 = container1.begin();
53  m_beginC2 = container2.begin();
54 
55  m_endC1 = container1.end();
56  m_endC2 = container2.end();
57 
58  auto distanceC1 = std::distance(m_beginC1, m_endC1);
59  auto distanceC2 = std::distance(m_beginC2, m_endC2);
60 
61  if (distanceC1 == distanceC2) {
62  m_zipEndC1 = m_endC1;
63  m_zipEndC2 = m_endC2;
64  }
65  else if (distanceC1 < distanceC2) {
66  m_zipEndC1 = m_endC1;
67  m_zipEndC2 = std::next(m_beginC2, distanceC1);
68  }
69  else {
70  m_zipEndC2 = m_endC2;
71  m_zipEndC1 = std::next(m_beginC1, distanceC2);
72  }
73  }
74 
75  class Iterator {
76  public:
77  Iterator(
78  Iterator1 currentIt1,
79  Iterator2 currentIt2,
80  Iterator1 endIt1,
81  Iterator2 endIt2):
82  m_currentIt1(currentIt1),
83  m_currentIt2(currentIt2),
84  m_endIt1(endIt1),
85  m_endIt2(endIt2)
86  {
87  }
88 
89  Iterator& operator++()
90  {
91  m_currentIt1++;
92  m_currentIt2++;
93  return *this;
94  }
95 
96  Iterator operator++(int)
97  {
98  Iterator copy = *this;
99  m_currentIt1++;
100  m_currentIt2++;
101  return copy;
102  }
103 
104  bool operator==(const Iterator &other) const
105  {
106  return m_currentIt1 == other.m_currentIt1
107  && m_currentIt2 == other.m_currentIt2;
108  }
109 
110  bool operator!=(const Iterator &other) const
111  {
112  return m_currentIt1 != other.m_currentIt1
113  || m_currentIt2 != other.m_currentIt2;
114  }
115 
116  std::pair<Value1, Value2> operator*()
117  {
118  return std::pair<Value1, Value2>(*m_currentIt1, *m_currentIt2);
119  }
120 
121  Iterator1 firstIterator() const
122  {
123  return m_currentIt1;
124  }
125 
126  Iterator2 secondIterator() const
127  {
128  return m_currentIt2;
129  }
130 
131  bool hasFirstEnded() const
132  {
133  return m_currentIt1 == m_endIt1;
134  }
135 
136  bool hasSecondEnded() const
137  {
138  return m_currentIt2 == m_endIt2;
139  }
140 
141  bool hasBothEnded() const
142  {
143  return m_currentIt1 == m_endIt1 && m_currentIt2 == m_endIt2;
144  }
145 
146  private:
147  Iterator1 m_currentIt1;
148  Iterator2 m_currentIt2;
149 
150  Iterator1 m_endIt1;
151  Iterator2 m_endIt2;
152  };
153 
155  {
156  return Iterator(m_beginC1, m_beginC2, m_endC1, m_endC2);
157  }
158 
160  {
161  return Iterator(m_zipEndC1, m_zipEndC2, m_endC1, m_endC2);
162  }
163 
164  Iterator1 firstEnd() const
165  {
166  return m_endC1;
167  }
168 
169  Iterator2 secondEnd() const
170  {
171  return m_endC2;
172  }
173 
174 private:
175  Iterator1 m_beginC1;
176  Iterator2 m_beginC2;
177  Iterator1 m_endC1;
178  Iterator2 m_endC2;
179  Iterator1 m_zipEndC1;
180  Iterator2 m_zipEndC2;
181 };
182 
183 }
Definition: ZipIterator.h:75
The class provides an elegant way to iterate over 2 containers, which size can be different...
Definition: ZipIterator.h:44