@@ -29,21 +29,6 @@ namespace containers {
2929template <typename ... Iterators>
3030struct zip_iterator ;
3131
32- template <typename ... Ts>
33- constexpr auto ref_or_value_tuple (Ts && ... args) {
34- return tv::tuple<Ts...>(OPERATORS_FORWARD (args)...);
35- }
36-
37- template <std::size_t ... indexes>
38- constexpr auto dereference (auto const & tuple, std::index_sequence<indexes...>) {
39- return ref_or_value_tuple (*tuple[bounded::constant<indexes>]...);
40- }
41-
42- template <typename ... Iterators, std::size_t ... indexes>
43- constexpr auto add (tv::tuple<Iterators...> tuple, auto const offset, std::index_sequence<indexes...>) -> zip_iterator<Iterators...> {
44- return zip_iterator<Iterators...>((std::move (tuple)[bounded::constant<indexes>] + offset)...);
45- }
46-
4732template <typename ... Iterators>
4833struct zip_difference_type_impl {
4934 static constexpr auto min_max = bounded::min(
@@ -77,17 +62,20 @@ struct zip_iterator {
7762 }
7863
7964 friend constexpr auto operator *(zip_iterator const & it) {
80- return dereference (it.m_its , indexes);
65+ auto const & [...its ] = it.m_its ;
66+ return tv::tuple<decltype (*its)...>(*its...);
8167 }
82- friend constexpr auto operator +(zip_iterator it, bounded::constant_t <1 >) -> zip_iterator {
68+ friend constexpr auto operator +(zip_iterator it, bounded::constant_t <1 > const offset ) -> zip_iterator {
8369 if constexpr (sizeof ...(Iterators) == 0 ) {
8470 std::unreachable ();
8571 } else {
86- return add (std::move (it).m_its , 1_bi, indexes);
72+ auto && [...its ] = std::move (it).m_its ;
73+ return zip_iterator ((std::move (its) + offset)...);
8774 }
8875 }
8976 friend constexpr auto operator +(zip_iterator it, bounded::convertible_to<difference_type> auto const offset) -> zip_iterator {
90- return add (std::move (it).m_its , offset, indexes);
77+ auto && [...its ] = std::move (it).m_its ;
78+ return zip_iterator ((std::move (its) + offset)...);
9179 }
9280
9381 friend auto operator <=>(zip_iterator const &, zip_iterator const &) = default ;
@@ -96,20 +84,9 @@ struct zip_iterator {
9684 friend struct zip_sentinel ;
9785 template <typename ... Sentinels>
9886 friend struct zip_smallest_sentinel ;
99- static constexpr auto indexes = std::make_index_sequence<sizeof ...(Iterators)>();
10087 [[no_unique_address]] tv::tuple<Iterators...> m_its;
10188};
10289
103- template <std::size_t ... indexes>
104- constexpr auto all (auto const & lhs, auto const & rhs, std::index_sequence<indexes...>, auto const predicate) {
105- return (... and predicate (lhs[bounded::constant<indexes>], rhs[bounded::constant<indexes>]));
106- }
107-
108- template <std::size_t ... indexes>
109- constexpr auto any (auto const & lhs, auto const & rhs, std::index_sequence<indexes...>, auto const predicate) {
110- return (... or predicate (lhs[bounded::constant<indexes>], rhs[bounded::constant<indexes>]));
111- }
112-
11390template <typename ... Sentinels>
11491struct zip_sentinel {
11592 constexpr explicit zip_sentinel (Sentinels... sentinels):
@@ -118,10 +95,10 @@ struct zip_sentinel {
11895 }
11996 template <typename ... Iterators> requires (sizeof ...(Iterators) == sizeof...(Sentinels))
12097 friend constexpr auto operator==(zip_iterator<Iterators...> const & lhs, zip_sentinel const rhs) -> bool {
121- constexpr auto indexes = std::make_index_sequence <sizeof ...(Sentinels)>();
122- if (all ( lhs.m_its , rhs.m_sentinels , indexes, std::not_equal_to ( ))) {
98+ auto const [... indexes ] = bounded::index_sequence_struct <sizeof ...(Sentinels)>();
99+ if ((... and ( lhs.m_its [indexes] != rhs.m_sentinels [ indexes] ))) {
123100 return false ;
124- } else if (all ( lhs.m_its , rhs.m_sentinels , indexes, std::equal_to ( ))) {
101+ } else if ((... and ( lhs.m_its [indexes] == rhs.m_sentinels [ indexes] ))) {
125102 return true ;
126103 } else {
127104 throw std::runtime_error (" Mismatched sizes for inputs to zip" );
@@ -139,8 +116,8 @@ struct zip_smallest_sentinel {
139116 }
140117 template <typename ... Iterators> requires (sizeof ...(Iterators) == sizeof...(Sentinels))
141118 friend constexpr auto operator==(zip_iterator<Iterators...> const & lhs, zip_smallest_sentinel const rhs) -> bool {
142- constexpr auto indexes = std::make_index_sequence <sizeof ...(Sentinels)>();
143- return any ( lhs.m_its , rhs.m_sentinels , indexes, std::equal_to ( ));
119+ auto const [... indexes ] = bounded::index_sequence_struct <sizeof ...(Sentinels)>();
120+ return (... or ( lhs.m_its [indexes] == rhs.m_sentinels [ indexes] ));
144121 }
145122private:
146123 [[no_unique_address]] tv::tuple<Sentinels...> m_sentinels;
@@ -154,38 +131,6 @@ constexpr auto all_are_equal() -> bool {
154131 return true ;
155132}
156133
157- template <std::size_t ... indexes>
158- constexpr auto make_zip_iterator (auto && ranges, std::index_sequence<indexes...>, auto get) {
159- return zip_iterator (
160- get (OPERATORS_FORWARD (ranges)[bounded::constant<indexes>])...
161- );
162- }
163-
164- // https://github.com/llvm/llvm-project/issues/59513
165- struct use_begin {
166- static constexpr auto operator ()(auto && r) {
167- return containers::begin (OPERATORS_FORWARD (r));
168- }
169- };
170- struct use_end {
171- static constexpr auto operator ()(auto && r) {
172- return containers::end (OPERATORS_FORWARD (r));
173- }
174- };
175-
176- template <bool check_equal_sizes, std::size_t ... indexes>
177- constexpr auto make_zip_sentinel (auto && ranges, std::index_sequence<indexes...>) {
178- if constexpr (check_equal_sizes) {
179- return zip_sentinel (
180- containers::end (OPERATORS_FORWARD (ranges)[bounded::constant<indexes>])...
181- );
182- } else {
183- return zip_smallest_sentinel (
184- containers::end (OPERATORS_FORWARD (ranges)[bounded::constant<indexes>])...
185- );
186- }
187- }
188-
189134template <typename Range>
190135concept supports_begin = requires (Range r) {
191136 containers::begin (OPERATORS_FORWARD (r));
@@ -208,7 +153,6 @@ export template<bool check_equal_sizes, range... Ranges>
208153struct zip_impl {
209154private:
210155 static constexpr auto all_are_sized = (... and sized_range<Ranges>);
211- static constexpr auto indexes = std::make_index_sequence<sizeof ...(Ranges)>();
212156
213157 static constexpr auto as_tuple (Ranges && ... ranges) {
214158 if constexpr (all_are_sized and !check_equal_sizes and sizeof ...(Ranges) != 0 ) {
@@ -221,18 +165,14 @@ struct zip_impl {
221165
222166 decltype (as_tuple(bounded::declval<Ranges>()...)) m_ranges;
223167
224- static constexpr auto end_impl (auto && ranges) {
168+ static constexpr auto end_impl (auto && m_ranges) {
169+ auto && [...ranges ] = OPERATORS_FORWARD (m_ranges);
225170 if constexpr (all_are_sized) {
226- return ::containers::make_zip_iterator (
227- OPERATORS_FORWARD (ranges),
228- indexes,
229- use_end ()
230- );
171+ return zip_iterator (::containers::end (OPERATORS_FORWARD (ranges))...);
172+ } else if constexpr (check_equal_sizes) {
173+ return zip_sentinel (containers::end (OPERATORS_FORWARD (ranges))...);
231174 } else {
232- return ::containers::make_zip_sentinel<check_equal_sizes>(
233- OPERATORS_FORWARD (ranges),
234- indexes
235- );
175+ return zip_smallest_sentinel (containers::end (OPERATORS_FORWARD (ranges))...);
236176 }
237177 }
238178
@@ -255,13 +195,16 @@ struct zip_impl {
255195 }
256196
257197 constexpr auto begin () const & requires all_support_begin<Ranges const &...> {
258- return make_zip_iterator (m_ranges, indexes, use_begin ());
198+ auto && [...ranges ] = m_ranges;
199+ return zip_iterator (::containers::begin (OPERATORS_FORWARD (ranges))...);
259200 }
260201 constexpr auto begin () & requires all_support_begin<Ranges &...> {
261- return make_zip_iterator (m_ranges, indexes, use_begin ());
202+ auto && [...ranges ] = m_ranges;
203+ return zip_iterator (::containers::begin (OPERATORS_FORWARD (ranges))...);
262204 }
263205 constexpr auto begin () && requires all_support_begin<Ranges &&...> {
264- return make_zip_iterator (std::move (m_ranges), indexes, use_begin ());
206+ auto && [...ranges ] = std::move (m_ranges);
207+ return zip_iterator (::containers::begin (OPERATORS_FORWARD (ranges))...);
265208 }
266209
267210 constexpr auto end () const & requires all_support_end<Ranges const &...> {
0 commit comments