Iterator.h
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXCore::core
19 * @author Raphael Grimm (raphael dot grimm at kit dot edu)
20 * @date 2019
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24 
25 #pragma once
26 
27 
28 #include <tuple>
29 #include <utility>
30 #include <stdexcept>
31 #include <algorithm>
32 
33 #include <boost/iterator/iterator_facade.hpp>
34 
35 namespace armarx
36 {
37  template<class Ituple, class Rtuple, class Idx>
39 
40  template<class Ituple, class Rtuple, std::size_t...Idxs>
41  class ZipIteratorBase < Ituple, Rtuple, std::index_sequence<Idxs...>> :
42  public boost::iterator_facade <
43  ZipIteratorBase<Ituple, Rtuple, std::index_sequence<Idxs...>>,
44  Rtuple,
45  boost::forward_traversal_tag,
46  Rtuple
47  >
48  {
49  public:
50  using IteratorTuple = Ituple;
51  using reference = Rtuple;
52  using difference_type = std::ptrdiff_t;
53  private:
54  IteratorTuple _iters;
55  public:
56  ZipIteratorBase(ZipIteratorBase&&) = default;
57  ZipIteratorBase(const ZipIteratorBase&) = default;
58 
59  ZipIteratorBase& operator=(ZipIteratorBase&&) = default;
60  ZipIteratorBase& operator=(const ZipIteratorBase&) = default;
61 
62  ZipIteratorBase(IteratorTuple its) : _iters{std::move(its)} {}
63  private:
64  friend class boost::iterator_core_access;
65 
66  // Implementation of Iterator Operations
67  // =====================================
68  reference dereference() const
69  {
70  return std::forward_as_tuple(*std::get<Idxs>(_iters)...);
71  }
72 
73  bool equal(const ZipIteratorBase& other) const
74  {
75  return _iters == other._iters;
76  }
77 
78  // Advancing a zip iterator means to advance all iterators in the
79  // iterator tuple.
80  void advance(difference_type n)
81  {
82  ((std::get<Idxs>(_iters) += n), ...);
83  }
84  // Incrementing a zip iterator means to increment all iterators in
85  // the iterator tuple.
86  void increment()
87  {
88  (++std::get<Idxs>(_iters), ...);
89  }
90 
91  // Decrementing a zip iterator means to decrement all iterators in
92  // the iterator tuple.
93  void decrement()
94  {
95  (--std::get<Idxs>(_iters), ...);
96  }
97 
98  // // Distance is calculated using the first iterator in the tuple.
99  // template<typename OtherIteratorTuple>
100  // typename super_t::difference_type distance_to(
101  // const zip_iterator<OtherIteratorTuple>& other
102  // ) const
103  // {
104  // return fusion::at_c<0>(other.get_iterator_tuple()) -
105  // fusion::at_c<0>(this->get_iterator_tuple());
106  // }
107 
108 
109  };
110 
111  template<class It0, class...Its>
112  class ZipIterator :
113  public ZipIteratorBase
114  <
115  std::tuple<It0, Its...>,
116  std::tuple
117  <
118  typename std::iterator_traits<It0>::reference&&,
119  typename std::iterator_traits<Its>::reference&& ...
120  >,
121  std::make_index_sequence < 1 + sizeof...(Its) >
122  >
123  {
124  public:
125  using Base = ZipIteratorBase
126  <
127  std::tuple<It0, Its...>,
128  std::tuple
129  <
130  typename std::iterator_traits<It0>::reference &&,
131  typename std::iterator_traits<Its>::reference && ...
132  >,
133  std::make_index_sequence < 1 + sizeof...(Its) >
134  >;
135 
136  ZipIterator(It0&& it0, Its&& ...its) :
137  Base({std::forward<It0>(it0), std::forward<Its>(its)...})
138  {}
139  using Base::Base;
140  using Base::operator=;
141  };
142 }
143 
144 #include <utility>
145 namespace armarx
146 {
147  template<class It>
149  {
150  IteratorRange(It b, It e)
151  : _begin{std::move(b)}, _end{std::move(e)}
152  {}
153  It begin() const
154  {
155  return _begin;
156  }
157  It end() const
158  {
159  return _end;
160  }
161  private:
162  It _begin;
163  It _end;
164  };
165 }
166 
167 #include <boost/iterator/zip_iterator.hpp>
168 #include <boost/iterator/counting_iterator.hpp>
169 namespace armarx
170 {
171  template<class Container, class...Containers>
172  auto MakeIndexedContainer(Container& c, Containers& ...cs)
173  {
174  if constexpr(sizeof...(Containers))
175  {
176  const auto initlist = {c.size(), cs.size()...};
177  const auto [lo, hi] = std::minmax(initlist);
178  if (lo != hi)
179  {
180  throw std::invalid_argument{"All containers have to be of the same size!"};
181  }
182  }
183  return IteratorRange
184  {
185  ZipIterator(boost::counting_iterator<std::size_t>(0), c.begin(), cs.begin()...),
186  ZipIterator(boost::counting_iterator<std::size_t>(c.size()), c.end(), cs.end()...)
187  };
188  }
189 
190  template<class Container, class...Containers>
191  auto MakeZippedContainer(Container& c, Containers& ...cs)
192  {
193  if constexpr(sizeof...(Containers))
194  {
195  const auto initlist = {c.size(), cs.size()...};
196  const auto [lo, hi] = std::minmax(initlist);
197  if (lo != hi)
198  {
199  throw std::invalid_argument{"All containers have to be of the same size!"};
200  }
201  }
202  return IteratorRange
203  {
204  ZipIterator(c.begin(), cs.begin()...),
205  ZipIterator(c.end(), cs.end()...)
206  };
207  }
208 
209  template<class Container>
210  auto MakeReversedRange(Container& c)
211  {
212  return IteratorRange{c.rbegin(), c.rend()};
213  }
214 }
armarx::ZipIteratorBase< Ituple, Rtuple, std::index_sequence< Idxs... > >::ZipIteratorBase
ZipIteratorBase(IteratorTuple its)
Definition: Iterator.h:62
armarx::ZipIteratorBase< Ituple, Rtuple, std::index_sequence< Idxs... > >::IteratorTuple
Ituple IteratorTuple
Definition: Iterator.h:50
armarx::ZipIteratorBase< Ituple, Rtuple, std::index_sequence< Idxs... > >::reference
Rtuple reference
Definition: Iterator.h:51
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
lo
#define lo(x)
Definition: AbstractInterface.h:43
armarx::IteratorRange
Definition: Iterator.h:148
armarx::ZipIterator::ZipIterator
ZipIterator(It0 &&it0, Its &&...its)
Definition: Iterator.h:136
armarx::ZipIteratorBase
Definition: Iterator.h:38
armarx::MakeReversedRange
auto MakeReversedRange(Container &c)
Definition: Iterator.h:210
armarx::MakeZippedContainer
auto MakeZippedContainer(Container &c, Containers &...cs)
Definition: Iterator.h:191
armarx::IteratorRange::IteratorRange
IteratorRange(It b, It e)
Definition: Iterator.h:150
armarx::IteratorRange::begin
It begin() const
Definition: Iterator.h:153
armarx::ZipIterator
Definition: Iterator.h:112
std
Definition: Application.h:66
hi
#define hi(x)
Definition: AbstractInterface.h:42
armarx::ZipIteratorBase< Ituple, Rtuple, std::index_sequence< Idxs... > >::difference_type
std::ptrdiff_t difference_type
Definition: Iterator.h:52
armarx::MakeIndexedContainer
auto MakeIndexedContainer(Container &c, Containers &...cs)
Definition: Iterator.h:172
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::IteratorRange::end
It end() const
Definition: Iterator.h:157