R-Type  2
Doom but in better
Loading...
Searching...
No Matches
ZipperIterator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <tuple>
5#include <optional>
6#include <type_traits>
7#include <iterator>
8#include <iostream>
9
19template <class... Containers>
22 template <class Container>
23 using iterator_t = typename Container::iterator;
24
26 template <class Container>
27 using it_reference_t = decltype(std::declval<Container>()[0]);
28
29public:
31 using value_type = std::tuple<it_reference_t<Containers>...>;
33 using pointer = void;
34 using difference_type = std::size_t;
35 using iterator_category = std::input_iterator_tag;
38 using iterator_tuple = std::tuple<iterator_t<Containers>...>;
39
46 ZipperIterator(iterator_tuple const& it_tuple, std::size_t max, std::size_t idx = 0) : _current(it_tuple), _max(max), _idx(idx) {}
47
53 ZipperIterator(const ZipperIterator& z) : _current(z._current), _max(z._max), _idx(z._idx) {}
54
63 incr_all(std::index_sequence_for<Containers...>{});
64 return *this;
65 }
66
75 ZipperIterator tmp(*this);
76 ++(*this);
77 return tmp;
78 }
79
88 return to_value(std::index_sequence_for<Containers...>{});
89 }
90
99 return &(*this);
100 }
101
112 return lhs._idx == rhs._idx;
113 }
114
125 return lhs._idx != rhs._idx;
126 }
127
128private:
134 template <std::size_t... Is>
135 void incr_all(std::index_sequence<Is...>) {
136 (++std::get<Is>(_current), ...);
137 ++_idx;
138
139 while (_idx < _max && !all_set(std::index_sequence<Is...>{})) {
140 (++std::get<Is>(_current), ...);
141 ++_idx;
142 }
143 }
144
151 template <std::size_t... Is>
152 bool all_set(std::index_sequence<Is...>) {
153 return (... && std::get<Is>(_current)[0].has_value());
154 }
155
162 template <std::size_t... Is>
163 value_type to_value(std::index_sequence<Is...>) {
164 return std::tuple<it_reference_t<Containers>...>(*(std::get<Is>(_current))...);
165 }
166
167private:
168 iterator_tuple _current;
169 std::size_t _max;
170 std::size_t _idx;
171 static constexpr std::index_sequence_for<Containers...> _seq{};
172};
Iterator for traversing multiple zipped containers simultaneously.
std::input_iterator_tag iterator_category
ZipperIterator(iterator_tuple const &it_tuple, std::size_t max, std::size_t idx=0)
Constructs a ZipperIterator with the provided iterator tuple and maximum iteration count.
friend bool operator==(const ZipperIterator< Containers... > &lhs, const ZipperIterator< Containers... > &rhs)
Equality operator.
value_type * operator->()
Member access operator.
std::tuple< it_reference_t< Containers >... > value_type
Type alias for the value type returned by the iterator.
std::size_t difference_type
ZipperIterator(const ZipperIterator &z)
Copy constructor.
std::tuple< iterator_t< Containers >... > iterator_tuple
Type alias for the tuple of iterators used in the zipped containers.
ZipperIterator & operator++()
Pre-increment operator.
ZipperIterator operator++(int)
Post-increment operator.
value_type & reference
friend bool operator!=(const ZipperIterator< Containers... > &lhs, const ZipperIterator< Containers... > &rhs)
Inequality operator.
value_type operator*()
Dereference operator.