Skip to content

Commit 34fb85d

Browse files
mdonakaclaude
andcommitted
replace custom range views with C++23 standard library
- Remove zip_view, cartesian_product_view implementations - Use std::views::zip, enumerate, cartesian_product - Keep flatten_view and product_n (not in standard) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 5713f1e commit 34fb85d

1 file changed

Lines changed: 1 addition & 328 deletions

File tree

Library/Range/util.hpp

Lines changed: 1 addition & 328 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)