14#ifndef RANGES_V3_VIEW_TRANSFORM_HPP
15#define RANGES_V3_VIEW_TRANSFORM_HPP
36#include <range/v3/utility/static_const.hpp>
41#include <range/v3/detail/prologue.hpp>
48 constexpr cardinality transform2_cardinality(cardinality c1, cardinality c2)
50 return c1 >= 0 || c2 >= 0
51 ? (c1 >= 0 && c2 >= 0 ? (c1 < c2 ? c1 : c2) : finite)
52 : c1 == finite || c2 == finite
54 : c1 == unknown || c2 == unknown ? unknown : infinite;
60 template(
typename Fun,
typename Rng)(
61 concept (iter_transform_1_readable_)(Fun, Rng),
62 regular_invocable<Fun &, iterator_t<Rng>> AND
63 regular_invocable<Fun &, copy_tag, iterator_t<Rng>> AND
64 regular_invocable<Fun &, move_tag, iterator_t<Rng>> AND
65 common_reference_with<
66 invoke_result_t<Fun &, iterator_t<Rng>> &&,
67 invoke_result_t<Fun &, copy_tag, iterator_t<Rng>> &> AND
68 common_reference_with<
69 invoke_result_t<Fun &, iterator_t<Rng>> &&,
70 invoke_result_t<Fun &, move_tag, iterator_t<Rng>> &&> AND
71 common_reference_with<
72 invoke_result_t<Fun &, move_tag, iterator_t<Rng>> &&,
73 invoke_result_t<Fun &, copy_tag, iterator_t<Rng>>
const &>
77 template<
typename Fun,
typename Rng>
78 CPP_concept iter_transform_1_readable =
79 CPP_concept_ref(detail::iter_transform_1_readable_, Fun, Rng);
83 template(
typename Fun,
typename Rng1,
typename Rng2)(
84 concept (iter_transform_2_readable_)(Fun, Rng1, Rng2),
85 regular_invocable<Fun &, iterator_t<Rng1>, iterator_t<Rng2>> AND
86 regular_invocable<Fun &, copy_tag, iterator_t<Rng1>, iterator_t<Rng2>> AND
87 regular_invocable<Fun &, move_tag, iterator_t<Rng1>, iterator_t<Rng2>> AND
88 common_reference_with<
89 invoke_result_t<Fun &, iterator_t<Rng1>, iterator_t<Rng2>> &&,
90 invoke_result_t<Fun &, copy_tag, iterator_t<Rng1>, iterator_t<Rng2>> &> AND
91 common_reference_with<
92 invoke_result_t<Fun &, iterator_t<Rng1>, iterator_t<Rng2>> &&,
93 invoke_result_t<Fun &, move_tag, iterator_t<Rng1>, iterator_t<Rng2>> &&> AND
94 common_reference_with<
95 invoke_result_t<Fun &, move_tag, iterator_t<Rng1>, iterator_t<Rng2>> &&,
96 invoke_result_t<Fun &, copy_tag, iterator_t<Rng1>, iterator_t<Rng2>>
const &>
100 template<
typename Fun,
typename Rng1,
typename Rng2>
101 CPP_concept iter_transform_2_readable =
102 CPP_concept_ref(detail::iter_transform_2_readable_, Fun, Rng1, Rng2);
109 template<
typename Rng,
typename Fun>
114 RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Fun> fun_;
116 using use_sentinel_t =
118 single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rng>>>>;
120 template<
bool IsConst>
124 friend struct adaptor<!IsConst>;
125 using CRng = meta::const_if_c<IsConst, Rng>;
126 using fun_ref_ = semiregular_box_ref_or_val_t<Fun, IsConst>;
127 RANGES_NO_UNIQUE_ADDRESS fun_ref_ fun_;
131 detail::decay_t<invoke_result_t<Fun &, copy_tag, iterator_t<CRng>>>;
133 adaptor(fun_ref_ fun)
134 : fun_(std::move(fun))
136 template(
bool Other)(
137 requires IsConst AND CPP_NOT(Other))
138 adaptor(adaptor<Other> that)
139 : fun_(std::move(that.fun_))
145 return invoke(fun_, it)
154 adaptor<false> begin_adaptor()
158 template(
bool Const =
true)(
159 requires Const AND
range<meta::const_if_c<Const, Rng>> AND
160 detail::iter_transform_1_readable<Fun
const,
161 meta::const_if_c<Const, Rng>>)
162 adaptor<Const> begin_adaptor()
const
170 template(
bool Const =
true)(
171 requires Const AND
range<meta::const_if_c<Const, Rng>> AND
172 detail::iter_transform_1_readable<Fun
const,
173 meta::const_if_c<Const, Rng>>)
182 : iter_transform_view::view_adaptor{std::move(rng)}
183 , fun_(std::move(fun))
186 constexpr auto CPP_fun(size)()(
189 return ranges::size(this->base());
192 constexpr auto CPP_fun(size)()(
const
195 return ranges::size(this->base());
199 template<
typename Rng,
typename Fun>
205 indirect(std::move(fun))}
209#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
210 template(
typename Rng,
typename Fun)(
211 requires copy_constructible<Fun>)
216 template<
typename Rng1,
typename Rng2,
typename Fun>
218 :
view_facade<iter_transform2_view<Rng1, Rng2, Fun>,
219 detail::transform2_cardinality(range_cardinality<Rng1>::value,
220 range_cardinality<Rng2>::value)>
224 RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Fun> fun_;
227 using difference_type_ =
228 common_type_t<range_difference_t<Rng1>, range_difference_t<Rng2>>;
230 static constexpr cardinality my_cardinality = detail::transform2_cardinality(
240 friend struct cursor<Const>;
241 sentinel_t<meta::const_if_c<Const, Rng1>> end1_;
242 sentinel_t<meta::const_if_c<Const, Rng2>> end2_;
245 sentinel() =
default;
246 sentinel(meta::const_if_c<Const, iter_transform2_view> * parent,
247 decltype(ranges::end))
248 : end1_(end(parent->rng1_))
249 , end2_(end(parent->rng2_))
251 template(
bool Other)(
252 requires Const AND CPP_NOT(Other))
253 sentinel(sentinel<Other> that)
254 : end1_(std::move(that.end1_))
255 , end2_(std::move(that.end2_))
263 using fun_ref_ = semiregular_box_ref_or_val_t<Fun, Const>;
264 using R1 = meta::const_if_c<Const, Rng1>;
265 using R2 = meta::const_if_c<Const, Rng2>;
271 using difference_type = difference_type_;
273 (
bool)single_pass_iterator_<iterator_t<R2>>>;
275 detail::decay_t<invoke_result_t<meta::const_if_c<Const, Fun> &,
copy_tag,
279 template<
typename BeginEndFn>
280 cursor(meta::const_if_c<Const, iter_transform2_view> * parent,
281 BeginEndFn begin_end)
283 , it1_(begin_end(parent->rng1_))
284 , it2_(begin_end(parent->rng2_))
286 template(
bool Other)(
287 requires Const AND CPP_NOT(Other))
288 cursor(cursor<Other> that)
289 : fun_(std::move(that.fun_))
290 , it1_(std::move(that.end1_))
291 , it2_(std::move(that.end2_))
294 auto CPP_auto_fun(read)()(
const)
296 return invoke(fun_, it1_, it2_)
305 auto equal(cursor
const & that)
const
312 return it1_ == that.it1_ || it2_ == that.it2_;
314 bool equal(sentinel<Const>
const & s)
const
319 return it1_ == s.end1_ || it2_ == s.end2_;
330 auto advance(difference_type n) -> CPP_ret(
void)(
333 ranges::advance(it1_, n);
334 ranges::advance(it2_, n);
337 auto distance_to(cursor
const & that)
const
338 -> CPP_ret(difference_type)(
344 difference_type d1 = that.it1_ - it1_, d2 = that.it2_ - it2_;
345 return 0 < d1 ? ranges::min(d1, d2) : ranges::max(d1, d2);
348 auto CPP_auto_fun(move)()(
const)
350 return invoke(fun_,
move_tag{}, it1_, it2_)
356 using end_cursor_t = meta::if_c<
359 !single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rng1>>> &&
360 !single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rng2>>>,
361 cursor<Const>, sentinel<Const>>;
363 cursor<simple_view<Rng1>() && simple_view<Rng2>()> begin_cursor()
365 return {
this, ranges::begin};
367 end_cursor_t<simple_view<Rng1>() && simple_view<Rng2>()> end_cursor()
369 return {
this, ranges::end};
371 template(
bool Const =
true)(
372 requires Const AND
range<meta::const_if_c<Const, Rng1>> AND
373 range<meta::const_if_c<Const, Rng2>> AND
374 detail::iter_transform_2_readable<
376 meta::const_if_c<Const, Rng1>,
377 meta::const_if_c<Const, Rng2>>)
378 cursor<true> begin_cursor()
const
380 return {
this, ranges::begin};
382 template(
bool Const =
true)(
383 requires Const AND
range<meta::const_if_c<Const, Rng1>> AND
384 range<meta::const_if_c<Const, Rng2>> AND
385 detail::iter_transform_2_readable<
387 meta::const_if_c<Const, Rng1>,
388 meta::const_if_c<Const, Rng2>>)
389 end_cursor_t<Const> end_cursor()
const
391 return {
this, ranges::end};
393 template<
typename Self>
394 static constexpr auto size_(Self & self)
396 using size_type = common_type_t<range_size_t<Rng1>, range_size_t<Rng2>>;
397 return ranges::min(
static_cast<size_type
>(ranges::size(self.rng1_)),
398 static_cast<size_type
>(ranges::size(self.rng2_)));
409 : fun_(std::move(fun))
410 , rng1_(std::move(rng1))
411 , rng2_(std::move(rng2))
414 static constexpr auto size()
415 -> CPP_ret(std::size_t)(
416 requires (my_cardinality >= 0))
418 return static_cast<std::size_t
>(my_cardinality);
420 template(
bool True =
true)(
423 common_with<range_size_t<R1<True>>, range_size_t<R2<True>>>)
424 constexpr auto size()
const
428 template(
bool True =
true)(
430 common_with<range_size_t<R1<True>>, range_size_t<R2<True>>>)
431 constexpr auto size()
437 template<
typename Rng1,
typename Rng2,
typename Fun>
444 indirect(std::move(fun))}
452 template(
typename Rng,
typename Fun)(
454 copy_constructible<Fun> AND
455 detail::iter_transform_1_readable<Fun, Rng>)
457 operator()(Rng && rng, Fun fun)
const
459 return {all(
static_cast<Rng &&
>(rng)), std::move(fun)};
462 template(
typename Rng1,
typename Rng2,
typename Fun)(
465 copy_constructible<Fun> AND
466 common_with<range_difference_t<Rng1>, range_difference_t<Rng1>> AND
467 detail::iter_transform_2_readable<Fun, Rng1, Rng2>)
469 operator()(Rng1 && rng1, Rng2 && rng2, Fun fun)
const
471 return {all(
static_cast<Rng1 &&
>(rng1)),
472 all(
static_cast<Rng2 &&
>(rng2)),
479 using iter_transform_base_fn::operator();
481 template<
typename Fun>
482 constexpr auto operator()(Fun fun)
const
484 return make_view_closure(
498 template(
typename Rng,
typename Fun)(
505 template<
typename Rng,
typename Fun>
508 copy_constructible<Fun> &&
513 template(
typename Rng1,
typename Rng2,
typename Fun)(
521 template<
typename Rng1,
typename Rng2,
typename Fun>
525 copy_constructible<Fun> &&
531 template(
typename Rng,
typename Fun)(
536 return {all(
static_cast<Rng &&
>(rng)), std::move(fun)};
539 template(
typename Rng1,
typename Rng2,
typename Fun)(
542 operator()(Rng1 && rng1, Rng2 && rng2, Fun fun)
const
544 return {all(
static_cast<Rng1 &&
>(rng1)),
545 all(
static_cast<Rng2 &&
>(rng2)),
583 using transform_base_fn::operator();
585 template<
typename Fun>
586 constexpr auto operator()(Fun fun)
const
601 using ranges::views::transform;
603 template(
typename Rng,
typename F)(
604 requires input_range<Rng> AND copy_constructible<F> AND view_<Rng> AND
605 std::is_object<F>::value AND
606 regular_invocable<F &, iter_reference_t<iterator_t<Rng>>>)
612#include <range/v3/detail/epilogue.hpp>
614#include <range/v3/detail/satisfy_boost_range.hpp>
The bidirectional_range concept.
The common_range concept.
The forward_range concept.
The random_access_range concept.
The regular_invocable concept.
The sized_sentinel_for concept.
The viewable_range concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition meta.hpp:541
_t< detail::_if_< list< Args... > > > if_
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1247
Definition adaptor.hpp:110
Definition range_fwd.hpp:492
Definition range_fwd.hpp:494
Definition traits.hpp:128
Definition adaptor.hpp:475
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition facade.hpp:66