5 #ifndef VCCC_RANGES_VIEWS_ZIP_VIEW_HPP_
6 #define VCCC_RANGES_VIEWS_ZIP_VIEW_HPP_
10 #include <type_traits>
55 template<
bool AllForward >
56 struct zip_view_iterator_category {
61 struct zip_view_iterator_category<false> {
62 #if __cplusplus < 202002L
63 using iterator_category = iterator_ignore;
68 struct min_tuple_distance_fn {
69 template<
typename T1,
typename T2>
70 R operator()(
const T1& t1,
const T2& t2)
const {
71 static_assert(std::tuple_size<remove_cvref_t<T1>>::
value ==
72 std::tuple_size<remove_cvref_t<T2>>::
value,
"Size doesn't match");
74 return call(t1, t2, std::make_index_sequence<std::tuple_size<remove_cvref_t<T2>>::
value>{});
78 template<
typename T1,
typename T2, std::size_t... I>
79 R call(
const T1& t1,
const T2& t2, std::index_sequence<I...>)
const {
80 return (
ranges::min)({R(std::get<I>(t1) - std::get<I>(t2))...});
84 template<
typename... Rs>
88 bool_constant<sizeof...(Rs) == 1>,
93 conjunction<bidirectional_range<Rs>...>
98 random_access_range<Rs>...,
108 template<
typename... Views>
110 static constexpr std::size_t kViewCount =
sizeof...(Views);
111 using tuple_index_sequence = std::index_sequence_for<Views...>;
114 static_assert(
sizeof...(Views) > 0,
"Constraints not satisfied");
118 template<
bool Const>
class iterator;
119 template<
bool Const>
class sentinel;
123 class iterator :
public detail::zip_view_iterator_category<conjunction<forward_range<maybe_const<Const, Views>>...>::value> {
133 struct tuple_deref_fn {
135 constexpr decltype(
auto) operator()(I& i)
const {
153 #if __cplusplus < 202002L
157 std::declval<tuple_deref_fn>()
163 template<
bool AntiConst, std::enable_if_t<
conjunction<
168 : current_(
std::move(i.current_)) {}
170 constexpr decltype(
auto) operator*()
const {
175 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
181 [&](
auto& i) -> decltype(
auto) {
182 static_assert(std::is_lvalue_reference<decltype(i)>::
value,
"Invalid type");
194 template<
typename AF = all_forward, std::enable_if_t<!AF::value,
int> = 0>
199 template<
typename AF = all_forward, std::enable_if_t<AF::value,
int> = 0>
206 template<
typename AB = all_b
idirectional, std::enable_if_t<AB::value,
int> = 0>
211 template<
typename AB = all_b
idirectional, std::enable_if_t<AB::value,
int> = 0>
218 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
221 static_assert(std::is_lvalue_reference<decltype(i)>::
value,
"Invalid type");
228 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
231 static_assert(std::is_lvalue_reference<decltype(i)>::
value,
"Invalid type");
238 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
239 equality_comparable<iterator_t<maybe_const<Const, Views>>>...
245 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
246 equality_comparable<iterator_t<maybe_const<Const, Views>>>...
252 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
254 return x.current_ < y.current_;
257 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
259 using namespace rel_ops;
260 return x.current_ <= y.current_;
263 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
265 using namespace rel_ops;
266 return x.current_ > y.current_;
269 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
271 using namespace rel_ops;
272 return x.current_ >= y.current_;
275 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
282 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
289 template<
typename AR = all_random_access, std::enable_if_t<AR::value,
int> = 0>
296 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
297 sized_sentinel_for<iterator_t<maybe_const<Const, Views>>,
298 iterator_t<maybe_const<Const, Views>>>
302 return detail::min_tuple_distance_fn<difference_type>{}(i.current_, j.current_);
312 std::is_nothrow_move_constructible<
322 std::enable_if_t<IS::value, int> = 0>
331 x.iter_swap_impl(y, tuple_index_sequence{});
335 template<
typename Tuple>
337 : current_(
std::forward<Tuple>(tup)) {}
339 constexpr
bool equal(
const iterator& other)
const {
340 return equal_1(other, all_bidirectional{});
343 constexpr
bool equal_1(
const iterator& other, std::true_type )
const {
344 return current_ == other.current_;
347 constexpr
bool equal_1(
const iterator& other, std::false_type )
const {
348 return equal_2(other, in_place_index_t<0>{});
351 template<
typename OtherTuple, std::
size_t I, std::enable_if_t<I != kViewCount,
int> = 0>
352 constexpr
bool equal_2(
const OtherTuple& t, in_place_index_t<I>)
const {
353 return bool(std::get<I>(current_) == std::get<I>(t))
355 : equal_2(t, in_place_index_t<I + 1>{});
358 template<
typename OtherTuple>
359 constexpr
bool equal_2(
const OtherTuple&, in_place_index_t<kViewCount>)
const {
363 template<std::size_t... I>
364 constexpr
void iter_swap_impl(
const iterator& other, std::index_sequence<I...>)
const {
371 std::tuple<iterator_t<maybe_const<Const, Views>>...> current_{};
381 template<
bool AntiConst, std::enable_if_t<
conjunction<
386 : end_(
std::move(i.end_)) {}
388 template<
bool OtherConst, std::enable_if_t<
conjunction<
395 return y.is_equal(x);
398 template<
bool OtherConst, std::enable_if_t<
conjunction<
408 template<
bool OtherConst, std::enable_if_t<
conjunction<
418 template<
bool OtherConst, std::enable_if_t<
conjunction<
428 template<
bool OtherConst, std::enable_if_t<
conjunction<
437 return detail::min_tuple_distance_fn<R>{}(x.current_, y.end_);
440 template<
bool OtherConst, std::enable_if_t<
conjunction<
452 template<
typename Tuple>
454 : end_(
std::forward<Tuple>(tup)) {}
456 template<
bool OtherConst>
457 constexpr
bool is_equal(
const iterator<OtherConst>& i)
const {
461 std::tuple<sentinel_t<maybe_const<Const, Views>>...> end_{};
467 : views_(
std::move(views)...) {}
469 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
478 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
479 range<const Views>...
485 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
494 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
495 range<const Views>...
497 constexpr
auto end()
const {
501 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
502 sized_range<Views>...
507 using CT = std::make_unsigned_t<
common_type_t<decltype(sizes)...>>;
514 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
515 sized_range<const Views>...
520 using CT = std::make_unsigned_t<
common_type_t<decltype(sizes)...>>;
528 template<
bool Const,
typename Self,
typename Any>
529 static constexpr
auto end_impl(Self&&
self, std::false_type , Any) {
533 template<
bool Const,
typename Self>
534 static constexpr
auto end_impl(Self&&
self, std::true_type , std::true_type ) {
535 return self.begin() + iter_difference_t<iterator<Const>>(
self.size());
538 template<
bool Const,
typename Self>
539 static constexpr
auto end_impl(Self&&
self, std::true_type , std::false_type ) {
543 std::tuple<Views...> views_{};
546 #if __cplusplus >= 201703L
548 template<
typename... Rs>
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
Definition: zip_view.hpp:123
constexpr iterator & operator--()
Definition: zip_view.hpp:207
common_type_t< range_difference_t< maybe_const< Const, Views > >... > difference_type
Definition: zip_view.hpp:151
constexpr friend iterator operator+(const iterator &i, difference_type n)
Definition: zip_view.hpp:276
friend class iterator< true >
Definition: zip_view.hpp:128
constexpr friend iterator operator-(const iterator &i, difference_type n)
Definition: zip_view.hpp:290
void pointer
Definition: zip_view.hpp:154
constexpr void operator++(int)
Definition: zip_view.hpp:195
constexpr friend void iter_swap(const iterator &x, const iterator &y) noexcept(conjunction< bool_constant< noexcept(ranges::iter_swap(std::declval< const iterator_t< maybe_const< Const, Views >> & >(), std::declval< const iterator_t< maybe_const< Const, Views >> & >()))>... >::value)
Definition: zip_view.hpp:323
std::tuple< maybe_const< Const, Views >... > value_type
Definition: zip_view.hpp:150
constexpr friend auto iter_move(const iterator &i) noexcept(conjunction< bool_constant< noexcept(ranges::iter_move(std::declval< const iterator_t< maybe_const< Const, Views >> & >()))>..., std::is_nothrow_move_constructible< range_rvalue_reference_t< maybe_const< Const, Views >> >... >::value)
Definition: zip_view.hpp:305
constexpr iterator(iterator< AntiConst > i)
Definition: zip_view.hpp:167
constexpr friend bool operator<(const iterator &x, const iterator &y)
Definition: zip_view.hpp:253
constexpr friend bool operator==(const iterator &x, const iterator &y)
Definition: zip_view.hpp:241
decltype(vccc::tuple_transform(std::declval< std::tuple< iterator_t< maybe_const< Const, Views > >... > & >(), std::declval< tuple_deref_fn >())) reference
Definition: zip_view.hpp:158
constexpr friend bool operator!=(const iterator &x, const iterator &y)
Definition: zip_view.hpp:248
constexpr iterator & operator-=(difference_type n)
Definition: zip_view.hpp:229
constexpr iterator & operator+=(difference_type n)
Definition: zip_view.hpp:219
constexpr iterator operator--(int)
Definition: zip_view.hpp:212
constexpr friend bool operator>(const iterator &x, const iterator &y)
Definition: zip_view.hpp:264
constexpr friend bool operator<=(const iterator &x, const iterator &y)
Definition: zip_view.hpp:258
constexpr friend iterator operator+(difference_type n, const iterator &i)
Definition: zip_view.hpp:283
constexpr iterator operator++(int)
Definition: zip_view.hpp:200
constexpr friend bool operator>=(const iterator &x, const iterator &y)
Definition: zip_view.hpp:270
friend class zip_view
Definition: zip_view.hpp:131
constexpr friend difference_type operator-(const iterator &i, const iterator &j)
Definition: zip_view.hpp:301
std::conditional_t< all_random_access::value, random_access_iterator_tag, std::conditional_t< all_bidirectional::value, bidirectional_iterator_tag, std::conditional_t< all_forward::value, forward_iterator_tag, input_iterator_tag > >> iterator_concept
Definition: zip_view.hpp:149
constexpr iterator & operator++()
Definition: zip_view.hpp:189
Definition: zip_view.hpp:375
constexpr friend bool operator==(const sentinel &y, const iterator< OtherConst > &x)
Definition: zip_view.hpp:404
constexpr sentinel(sentinel< AntiConst > i)
Definition: zip_view.hpp:385
constexpr friend bool operator!=(const sentinel &y, const iterator< OtherConst > &x)
Definition: zip_view.hpp:424
constexpr friend bool operator==(const iterator< OtherConst > &x, const sentinel &y)
Definition: zip_view.hpp:394
constexpr friend bool operator!=(const iterator< OtherConst > &x, const sentinel &y)
Definition: zip_view.hpp:414
constexpr friend common_type_t< range_difference_t< maybe_const< OtherConst, Views > >... > operator-(const sentinel &y, const iterator< OtherConst > &x)
Definition: zip_view.hpp:447
constexpr friend common_type_t< range_difference_t< maybe_const< OtherConst, Views > >... > operator-(const iterator< OtherConst > &x, const sentinel &y)
Definition: zip_view.hpp:435
Definition: zip_view.hpp:109
constexpr zip_view(Views... views)
Definition: zip_view.hpp:466
constexpr auto size() const
Definition: zip_view.hpp:517
constexpr auto size()
Definition: zip_view.hpp:504
constexpr auto end()
Definition: zip_view.hpp:490
constexpr auto end() const
Definition: zip_view.hpp:497
constexpr auto begin() const
Definition: zip_view.hpp:481
constexpr auto begin()
Definition: zip_view.hpp:474
constexpr VCCC_INLINE_OR_STATIC detail::min_niebloid min
Definition: min.hpp:90
constexpr VCCC_INLINE_OR_STATIC detail_iter_move::iter_move_niebloid iter_move
Definition: iter_move.hpp:92
constexpr VCCC_INLINE_OR_STATIC detail_iter_swap::iter_swap_niebloid iter_swap
Definition: iter_swap.hpp:90
std::forward_iterator_tag forward_iterator_tag
Definition: iterator_tag.hpp:17
std::random_access_iterator_tag random_access_iterator_tag
Definition: iterator_tag.hpp:19
typename iter_difference< T >::type iter_difference_t
Computes the difference type of T
Definition: iter_difference_t.hpp:49
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
std::bidirectional_iterator_tag bidirectional_iterator_tag
Definition: iterator_tag.hpp:18
typename sentinel< R >::type sentinel_t
Definition: sentinel_t.hpp:29
typename ranges::iterator< T >::type iterator_t
Definition: iterator_t.hpp:32
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
typename range_rvalue_reference< R >::type range_rvalue_reference_t
Used to obtain the rvalue reference type of the iterator type of range type R.
Definition: range_rvalue_reference_t.hpp:38
constexpr VCCC_INLINE_OR_STATIC detail::size_niebloid size
returns the size of a container or array
Definition: size.hpp:145
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
constexpr decltype(auto) apply(F &&f, Tuple &&t)
calls a function with the elements of tuple of arguments
Definition: apply.hpp:89
constexpr std::enable_if_t< detail::tuple_for_each_invocable< Tuple, F >::value > tuple_for_each(Tuple &&t, F &&f)
Definition: tuple_for_each.hpp:76
constexpr auto tuple_transform(Tuple &&t, F &&f) noexcept(noexcept(detail::tuple_transform_impl(std::forward< Tuple >(t), std::forward< F >(f), std::make_index_sequence< std::tuple_size< remove_cvref_t< Tuple >>::value >{})))
Constructs a new tuple with each elements transformed.
Definition: tuple_transform.hpp:36
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
std::conditional_t< Const, const V, V > maybe_const
Definition: maybe_const.hpp:16
constexpr VCCC_INLINE_OR_STATIC in_place_t in_place
Definition: in_place.hpp:47
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: conjunction.hpp:22
Models std::convertible_to
Definition: convertible_to.hpp:38
Definition: in_place.hpp:35
in-place construction tag
Definition: in_place.hpp:25
Definition: indirectly_swappable.hpp:46
Definition: sentinel_t.hpp:18
specifies that a range is a view, that is, it has constant time copy/move/assignment
Definition: view.hpp:31
Definition: sentinel_for.hpp:24
specifies that the - operator can be applied to an iterator and a sentinel to calculate their differe...
Definition: sized_sentinel_for.hpp:75