|
642 | 642 | template<class I>
|
643 | 643 | struct in_found_result;
|
644 | 644 |
|
| 645 | + template<class I, class T> |
| 646 | + struct in_value_result; |
| 647 | + |
645 | 648 | template<class O, class T>
|
646 | 649 | struct out_value_result;
|
647 | 650 | }
|
|
1169 | 1172 | @\libconcept{indirectly_comparable}@<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
|
1170 | 1173 | constexpr bool ends_with(R1&& r1, R2&& r2, Pred pred = {},
|
1171 | 1174 | Proj1 proj1 = {}, Proj2 proj2 = {});
|
| 1175 | + |
| 1176 | + // \ref{alg.fold}, fold |
| 1177 | + template<class F> |
| 1178 | + class @\exposid{flipped}@ { // \expos |
| 1179 | + F @\exposid{f}@; // \expos |
| 1180 | + |
| 1181 | + public: |
| 1182 | + template<class T, class U> requires @\libconcept{invocable}@<F&, U, T> |
| 1183 | + invoke_result_t<F&, U, T> operator()(T&&, U&&); |
| 1184 | + }; |
| 1185 | + |
| 1186 | + template<class F, class T, class I, class U> |
| 1187 | + concept @\defexposconcept{indirectly-binary-left-foldable-impl}@ = // \expos |
| 1188 | + @\libconcept{movable}@<T> && @\libconcept{movable}@<U> && |
| 1189 | + @\libconcept{convertible_to}@<T, U> && @\libconcept{invocable}@<F&, U, iter_reference_t<I>> && |
| 1190 | + @\libconcept{assignable_from}@<U&, invoke_result_t<F&, U, iter_reference_t<I>>>; |
| 1191 | + |
| 1192 | + template<class F, class T, class I> |
| 1193 | + concept @\defexposconcept{indirectly-binary-left-foldable}@ = // \expos |
| 1194 | + @\libconcept{copy_constructible}@<F> && @\libconcept{indirectly_readable}@<I> && |
| 1195 | + @\libconcept{invocable}@<F&, T, iter_reference_t<I>> && |
| 1196 | + @\libconcept{convertible_to}@<invoke_result_t<F&, T, iter_reference_t<I>>, |
| 1197 | + decay_t<invoke_result_t<F&, T, iter_reference_t<I>>>> && |
| 1198 | + @\exposconcept{indirectly-binary-left-foldable-impl}@<F, T, I, |
| 1199 | + decay_t<invoke_result_t<F&, T, iter_reference_t<I>>>>; |
| 1200 | + |
| 1201 | + template<class F, class T, class I> |
| 1202 | + concept @\defexposconcept{indirectly-binary-right-foldable}@ = // \expos |
| 1203 | + @\exposconcept{indirectly-binary-left-foldable}@<@\exposid{flipped}@<F>, T, I>; |
| 1204 | + |
| 1205 | + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 1206 | + @\exposconcept{indirectly-binary-left-foldable}@<T, I> F> |
| 1207 | + constexpr auto fold_left(I first, S last, T init, F f); |
| 1208 | + |
| 1209 | + template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, iterator_t<R>> F> |
| 1210 | + constexpr auto fold_left(R&& r, T init, F f); |
| 1211 | + |
| 1212 | + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 1213 | + @\exposconcept{indirectly-binary-left-foldable}@<iter_value_t<I>, I> F> |
| 1214 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 1215 | + constexpr auto fold_left_first(I first, S last, F f); |
| 1216 | + |
| 1217 | + template <@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 1218 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 1219 | + constexpr auto fold_left_first(R&& r, F f); |
| 1220 | + |
| 1221 | + template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 1222 | + @\exposconcept{indirectly-binary-right-foldable}@<T, I> F> |
| 1223 | + constexpr auto fold_right(I first, S last, T init, F f); |
| 1224 | + |
| 1225 | + template<@\libconcept{bidirectional_range}@ R, class T, |
| 1226 | + @\exposconcept{indirectly-binary-right-foldable}@<T, iterator_t<R>> F> |
| 1227 | + constexpr auto fold_right(R&& r, T init, F f); |
| 1228 | + |
| 1229 | + template <@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 1230 | + indirectly-binary-right-foldable<iter_value_t<I>, I> F> |
| 1231 | + requires constructible_from<iter_value_t<I>, iter_reference_t<I>> |
| 1232 | + constexpr auto fold_right_last(I first, S last, F f); |
| 1233 | + |
| 1234 | + template <@\libconcept{bidirectional_range}@ R, |
| 1235 | + @\exposconcept{indirectly-binary-right-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 1236 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 1237 | + constexpr auto fold_right_last(R&& r, F f); |
| 1238 | + |
| 1239 | + template<class I, class T> |
| 1240 | + using fold_left_with_iter_result = in_value_result<I, T>; |
| 1241 | + template<class I, class T> |
| 1242 | + using fold_left_first_with_iter_result = in_value_result<I, T>; |
| 1243 | + |
| 1244 | + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 1245 | + @\exposconcept{indirectly-binary-left-foldable}@<T, I> F> |
| 1246 | + constexpr @\seebelow@ fold_left_with_iter(I first, S last, T init, F f); |
| 1247 | + |
| 1248 | + template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, iterator_t<R>> F> |
| 1249 | + constexpr @\seebelow@ fold_left_with_iter(R&& r, T init, F f); |
| 1250 | + |
| 1251 | + template <@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 1252 | + @\exposconcept{indirectly-binary-left-foldable}@<iter_value_t<I>, I> F> |
| 1253 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 1254 | + constexpr @\seebelow@ fold_left_first_with_iter(I first, S last, F f); |
| 1255 | + |
| 1256 | + template <@\libconcept{input_range}@ R, |
| 1257 | + @\exposconcept{indirectly-binary-left-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 1258 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 1259 | + constexpr @\seebelow@ fold_left_first_with_iter(R&& r, F f); |
1172 | 1260 | }
|
1173 | 1261 |
|
1174 | 1262 | // \ref{alg.modifying.operations}, mutating sequence operations
|
|
3058 | 3146 | }
|
3059 | 3147 | };
|
3060 | 3148 |
|
| 3149 | + template<class I, class T> |
| 3150 | + struct in_value_result { |
| 3151 | + [[no_unique_address]] I in; |
| 3152 | + [[no_unique_address]] T value; |
| 3153 | + |
| 3154 | + template<class I2, class T2> |
| 3155 | + requires @\libconcept{convertible_to}@<const I&, I2> && @\libconcept{convertible_to}@<const T&, T2> |
| 3156 | + constexpr operator in_value_result<I2, T2>() const & { |
| 3157 | + return {in, value}; |
| 3158 | + } |
| 3159 | + |
| 3160 | + template<class I2, class T2> |
| 3161 | + requires @\libconcept{convertible_to}@<I, I2> && @\libconcept{convertible_to}@<T, T2> |
| 3162 | + constexpr operator in_value_result<I2, T2>() && { |
| 3163 | + return {std::move(in), std::move(value)}; |
| 3164 | + } |
| 3165 | + }; |
| 3166 | + |
3061 | 3167 | template<class O, class T>
|
3062 | 3168 | struct out_value_result {
|
3063 | 3169 | [[no_unique_address]] O out;
|
|
4384 | 4490 | \end{codeblock}
|
4385 | 4491 | \end{itemdescr}
|
4386 | 4492 |
|
| 4493 | +\rSec2[alg.fold]{Fold} |
| 4494 | + |
| 4495 | +\indexlibraryglobal{fold_left}% |
| 4496 | +\begin{itemdecl} |
| 4497 | +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, I> F> |
| 4498 | + constexpr auto ranges::fold_left(I first, S last, T init, F f); |
| 4499 | +template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, iterator_t<R>> F> |
| 4500 | + constexpr auto ranges::fold_left(R&& r, T init, F f); |
| 4501 | +\end{itemdecl} |
| 4502 | + |
| 4503 | +\begin{itemdescr} |
| 4504 | +\pnum |
| 4505 | +\returns |
| 4506 | +\begin{codeblock} |
| 4507 | +ranges::fold_left_with_iter(std::move(first), last, std::move(init), f).value |
| 4508 | +\end{codeblock} |
| 4509 | +\end{itemdescr} |
| 4510 | + |
| 4511 | +\indexlibraryglobal{fold_left_first}% |
| 4512 | +\begin{itemdecl} |
| 4513 | +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 4514 | + @\exposconcept{indirectly-binary-left-foldable}@<iter_value_t<I>, I> F> |
| 4515 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 4516 | + constexpr auto ranges::fold_left_first(I first, S last, F f); |
| 4517 | +template <@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 4518 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 4519 | + constexpr auto ranges::fold_left_first(R&& r, F f); |
| 4520 | +\end{itemdecl} |
| 4521 | + |
| 4522 | +\begin{itemdescr} |
| 4523 | +\pnum |
| 4524 | +\returns |
| 4525 | +\begin{codeblock} |
| 4526 | +ranges::fold_left_first_with_iter(std::move(first), last, f).value |
| 4527 | +\end{codeblock} |
| 4528 | +\end{itemdescr} |
| 4529 | + |
| 4530 | +\indexlibraryglobal{fold_right}% |
| 4531 | +\begin{itemdecl} |
| 4532 | +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 4533 | + @\exposconcept{indirectly-binary-right-foldable}@<T, I> F> |
| 4534 | + constexpr auto ranges::fold_right(I first, S last, T init, F f); |
| 4535 | +template<@\libconcept{bidirectional_range}@ R, class T, |
| 4536 | + @\exposconcept{indirectly-binary-right-foldable}@<T, iterator_t<R>> F> |
| 4537 | + constexpr auto ranges::fold_right(R&& r, T init, F f); |
| 4538 | +\end{itemdecl} |
| 4539 | + |
| 4540 | +\begin{itemdescr} |
| 4541 | +\pnum |
| 4542 | +\effects |
| 4543 | +Equivalent to: |
| 4544 | +\begin{codeblock} |
| 4545 | +using U = decay_t<invoke_result_t<F&, iter_reference_t<I>, T>>; |
| 4546 | +if (first == last) |
| 4547 | + return U(std::move(init)); |
| 4548 | +I tail = ranges::next(first, last); |
| 4549 | +U accum = invoke(f, *--tail, std::move(init)); |
| 4550 | +while (first != tail) |
| 4551 | + accum = invoke(f, *--tail, std::move(accum)); |
| 4552 | +return accum; |
| 4553 | +\end{codeblock} |
| 4554 | +\end{itemdescr} |
| 4555 | + |
| 4556 | +\indexlibraryglobal{fold_right_last}% |
| 4557 | +\begin{itemdecl} |
| 4558 | +template <@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 4559 | + @\exposconcept{indirectly-binary-right-foldable}@<iter_value_t<I>, I> F> |
| 4560 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 4561 | + constexpr auto ranges::fold_right_last(I first, S last, F f); |
| 4562 | +template <@\libconcept{bidirectional_range}@ R, |
| 4563 | + @\exposconcept{indirectly-binary-right-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 4564 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 4565 | + constexpr auto ranges::fold_right_last(R&& r, F f); |
| 4566 | +\end{itemdecl} |
| 4567 | + |
| 4568 | +\begin{itemdescr} |
| 4569 | +\pnum |
| 4570 | +Let \tcode{U} be |
| 4571 | +\tcode{decltype(ranges::fold_right(first, last, iter_value_t<I>(*first), f))}. |
| 4572 | + |
| 4573 | +\pnum |
| 4574 | +\effects |
| 4575 | +Equivalent to: |
| 4576 | +\begin{codeblock} |
| 4577 | +if (first == last) |
| 4578 | + return optional<U>(); |
| 4579 | +I tail = ranges::prev(ranges::next(first, std::move(last))); |
| 4580 | +return optional<U>(in_place, |
| 4581 | + ranges::fold_right(std::move(first), tail, iter_value_t<I>(*tail), std::move(f))); |
| 4582 | +\end{codeblock} |
| 4583 | +\end{itemdescr} |
| 4584 | + |
| 4585 | +\indexlibraryglobal{fold_left_with_iter}% |
| 4586 | +\begin{itemdecl} |
| 4587 | +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 4588 | + @\exposconcept{indirectly-binary-left-foldable}@<T, I> F> |
| 4589 | + constexpr @\seebelow@ fold_left_with_iter(I first, S last, T init, F f); |
| 4590 | +template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, iterator_t<R>> F> |
| 4591 | + constexpr @\seebelow@ fold_left_with_iter(R&& r, T init, F f); |
| 4592 | +\end{itemdecl} |
| 4593 | + |
| 4594 | +\begin{itemdescr} |
| 4595 | +\pnum |
| 4596 | +Let \tcode{U} be \tcode{decay_t<invoke_result_t<F\&, T, iter_reference_t<I>>>}. |
| 4597 | + |
| 4598 | +\pnum |
| 4599 | +\effects |
| 4600 | +Equivalent to: |
| 4601 | +\begin{codeblock} |
| 4602 | +if (first == last) |
| 4603 | + return {std::move(first), U(std::move(init))}; |
| 4604 | +U accum = invoke(f, std::move(init), *first); |
| 4605 | +for (++first; first != last; ++first) |
| 4606 | + accum = invoke(f, std::move(accum), *first); |
| 4607 | +return {std::move(first), std::move(accum)}; |
| 4608 | +\end{codeblock} |
| 4609 | + |
| 4610 | +\pnum |
| 4611 | +\remarks |
| 4612 | +The return type is |
| 4613 | +\tcode{fold_left_with_iter_result<I, U>} for the first overload and |
| 4614 | +\tcode{fold_left_with_iter_result<borrowed_iterator_t<R>, U>} |
| 4615 | +for the second overload. |
| 4616 | +\end{itemdescr} |
| 4617 | + |
| 4618 | +\indexlibraryglobal{fold_left_first_with_iter}% |
| 4619 | +\begin{itemdecl} |
| 4620 | +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 4621 | + @\exposconcept{indirectly-binary-left-foldable}@<iter_value_t<I>, I> F> |
| 4622 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 4623 | + constexpr @\seebelow@ fold_left_first_with_iter(I first, S last, F f) |
| 4624 | +template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 4625 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 4626 | + constexpr @\seebelow@ fold_left_first_with_iter(R&& r, F f); |
| 4627 | +\end{itemdecl} |
| 4628 | + |
| 4629 | +\begin{itemdescr} |
| 4630 | +\pnum |
| 4631 | +Let \tcode{U} be |
| 4632 | +\begin{codeblock} |
| 4633 | +decltype(ranges::fold_left(std::move(first), last, iter_value_t<I>(*first), f)) |
| 4634 | +\end{codeblock} |
| 4635 | + |
| 4636 | +\pnum |
| 4637 | +\effects |
| 4638 | +Equivalent to: |
| 4639 | +\begin{codeblock} |
| 4640 | +if (first == last) |
| 4641 | + return {std::move(first), optional<U>()}; |
| 4642 | +optional<U> init(in_place, *first); |
| 4643 | +for (++first; first != last; ++first) |
| 4644 | + *init = invoke(f, std::move(*init), *first); |
| 4645 | +return {std::move(first), std::move(init)}; |
| 4646 | +\end{codeblock} |
| 4647 | + |
| 4648 | +\pnum |
| 4649 | +\remarks |
| 4650 | +The return type is |
| 4651 | +\tcode{fold_left_first_with_iter_result<I, optional<U>>} |
| 4652 | +for the first overload and |
| 4653 | +\tcode{fold_left_first_with_iter_result<borrowed_iterator_t<R>, optional<U>>} |
| 4654 | +for the second overload. |
| 4655 | +\end{itemdescr} |
| 4656 | + |
4387 | 4657 | \rSec1[alg.modifying.operations]{Mutating sequence operations}
|
4388 | 4658 |
|
4389 | 4659 | \rSec2[alg.copy]{Copy}
|
|
0 commit comments