emlabcpp
modern opinionated embedded C++ library
zip.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./range.h"
27 #include "./types.h"
28 #include "./view.h"
29 
30 #include <tuple>
31 
32 namespace emlabcpp
33 {
34 template < typename... >
35 class zip_iterator;
36 }
37 
38 template < typename... Iterators >
39 struct std::iterator_traits< emlabcpp::zip_iterator< Iterators... > >
40 {
42  using difference_type = std::ptrdiff_t;
43  using pointer = void;
45  using iterator_category = std::bidirectional_iterator_tag;
46 };
47 
48 namespace emlabcpp
49 {
50 
56 template < typename... Iterators >
58 {
59  std::tuple< Iterators... > iters_;
60 
61 public:
62  constexpr zip_iterator( Iterators... iters )
63  : iters_( std::move( iters )... )
64  {
65  }
66 
69  {
70  std::apply(
71  []( auto&&... it ) { //
72  ( ++it, ... );
73  },
74  iters_ );
75 
76  return *this;
77  }
78 
81  {
82  std::apply(
83  []( auto&&... it ) { //
84  ( ++it, ... );
85  },
86  iters_ );
87 
88  return *this;
89  }
90 
91  constexpr zip_iterator& operator+=( std::ptrdiff_t m )
92  {
93  for_each( iters_, [&]( auto& iter ) {
94  iter += m;
95  } );
96  return *this;
97  }
98 
99  constexpr std::ptrdiff_t operator-( zip_iterator< Iterators... > const& other ) const
100  {
101  return std::get< 0 >( iters_ ) - std::get< 0 >( other.iters_ );
102  }
103 
106  constexpr auto operator*()
107  {
108  return std::apply(
109  []( auto&&... it ) { //
110  return std::forward_as_tuple( ( *it )... );
111  },
112  iters_ );
113  }
114 
116  constexpr bool operator==( zip_iterator< Iterators... > const& other ) const
117  {
118  return equals( other, std::index_sequence_for< Iterators... >{} );
119  }
120 
121 private:
122  template < typename std::size_t... Idx >
123  [[nodiscard]] constexpr bool
124  equals( zip_iterator< Iterators... > const& other, std::index_sequence< Idx... > ) const
125  {
126  return ( ( std::get< Idx >( iters_ ) == std::get< Idx >( other.iters_ ) ) || ... );
127  }
128 };
129 
130 template < typename... Iterators >
131 constexpr zip_iterator< Iterators... >
133 {
134  lh += m;
135  return lh;
136 }
137 
138 template < typename... Iterators >
139 constexpr bool
141 {
142  return !( lh == rh );
143 }
144 
149 //
150 template < range_container... Ts >
151 auto zip( Ts&&... cont )
152 {
153  return view( zip_iterator( std::begin( cont )... ), zip_iterator( std::end( cont )... ) );
154 }
155 
156 template < typename TuplesTuple, std::size_t... ItemIndexes, std::size_t... TupleIndexes >
158  TuplesTuple&& tpls,
159  std::index_sequence< ItemIndexes... >,
160  std::index_sequence< TupleIndexes... > )
161 {
162  auto f = [&]< typename Index >( Index ) {
163  return std::make_tuple(
164  std::get< Index::value >( std::get< TupleIndexes >( tpls ) )... );
165  };
166 
167  return std::make_tuple( f( std::integral_constant< std::size_t, ItemIndexes >{} )... );
168 }
169 
174 template < gettable_container Tuple, gettable_container... Tuples >
175 auto zip( Tuple&& frst, Tuples&&... tpls )
176 {
177  static_assert(
178  ( ( static_size_v< Tuple > == static_size_v< Tuples > ) && ... ),
179  "All tuples has to be of same size in zip" );
180  return tuple_zip_impl(
181  std::make_tuple( frst, tpls... ),
182  std::make_index_sequence< static_size_v< Tuple > >{},
183  std::make_index_sequence< sizeof...( Tuples ) + 1 >{} );
184 }
185 
186 } // namespace emlabcpp
zip_ierator iterates over a group of iterators, where value is a tuple of references to value for eac...
Definition: zip.h:58
constexpr std::ptrdiff_t operator-(zip_iterator< Iterators... > const &other) const
Definition: zip.h:99
constexpr auto operator*()
Dereference of each iterator, returns tuple of references to the operator* of iterators.
Definition: zip.h:106
constexpr zip_iterator operator++()
Increases each iterator.
Definition: zip.h:68
constexpr zip_iterator operator--()
Decreases each iterator.
Definition: zip.h:80
constexpr zip_iterator(Iterators... iters)
Definition: zip.h:62
constexpr zip_iterator & operator+=(std::ptrdiff_t m)
Definition: zip.h:91
constexpr bool operator==(zip_iterator< Iterators... > const &other) const
Two zip iterators are equal if all of their iterators are equal.
Definition: zip.h:116
std::variant< int64_t, float, bool, string_buffer > value_type
Definition: base.h:51
MIT License.
Definition: impl.h:31
constexpr point< N > operator+(point< N > a, vector< N > const &b)
Returns a result of addition a to b, viz += operator.
Definition: point.h:93
T & reference
Definition: static_storage.h:101
auto zip(Ts &&... cont)
Creates a view of zip iterators for specified containers.
Definition: zip.h:151
view(Container &cont) -> view< iterator_of_t< Container > >
The container deduction guide uses iterator_of_t.
constexpr void for_each(Container &&cont, UnaryCallable &&f)
Applies unary callable 'f' to each element of container 'cont'.
Definition: algorithm.h:171
concept range_container
so, std::ranges::range is meh because it expects return of begin() being input_output_iterator,...
Definition: concepts.h:78
auto tuple_zip_impl(TuplesTuple &&tpls, std::index_sequence< ItemIndexes... >, std::index_sequence< TupleIndexes... >)
Definition: zip.h:157
concept gettable_container
Definition: concepts.h:71
constexpr bool operator!=(pose const &x, pose const &y)
negation of operator== between poses
Definition: pose.h:99
UnaryCallable && f
Definition: algorithm.h:161
std::bidirectional_iterator_tag iterator_category
Definition: zip.h:45
std::tuple< typename std::iterator_traits< Iterators >::reference... > value_type
Definition: zip.h:41