5 #ifndef VCCC_RANGES_VIEWS_ZIP_TRANSFORM_VIEW_HPP_
6 #define VCCC_RANGES_VIEWS_ZIP_TRANSFORM_VIEW_HPP_
48 struct zip_transform_view_iterator_category {
49 #if __cplusplus < 202002L
50 using iterator_category = iterator_ignore;
54 template<
bool Const,
typename Base,
typename F,
typename... Views>
55 struct zip_transform_view_iterator_category<Const, Base, F, type_sequence<Views...>, true> {
57 using MF = maybe_const<Const, F>;
58 template<
typename View>
59 using IC =
typename cxx20_iterator_traits<iterator_t< maybe_const<Const, View> >>::iterator_category;
61 template<
typename BaseC>
62 using POT_derived_from = conjunction<derived_from<Views, BaseC>...>;
65 using iterator_category =
67 negation<is_referencable< invoke_result_t<MF&, range_reference_t<maybe_const<Const, Views>>...> >>
::value,
input_iterator_tag,
83 template<
typename F,
typename... Views>
89 static_assert(
sizeof...(Views) > 0,
"Constraints not satisfied");
108 :
public detail::zip_transform_view_iterator_category<
112 type_sequence<Views...>>
125 template<
typename Tuple, std::size_t... I>
126 decltype(
auto) operator()(const F& f, const Tuple& t,
std::index_sequence<I...>)
134 template<
typename Tuple>
135 decltype(
auto) operator()(const F& f, const Tuple& t)
151 #if __cplusplus < 202002L
158 template<
bool AntiConst, std::enable_if_t<
conjunction<
163 : parent_(
std::move(i.parent_)), inner_(
std::move(i.inner_)) {}
165 constexpr decltype(
auto) operator*() const
166 noexcept(noexcept(
vccc::
invoke(deref_fn{}, *parent_->fun_, *inner_)))
168 return deref_fn{}(*parent_->fun_, *inner_);
174 [&](
const auto&... iters) -> decltype(
auto) {
222 template<
typename Z = ziperator<Const>, std::enable_if_t<equality_comparable<Z>::value,
int> = 0>
224 return x.inner_ == y.inner_;
227 template<
typename Z = ziperator<Const>, std::enable_if_t<equality_comparable<Z>::value,
int> = 0>
229 return !(x.inner_ == y.inner_);
232 template<
typename Z = ziperator<Const>, std::enable_if_t<conjunction<
233 random_access_range<Z>,
234 unstable_three_way_comparable<Z>
237 return x.inner_ < y.inner_;
240 template<
typename Z = ziperator<Const>, std::enable_if_t<conjunction<
241 random_access_range<Z>,
242 unstable_three_way_comparable<Z>
249 template<
typename Z = ziperator<Const>, std::enable_if_t<conjunction<
250 random_access_range<Z>,
251 unstable_three_way_comparable<Z>
258 template<
typename Z = ziperator<Const>, std::enable_if_t<conjunction<
259 random_access_range<Z>,
260 unstable_three_way_comparable<Z>
269 return iterator(*i.parent_, i.inner_ + n);
274 return iterator(*i.parent_, i.inner_ + n);
279 return iterator(*i.parent_, i.inner_ - n);
282 template<
typename Z = ziperator<Const>, std::enable_if_t<sized_sentinel_for<Z, Z>::value,
int> = 0>
284 return i.inner_ - j.inner_;
292 ziperator<Const> inner_{};
303 template<
bool AntiConst, std::enable_if_t<
conjunction<
308 : inner_(
std::move(i.inner_)) {}
310 template<
bool OtherConst, std::enable_if_t<sentinel_for<zentinel<Const>, ziperator<OtherConst>>::value,
int> = 0>
312 return y.equal_to(x);
315 template<
bool OtherConst, std::enable_if_t<sentinel_for<zentinel<Const>, ziperator<OtherConst>>::value,
int> = 0>
320 template<
bool OtherConst, std::enable_if_t<sentinel_for<zentinel<Const>, ziperator<OtherConst>>::value,
int> = 0>
325 template<
bool OtherConst, std::enable_if_t<sentinel_for<zentinel<Const>, ziperator<OtherConst>>::value,
int> = 0>
330 template<
bool OtherConst, std::enable_if_t<sized_sentinel_for<zentinel<Const>, ziperator<OtherConst>>::value,
int> = 0>
333 return x.inner_ - y.inner_;
336 template<
bool OtherConst, std::enable_if_t<sized_sentinel_for<zentinel<Const>, ziperator<OtherConst>>::value,
int> = 0>
339 return y.inner_ - x.inner_;
343 constexpr
explicit sentinel(zentinel<Const> inner)
344 : inner_(
std::move(inner)) {}
346 template<
bool OtherConst>
347 constexpr
bool equal_to(
const iterator<OtherConst>& x)
const {
348 return x.inner_ == inner_;
351 zentinel<Const> inner_{};
357 : fun_(
std::move(fun)), zip_(
std::move(views)...) {}
363 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
364 range<const zip_view<Views...>>
374 constexpr
auto end()
const {
378 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
379 sized_range<InnerView>
385 template<
typename Dummy =
void, std::enable_if_t<conjunction<std::is_
void<Dummy>,
386 sized_range<const InnerView>
393 template<
bool Const,
typename Self>
394 static constexpr iterator<Const> end_impl(Self&&
self, std::true_type ) {
395 return iterator<Const>(
self,
self.zip_.end());
398 template<
bool Const,
typename Self>
399 static constexpr sentinel<Const> end_impl(Self&&
self, std::false_type ) {
400 return sentinel<Const>(
self.zip_.end());
403 movable_box<F> fun_{};
407 #if __cplusplus >= 201703L
409 template<
typename F,
typename... Rs>
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
#define VCCC_CONSTEXPR_AFTER_CXX17
Definition: constexpr.hpp:20
constexpr invoke_result_t< F, Args... > invoke(F &&f, Args &&... args) noexcept(is_nothrow_invocable< F, Args... >::value)
Definition: invoke.hpp:38
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
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
constexpr auto get(const subrange< I, S, K > &r)
Definition: subrange.hpp:371
typename sentinel< R >::type sentinel_t
Definition: sentinel_t.hpp:29
typename ranges::iterator< T >::type iterator_t
Definition: iterator_t.hpp:32
typename range_difference< R >::type range_difference_t
Used to obtain the difference type of the iterator type of range type R.
Definition: range_difference_t.hpp:41
typename range_reference< R >::type range_reference_t
Used to obtain the reference type of the iterator type of range type R.
Definition: range_reference_t.hpp:42
constexpr decltype(auto) apply(F &&f, Tuple &&t)
calls a function with the elements of tuple of arguments
Definition: apply.hpp:89
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
typename invoke_result< F, Args... >::type invoke_result_t
Definition: is_invocable.hpp:66
std::conditional_t< Const, const V, V > maybe_const
Definition: maybe_const.hpp:16
Definition: matrix.hpp:495
Definition: cxx20_rel_ops.hpp:17
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: is_referenceable.hpp:18
Definition: common_range.hpp:41
Definition: equal_to.hpp:20
specifies that a range is a view, that is, it has constant time copy/move/assignment
Definition: view.hpp:31
specifies that a callable type can be invoked with a given set of argument types
Definition: invocable.hpp:64