9namespace bricks::detail {
15template <
typename... Args, std::size_t... Index>
16auto any_match_impl(std::tuple<Args...>
const& lhs, std::tuple<Args...>
const& rhs,
17 std::index_sequence<Index...> ) ->
bool
19 return (... || (std::get<Index>(lhs) == std::get<Index>(rhs)));
25template <
typename... Args>
26auto any_match(std::tuple<Args...>
const& lhs, std::tuple<Args...>
const& rhs) ->
bool
28 return any_match_impl(lhs, rhs, std::index_sequence_for<Args...>{});
37template <
typename Iter>
38using tuple_value_type =
39 std::conditional_t<std::is_same_v<Iter, std::vector<bool>::iterator> ||
40 std::is_same_v<Iter, std::vector<bool>::const_iterator>,
41 typename Iter::value_type,
typename Iter::reference>;
43template <
typename... Iters>
46 using iterator_category = std::forward_iterator_tag;
47 using value_type = std::tuple<tuple_value_type<Iters>...>;
48 using difference_type = std::ptrdiff_t;
49 using pointer = value_type*;
50 using reference = value_type&;
52 zip_iterator() =
delete;
54 explicit zip_iterator(Iters&&... iters) : ierators_{std::move(iters)...} {}
56 auto operator++() -> zip_iterator&
58 std::apply([](
auto&&... args) { ((args++), ...); }, ierators_);
62 auto operator++(
int) -> zip_iterator
69 auto operator==(zip_iterator
const& other) {
return any_match(ierators_, other.ierators_); }
70 auto operator!=(zip_iterator
const& other) {
return !(*
this == other); }
72 auto operator*() const -> value_type
74 return std::apply([](
auto&&... args) {
return value_type(*args...); }, ierators_);
78 std::tuple<Iters...> ierators_;
83using select_iterator_for = std::conditional_t<std::is_const_v<std::remove_reference_t<T>>,
84 typename std::decay_t<T>::const_iterator,
85 typename std::decay_t<T>::iterator>;
87template <
typename... T>
90 using iter_t = zip_iterator<select_iterator_for<T>...>;
92 explicit zipper(T&&... args) : args_{args...} {}
94 auto begin() const -> iter_t
96 return std::apply([](
auto&&... args) {
return iter_t(std::begin(args)...); }, args_);
98 auto end() const -> iter_t
100 return std::apply([](
auto&&... args) {
return iter_t(std::end(args)...); }, args_);
104 std::tuple<T...> args_;