R-Type  2
Doom but in better
Loading...
Searching...
No Matches
IndexedZipperIterator.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 = std::tuple<it_reference_t<Containers>...>;
32 using value_type = std::tuple<std::size_t, it_reference_t<Containers>...>;
34 using pointer = void;
35 using difference_type = std::size_t;
36 using iterator_category = std::forward_iterator_tag;
39 using iterator_tuple = std::tuple<iterator_t<Containers>...>;
40
47 IndexedZipperIterator(iterator_tuple it_tuple, std::size_t max, std::size_t idx = 0) : _current(it_tuple), _max(max), _idx(idx) {}
48
54 IndexedZipperIterator(const IndexedZipperIterator& z) : _current(z._current), _max(z._max), _idx(z._idx) {}
55
64 incr_all(std::index_sequence_for<Containers...>());
65 return *this;
66 }
67
76 IndexedZipperIterator tmp(*this);
77 ++(*this);
78 return tmp;
79 }
80
89 return std::tuple_cat(std::make_tuple(_idx), to_value(std::index_sequence_for<Containers...>()));
90 }
91
100 return &(*this);
101 }
102
113 return lhs._idx == rhs._idx;
114 }
115
126 return lhs._idx != rhs._idx;
127 }
128
129private:
135 template <std::size_t... Is>
136 void incr_all(std::index_sequence<Is...>) {
137 (++std::get<Is>(_current), ...);
138 ++_idx;
139
140 while (_idx < _max && !all_set(std::index_sequence<Is...>{})) {
141 (++std::get<Is>(_current), ...);
142 ++_idx;
143 }
144 }
145
152 template <std::size_t... Is>
153 bool all_set(std::index_sequence<Is...>) {
154 return (... && std::get<Is>(_current)[0].has_value());
155 }
156
163 template <std::size_t... Is>
164 value to_value(std::index_sequence<Is...>) {
165 return std::tuple<it_reference_t<Containers>...>(*(std::get<Is>(_current))...);
166 }
167
168private:
169 iterator_tuple _current;
170 std::size_t _max;
171 std::size_t _idx;
172 static constexpr std::index_sequence_for<Containers...> _seq{};
173};
Iterator for traversing the elements of multiple zipped containers, paired with their indices.
IndexedZipperIterator(iterator_tuple it_tuple, std::size_t max, std::size_t idx=0)
Constructs an IndexedZipperIterator with the current iterator positions and index.
friend bool operator==(const IndexedZipperIterator< Containers... > &lhs, const IndexedZipperIterator< Containers... > &rhs)
Inequality operator.
std::forward_iterator_tag iterator_category
friend bool operator!=(const IndexedZipperIterator< Containers... > &lhs, const IndexedZipperIterator< Containers... > &rhs)
Equality operator.
std::tuple< iterator_t< Containers >... > iterator_tuple
Type alias for the tuple of iterators for the containers being iterated.
IndexedZipperIterator(const IndexedZipperIterator &z)
Copy constructor.
std::tuple< it_reference_t< Containers >... > value
Type alias for the value type returned by the iterator.
IndexedZipperIterator operator++(int)
Post-increment operator.
std::tuple< std::size_t, it_reference_t< Containers >... > value_type
value_type operator*()
Dereference operator.
IndexedZipperIterator & operator++()
Pre-increment operator.
value_type * operator->()
Member access operator.