@@ -31,125 +31,7 @@ namespace mtd {
3131 return std::input_iterator_tag{};
3232 }
3333 }
34- } // namespace __detail
35-
36- template <std::ranges::range... _Range>
37- struct zip_view : public std ::ranges::view_interface<zip_view<_Range...>> {
38- class iterator {
39- public:
40- std::tuple<std::ranges::iterator_t <_Range>...> _M_current;
41-
42- using difference_type = int ;
43- using value_type = std::tuple<
44- std::iter_reference_t <std::ranges::iterator_t <_Range>>...>;
45- using iterator_concept =
46- decltype (__detail::_S_iter_concept<_Range...>());
4734
48- constexpr iterator () = default;
49- constexpr explicit iterator (const decltype (_M_current)& __current)
50- : _M_current(__current) {}
51- constexpr auto operator *() const {
52- return util::tuple_transform ([](auto & __i) { return *__i; },
53- _M_current);
54- }
55- constexpr auto & operator ++() {
56- util::tuple_for_each ([](auto & __i) { ++__i; }, _M_current);
57- return *this ;
58- }
59- constexpr auto operator ++(int ) { return ++*this ; }
60- constexpr auto operator ==(const iterator& other) const {
61- return [&]<size_t ... _Is>(std::index_sequence<_Is...>) {
62- return ((std::get<_Is>(_M_current) ==
63- std::get<_Is>(other._M_current )) ||
64- ...);
65- }
66- (std::make_index_sequence<sizeof ...(_Range)>{});
67- }
68- constexpr auto & operator --() requires
69- __detail::__all_bidirectional<_Range...> {
70- util::tuple_for_each ([](auto & __i) { --__i; }, _M_current);
71- return *this ;
72- }
73- constexpr auto operator --(
74- int ) requires __detail::__all_bidirectional<_Range...> {
75- return --*this ;
76- }
77- constexpr auto operator <=>(const iterator&)
78- const requires __detail::__all_random_access<_Range...>
79- = default ;
80- constexpr auto operator -(const iterator& itr)
81- const requires __detail::__all_random_access<_Range...> {
82- return [&]<size_t ... _Is>(std::index_sequence<_Is...>) {
83- return std::ranges::min ({difference_type (
84- std::get<_Is>(_M_current) - std::get<_Is>(itr._M_current ))...});
85- }
86- (std::make_index_sequence<sizeof ...(_Range)>{});
87- }
88- constexpr auto & operator +=(const difference_type n) requires
89- __detail::__all_random_access<_Range...> {
90- util::tuple_for_each ([&n](auto & __i) { __i += n; }, _M_current);
91- return *this ;
92- }
93- constexpr auto operator +(const difference_type n)
94- const requires __detail::__all_random_access<_Range...> {
95- auto __tmp = *this ;
96- __tmp += n;
97- return __tmp;
98- }
99- constexpr friend auto operator +(const difference_type n,
100- const iterator& itr) requires
101- __detail::__all_random_access<_Range...> {
102- return itr + n;
103- }
104- constexpr auto & operator -=(const difference_type n) requires
105- __detail::__all_random_access<_Range...> {
106- util::tuple_for_each ([&n](auto & __i) { __i -= n; }, _M_current);
107- return *this ;
108- }
109- constexpr auto operator -(const difference_type n)
110- const requires __detail::__all_random_access<_Range...> {
111- auto __tmp = *this ;
112- __tmp -= n;
113- return __tmp;
114- }
115- constexpr auto operator [](const difference_type n)
116- const requires __detail::__all_random_access<_Range...> {
117- return util::tuple_transform ([&n](auto & __i) { return __i[n]; },
118- _M_current);
119- }
120- };
121-
122- class sentinel {
123- public:
124- std::tuple<std::ranges::sentinel_t <_Range>...> _M_end;
125-
126- constexpr sentinel () = default;
127- constexpr explicit sentinel (const decltype (_M_end)& __end)
128- : _M_end(__end) {}
129-
130- friend constexpr bool operator ==(const iterator& __x,
131- const sentinel& __y) {
132- return [&]<size_t ... _Is>(std::index_sequence<_Is...>) {
133- return (
134- (std::get<_Is>(__x._M_current ) == std::get<_Is>(__y._M_end )) ||
135- ...);
136- }
137- (std::make_index_sequence<sizeof ...(_Range)>{});
138- }
139- };
140-
141- std::tuple<_Range...> _M_views;
142- constexpr explicit zip_view (const _Range&... __views)
143- : _M_views(__views...) {}
144- constexpr auto begin () {
145- return iterator (util::tuple_transform (std::ranges::begin, _M_views));
146- }
147- constexpr auto end () {
148- return sentinel (util::tuple_transform (std::ranges::end, _M_views));
149- }
150- };
151-
152- namespace __detail {
15335 template <typename T>
15436 auto _flatten (const T& t) {
15537 return std::make_tuple (t);
@@ -265,213 +147,16 @@ namespace mtd {
265147 constexpr auto end () { return sentinel (std::ranges::end (_M_views)); }
266148 };
267149
268- template <std::ranges::range... _Range>
269- struct cartesian_product_view : public std ::ranges::view_interface<
270- cartesian_product_view<_Range...>> {
271- class iterator {
272- public:
273- using _Parent = cartesian_product_view;
274- _Parent* _M_parent = nullptr ;
275- std::tuple<std::ranges::iterator_t <_Range>...> _M_current;
276-
277- using difference_type = int ;
278- using value_type = std::tuple<
279- std::iter_reference_t <std::ranges::iterator_t <_Range>>...>;
280- using iterator_concept =
281- decltype (__detail::_S_iter_concept<_Range...>());
282-
283- private:
284- template <size_t _Nm = sizeof ...(_Range) - 1 >
285- constexpr void _M_next () {
286- auto & __it = std::get<_Nm>(_M_current);
287- ++__it;
288- if constexpr (_Nm > 0 )
289- if (__it == std::ranges::end (std::get<_Nm>(_M_parent->_M_views ))) {
290- __it = std::ranges::begin (std::get<_Nm>(_M_parent->_M_views ));
291- _M_next<_Nm - 1 >();
292- }
293- }
294- template <size_t _Nm = sizeof ...(_Range) - 1 >
295- constexpr void _M_prev () {
296- auto & __it = std::get<_Nm>(_M_current);
297- if constexpr (_Nm > 0 )
298- if (__it ==
299- std::ranges::begin (std::get<_Nm>(_M_parent->_M_views ))) {
300- __it = std::ranges::end (std::get<_Nm>(_M_parent->_M_views ));
301- _M_prev<_Nm - 1 >();
302- }
303- --__it;
304- }
305-
306- template <size_t _Nm = sizeof ...(_Range) - 1 >
307- constexpr void _M_advance (difference_type __x) requires
308- __detail::__all_random_access<_Range...> {
309- if (__x == 1 )
310- _M_next<_Nm>();
311- else if (__x == -1 )
312- _M_prev<_Nm>();
313- else if (__x != 0 ) {
314- auto & __r = std::get<_Nm>(_M_parent->_M_views );
315- auto & __it = std::get<_Nm>(_M_current);
316- if constexpr (_Nm == 0 ) {
317- __it += __x;
318- } else {
319- auto __size = std::ranges::ssize (__r);
320- auto __begin = std::ranges::begin (__r);
321- auto __offset = __it - __begin;
322- __offset += __x;
323- __x = __offset / __size;
324- __offset %= __size;
325- if (__offset < 0 ) {
326- __offset = __size + __offset;
327- --__x;
328- }
329- __it = __begin + __offset;
330- _M_advance<_Nm - 1 >(__x);
331- }
332- }
333- }
334-
335- public:
336- constexpr iterator () = default;
337- constexpr explicit iterator (_Parent& __parent,
338- const decltype (_M_current)& __current)
339- : _M_parent(std::addressof(__parent)), _M_current(__current) {}
340- constexpr auto operator *() const {
341- return util::tuple_transform ([](auto & __i) { return *__i; },
342- _M_current);
343- }
344- constexpr auto & operator ++() {
345- _M_next ();
346- return *this ;
347- }
348- constexpr auto operator ++(int ) { return ++*this ; }
349- constexpr auto operator ==(const iterator& other) const {
350- return [&]<size_t ... _Is>(std::index_sequence<_Is...>) {
351- return ((std::get<_Is>(_M_current) ==
352- std::get<_Is>(other._M_current )) ||
353- ...);
354- }
355- (std::make_index_sequence<sizeof ...(_Range)>{});
356- }
357- constexpr auto & operator --() requires
358- __detail::__all_bidirectional<_Range...> {
359- _M_prev ();
360- return *this ;
361- }
362- constexpr auto operator --(
363- int ) requires __detail::__all_bidirectional<_Range...> {
364- return --*this ;
365- }
366- constexpr auto operator <=>(const iterator&)
367- const requires __detail::__all_random_access<_Range...>
368- = default ;
369- constexpr auto operator -(const iterator& itr)
370- const requires __detail::__all_random_access<_Range...> {
371- return [&]<size_t ... _Is>(std::index_sequence<_Is...>) {
372- return std::ranges::min ({difference_type (
373- std::get<_Is>(_M_current) - std::get<_Is>(itr._M_current ))...});
374- }
375- (std::make_index_sequence<sizeof ...(_Range)>{});
376- }
377- constexpr auto & operator +=(const difference_type n) requires
378- __detail::__all_random_access<_Range...> {
379- _M_advance (n);
380- return *this ;
381- }
382- constexpr auto operator +(const difference_type n)
383- const requires __detail::__all_random_access<_Range...> {
384- auto __tmp = *this ;
385- __tmp += n;
386- return __tmp;
387- }
388- constexpr friend auto operator +(const difference_type n,
389- const iterator& itr) requires
390- __detail::__all_random_access<_Range...> {
391- return itr + n;
392- }
393- constexpr auto & operator -=(const difference_type n) requires
394- __detail::__all_random_access<_Range...> {
395- *this += -n;
396- return *this ;
397- }
398- constexpr auto operator -(const difference_type n)
399- const requires __detail::__all_random_access<_Range...> {
400- auto __tmp = *this ;
401- __tmp -= n;
402- return __tmp;
403- }
404- constexpr auto operator [](const difference_type n)
405- const requires __detail::__all_random_access<_Range...> {
406- return util::tuple_transform ([&n](auto & __i) { return __i[n]; },
407- _M_current);
408- }
409- };
410-
411- class sentinel {
412- public:
413- std::tuple<std::ranges::sentinel_t <_Range>...> _M_end;
414-
415- constexpr sentinel () = default;
416- constexpr explicit sentinel (const decltype (_M_end)& __end)
417- : _M_end(__end) {}
418-
419- friend constexpr bool operator ==(const iterator& __x,
420- const sentinel& __y) {
421- return [&]<size_t ... _Is>(std::index_sequence<_Is...>) {
422- return (
423- (std::get<_Is>(__x._M_current ) == std::get<_Is>(__y._M_end )) ||
424- ...);
425- }
426- (std::make_index_sequence<sizeof ...(_Range)>{});
427- }
428- };
429-
430- std::tuple<_Range...> _M_views;
431- constexpr explicit cartesian_product_view (const _Range&... __views)
432- : _M_views(__views...) {}
433- constexpr auto begin () {
434- return iterator (*this ,
435- util::tuple_transform (std::ranges::begin, _M_views));
436- }
437- constexpr auto end () {
438- return sentinel (util::tuple_transform (std::ranges::end, _M_views));
439- }
440- };
441-
442150 } // namespace ranges
443151
444152 namespace views {
445153 namespace __detail {
446- template <typename ... _Args>
447- concept __can_zip_view = requires {
448- ranges::zip_view (std::declval<_Args>()...);
449- };
450154 template <typename ... _Args>
451155 concept __can_flatten_view = requires {
452156 ranges::flatten_view (std::declval<_Args>()...);
453157 };
454- template <typename ... _Args>
455- concept __can_cartesian_product_view = requires {
456- ranges::cartesian_product_view (std::declval<_Args>()...);
457- };
458158 } // namespace __detail
459159
460- struct _ZipView {
461- template <class ... _Tp>
462- requires __detail::__can_zip_view<_Tp...>
463- constexpr auto operator () [[nodiscard]] (_Tp&&... __e) const {
464- return ranges::zip_view (std::forward<_Tp>(__e)...);
465- }
466- };
467- struct _Enumerate : std::ranges::range_adaptor_closure<_Enumerate> {
468- template <class _Tp >
469- requires __detail::__can_zip_view<std::ranges::iota_view<size_t >, _Tp>
470- constexpr auto operator () [[nodiscard]] (_Tp&& __e) const {
471- return ranges::zip_view{std::views::iota (0 ), std::forward<_Tp>(__e)};
472- }
473- static constexpr bool _S_has_simple_call_op = true ;
474- };
475160 struct _Flatten : std::ranges::range_adaptor_closure<_Flatten> {
476161 template <class ... _Tp>
477162 requires __detail::__can_flatten_view<_Tp...>
@@ -480,26 +165,14 @@ namespace mtd {
480165 }
481166 static constexpr bool _S_has_simple_call_op = true ;
482167 };
483- struct _CartesianProduct {
484- template <class ... _Tp>
485- requires __detail::__can_cartesian_product_view<_Tp...>
486- constexpr auto operator () [[nodiscard]] (_Tp&&... __e) const {
487- return ranges::cartesian_product_view (std::forward<_Tp>(__e)...);
488- }
489- };
490168 struct _ProductN {
491169 template <class ... _Tp>
492- requires __detail::__can_cartesian_product_view<
493- std::ranges::iota_view<size_t , _Tp>...>
494170 constexpr auto operator () [[nodiscard]] (_Tp... __e) const {
495- return ranges::cartesian_product_view (std::views::iota (0 , __e)...);
171+ return std::views::cartesian_product (std::views::iota (0 , __e)...);
496172 }
497173 };
498174
499- inline constexpr _ZipView zip{};
500- inline constexpr _Enumerate enumerate{};
501175 inline constexpr _Flatten flatten{};
502- inline constexpr _CartesianProduct cartesian_product{};
503176 inline constexpr _ProductN product_n{};
504177 } // namespace views
505178} // namespace mtd
0 commit comments