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 <algorithm>
29 #include <stdexcept>
30 #include <tuple>
31 #include <utility>
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<ZipIteratorBase<Ituple, Rtuple, std::index_sequence<Idxs...>>,
43  Rtuple,
44  boost::forward_traversal_tag,
45  Rtuple>
46  {
47  public:
48  using IteratorTuple = Ituple;
49  using reference = Rtuple;
50  using difference_type = std::ptrdiff_t;
51 
52  private:
53  IteratorTuple _iters;
54 
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  {
64  }
65 
66  private:
67  friend class boost::iterator_core_access;
68 
69  // Implementation of Iterator Operations
70  // =====================================
71  reference
72  dereference() const
73  {
74  return std::forward_as_tuple(*std::get<Idxs>(_iters)...);
75  }
76 
77  bool
78  equal(const ZipIteratorBase& other) const
79  {
80  return _iters == other._iters;
81  }
82 
83  // Advancing a zip iterator means to advance all iterators in the
84  // iterator tuple.
85  void
86  advance(difference_type n)
87  {
88  ((std::get<Idxs>(_iters) += n), ...);
89  }
90 
91  // Incrementing a zip iterator means to increment all iterators in
92  // the iterator tuple.
93  void
94  increment()
95  {
96  (++std::get<Idxs>(_iters), ...);
97  }
98 
99  // Decrementing a zip iterator means to decrement all iterators in
100  // the iterator tuple.
101  void
102  decrement()
103  {
104  (--std::get<Idxs>(_iters), ...);
105  }
106 
107  // // Distance is calculated using the first iterator in the tuple.
108  // template<typename OtherIteratorTuple>
109  // typename super_t::difference_type distance_to(
110  // const zip_iterator<OtherIteratorTuple>& other
111  // ) const
112  // {
113  // return fusion::at_c<0>(other.get_iterator_tuple()) -
114  // fusion::at_c<0>(this->get_iterator_tuple());
115  // }
116  };
117 
118  template <class It0, class... Its>
119  class ZipIterator :
120  public ZipIteratorBase<std::tuple<It0, Its...>,
121  std::tuple<typename std::iterator_traits<It0>::reference&&,
122  typename std::iterator_traits<Its>::reference&&...>,
123  std::make_index_sequence<1 + sizeof...(Its)>>
124  {
125  public:
126  using Base = ZipIteratorBase<std::tuple<It0, Its...>,
127  std::tuple<typename std::iterator_traits<It0>::reference&&,
128  typename std::iterator_traits<Its>::reference&&...>,
129  std::make_index_sequence<1 + sizeof...(Its)>>;
130 
131  ZipIterator(It0&& it0, Its&&... its) :
132  Base({std::forward<It0>(it0), std::forward<Its>(its)...})
133  {
134  }
135 
136  using Base::Base;
137  using Base::operator=;
138  };
139 } // namespace armarx
140 
141 #include <utility>
142 
143 namespace armarx
144 {
145  template <class It>
147  {
148  IteratorRange(It b, It e) : _begin{std::move(b)}, _end{std::move(e)}
149  {
150  }
151 
152  It
153  begin() const
154  {
155  return _begin;
156  }
157 
158  It
159  end() const
160  {
161  return _end;
162  }
163 
164  private:
165  It _begin;
166  It _end;
167  };
168 } // namespace armarx
169 
170 #include <boost/iterator/counting_iterator.hpp>
171 #include <boost/iterator/zip_iterator.hpp>
172 
173 namespace armarx
174 {
175  template <class Container, class... Containers>
176  auto
177  MakeIndexedContainer(Container& c, Containers&... cs)
178  {
179  if constexpr (sizeof...(Containers))
180  {
181  const auto initlist = {c.size(), cs.size()...};
182  const auto [lo, hi] = std::minmax(initlist);
183  if (lo != hi)
184  {
185  throw std::invalid_argument{"All containers have to be of the same size!"};
186  }
187  }
188  return IteratorRange{
189  ZipIterator(boost::counting_iterator<std::size_t>(0), c.begin(), cs.begin()...),
190  ZipIterator(boost::counting_iterator<std::size_t>(c.size()), c.end(), cs.end()...)};
191  }
192 
193  template <class Container, class... Containers>
194  auto
195  MakeZippedContainer(Container& c, Containers&... cs)
196  {
197  if constexpr (sizeof...(Containers))
198  {
199  const auto initlist = {c.size(), cs.size()...};
200  const auto [lo, hi] = std::minmax(initlist);
201  if (lo != hi)
202  {
203  throw std::invalid_argument{"All containers have to be of the same size!"};
204  }
205  }
206  return IteratorRange{ZipIterator(c.begin(), cs.begin()...),
207  ZipIterator(c.end(), cs.end()...)};
208  }
209 
210  template <class Container>
211  auto
212  MakeReversedRange(Container& c)
213  {
214  return IteratorRange{c.rbegin(), c.rend()};
215  }
216 } // namespace armarx
armarx::MakeIndexedContainer
auto MakeIndexedContainer(Container &c, Containers &... cs)
Definition: Iterator.h:177
armarx::ZipIterator::ZipIterator
ZipIterator(It0 &&it0, Its &&... its)
Definition: Iterator.h:131
armarx::ZipIteratorBase< Ituple, Rtuple, std::index_sequence< Idxs... > >::ZipIteratorBase
ZipIteratorBase(IteratorTuple its)
Definition: Iterator.h:62
armarx::MakeZippedContainer
auto MakeZippedContainer(Container &c, Containers &... cs)
Definition: Iterator.h:195
armarx::ZipIteratorBase< Ituple, Rtuple, std::index_sequence< Idxs... > >::IteratorTuple
Ituple IteratorTuple
Definition: Iterator.h:48
armarx::ZipIteratorBase< Ituple, Rtuple, std::index_sequence< Idxs... > >::reference
Rtuple reference
Definition: Iterator.h:49
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
lo
#define lo(x)
Definition: AbstractInterface.h:47
armarx::IteratorRange
Definition: Iterator.h:146
armarx::ZipIteratorBase
Definition: Iterator.h:38
armarx::MakeReversedRange
auto MakeReversedRange(Container &c)
Definition: Iterator.h:212
armarx::IteratorRange::IteratorRange
IteratorRange(It b, It e)
Definition: Iterator.h:148
armarx::IteratorRange::begin
It begin() const
Definition: Iterator.h:153
armarx::ZipIterator
Definition: Iterator.h:119
std
Definition: Application.h:66
hi
#define hi(x)
Definition: AbstractInterface.h:46
armarx::ZipIteratorBase< Ituple, Rtuple, std::index_sequence< Idxs... > >::difference_type
std::ptrdiff_t difference_type
Definition: Iterator.h:50
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::IteratorRange::end
It end() const
Definition: Iterator.h:159