|
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 | }
|
|
1215 | 1218 | @\libconcept{indirectly_comparable}@<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
|
1216 | 1219 | constexpr bool ends_with(R1&& r1, R2&& r2, Pred pred = {},
|
1217 | 1220 | Proj1 proj1 = {}, Proj2 proj2 = {});
|
| 1221 | + |
| 1222 | + // \ref{alg.fold}, fold |
| 1223 | + template<class F> |
| 1224 | + class @\exposid{flipped}@ { // \expos |
| 1225 | + F @\exposid{f}@; // \expos |
| 1226 | + |
| 1227 | + public: |
| 1228 | + template<class T, class U> requires @\libconcept{invocable}@<F&, U, T> |
| 1229 | + invoke_result_t<F&, U, T> operator()(T&&, U&&); |
| 1230 | + }; |
| 1231 | + |
| 1232 | + template<class F, class T, class I, class U> |
| 1233 | + concept @\defexposconcept{indirectly-binary-left-foldable-impl}@ = // \expos |
| 1234 | + @\libconcept{movable}@<T> && @\libconcept{movable}@<U> && |
| 1235 | + @\libconcept{convertible_to}@<T, U> && @\libconcept{invocable}@<F&, U, iter_reference_t<I>> && |
| 1236 | + @\libconcept{assignable_from}@<U&, invoke_result_t<F&, U, iter_reference_t<I>>>; |
| 1237 | + |
| 1238 | + template<class F, class T, class I> |
| 1239 | + concept @\defexposconcept{indirectly-binary-left-foldable}@ = // \expos |
| 1240 | + @\libconcept{copy_constructible}@<F> && @\libconcept{indirectly_readable}@<I> && |
| 1241 | + @\libconcept{invocable}@<F&, T, iter_reference_t<I>> && |
| 1242 | + @\libconcept{convertible_to}@<invoke_result_t<F&, T, iter_reference_t<I>>, |
| 1243 | + decay_t<invoke_result_t<F&, T, iter_reference_t<I>>>> && |
| 1244 | + @\exposconcept{indirectly-binary-left-foldable-impl}@<F, T, I, |
| 1245 | + decay_t<invoke_result_t<F&, T, iter_reference_t<I>>>>; |
| 1246 | + |
| 1247 | + template<class F, class T, class I> |
| 1248 | + concept @\defexposconcept{indirectly-binary-right-foldable}@ = // \expos |
| 1249 | + @\exposconcept{indirectly-binary-left-foldable}@<@\exposid{flipped}@<F>, T, I>; |
| 1250 | + |
| 1251 | + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 1252 | + @\exposconcept{indirectly-binary-left-foldable}@<T, I> F> |
| 1253 | + constexpr auto fold_left(I first, S last, T init, F f); |
| 1254 | + |
| 1255 | + template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, iterator_t<R>> F> |
| 1256 | + constexpr auto fold_left(R&& r, T init, F f); |
| 1257 | + |
| 1258 | + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 1259 | + @\exposconcept{indirectly-binary-left-foldable}@<iter_value_t<I>, I> F> |
| 1260 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 1261 | + constexpr auto fold_left_first(I first, S last, F f); |
| 1262 | + |
| 1263 | + template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 1264 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 1265 | + constexpr auto fold_left_first(R&& r, F f); |
| 1266 | + |
| 1267 | + template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 1268 | + @\exposconcept{indirectly-binary-right-foldable}@<T, I> F> |
| 1269 | + constexpr auto fold_right(I first, S last, T init, F f); |
| 1270 | + |
| 1271 | + template<@\libconcept{bidirectional_range}@ R, class T, |
| 1272 | + @\exposconcept{indirectly-binary-right-foldable}@<T, iterator_t<R>> F> |
| 1273 | + constexpr auto fold_right(R&& r, T init, F f); |
| 1274 | + |
| 1275 | + template <@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 1276 | + @\exposconcept{indirectly-binary-right-foldable}@<iter_value_t<I>, I> F> |
| 1277 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 1278 | + constexpr auto fold_right_last(I first, S last, F f); |
| 1279 | + |
| 1280 | + template<@\libconcept{bidirectional_range}@ R, |
| 1281 | + @\exposconcept{indirectly-binary-right-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 1282 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 1283 | + constexpr auto fold_right_last(R&& r, F f); |
| 1284 | + |
| 1285 | + template<class I, class T> |
| 1286 | + using fold_left_with_iter_result = in_value_result<I, T>; |
| 1287 | + template<class I, class T> |
| 1288 | + using fold_left_first_with_iter_result = in_value_result<I, T>; |
| 1289 | + |
| 1290 | + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 1291 | + @\exposconcept{indirectly-binary-left-foldable}@<T, I> F> |
| 1292 | + constexpr @\seebelow@ fold_left_with_iter(I first, S last, T init, F f); |
| 1293 | + |
| 1294 | + template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, iterator_t<R>> F> |
| 1295 | + constexpr @\seebelow@ fold_left_with_iter(R&& r, T init, F f); |
| 1296 | + |
| 1297 | + template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 1298 | + @\exposconcept{indirectly-binary-left-foldable}@<iter_value_t<I>, I> F> |
| 1299 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 1300 | + constexpr @\seebelow@ fold_left_first_with_iter(I first, S last, F f); |
| 1301 | + |
| 1302 | + template<@\libconcept{input_range}@ R, |
| 1303 | + @\exposconcept{indirectly-binary-left-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 1304 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 1305 | + constexpr @\seebelow@ fold_left_first_with_iter(R&& r, F f); |
1218 | 1306 | }
|
1219 | 1307 |
|
1220 | 1308 | // \ref{alg.modifying.operations}, mutating sequence operations
|
|
3104 | 3192 | }
|
3105 | 3193 | };
|
3106 | 3194 |
|
| 3195 | + template<class I, class T> |
| 3196 | + struct in_value_result { |
| 3197 | + [[no_unique_address]] I in; |
| 3198 | + [[no_unique_address]] T value; |
| 3199 | + |
| 3200 | + template<class I2, class T2> |
| 3201 | + requires @\libconcept{convertible_to}@<const I&, I2> && @\libconcept{convertible_to}@<const T&, T2> |
| 3202 | + constexpr operator in_value_result<I2, T2>() const & { |
| 3203 | + return {in, value}; |
| 3204 | + } |
| 3205 | + |
| 3206 | + template<class I2, class T2> |
| 3207 | + requires @\libconcept{convertible_to}@<I, I2> && @\libconcept{convertible_to}@<T, T2> |
| 3208 | + constexpr operator in_value_result<I2, T2>() && { |
| 3209 | + return {std::move(in), std::move(value)}; |
| 3210 | + } |
| 3211 | + }; |
| 3212 | + |
3107 | 3213 | template<class O, class T>
|
3108 | 3214 | struct out_value_result {
|
3109 | 3215 | [[no_unique_address]] O out;
|
|
4518 | 4624 | \end{codeblock}
|
4519 | 4625 | \end{itemdescr}
|
4520 | 4626 |
|
| 4627 | +\rSec2[alg.fold]{Fold} |
| 4628 | + |
| 4629 | +\indexlibraryglobal{fold_left}% |
| 4630 | +\begin{itemdecl} |
| 4631 | +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, I> F> |
| 4632 | + constexpr auto ranges::fold_left(I first, S last, T init, F f); |
| 4633 | +template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, iterator_t<R>> F> |
| 4634 | + constexpr auto ranges::fold_left(R&& r, T init, F f); |
| 4635 | +\end{itemdecl} |
| 4636 | + |
| 4637 | +\begin{itemdescr} |
| 4638 | +\pnum |
| 4639 | +\returns |
| 4640 | +\begin{codeblock} |
| 4641 | +ranges::fold_left_with_iter(std::move(first), last, std::move(init), f).value |
| 4642 | +\end{codeblock} |
| 4643 | +\end{itemdescr} |
| 4644 | + |
| 4645 | +\indexlibraryglobal{fold_left_first}% |
| 4646 | +\begin{itemdecl} |
| 4647 | +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 4648 | + @\exposconcept{indirectly-binary-left-foldable}@<iter_value_t<I>, I> F> |
| 4649 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 4650 | + constexpr auto ranges::fold_left_first(I first, S last, F f); |
| 4651 | +template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 4652 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 4653 | + constexpr auto ranges::fold_left_first(R&& r, F f); |
| 4654 | +\end{itemdecl} |
| 4655 | + |
| 4656 | +\begin{itemdescr} |
| 4657 | +\pnum |
| 4658 | +\returns |
| 4659 | +\begin{codeblock} |
| 4660 | +ranges::fold_left_first_with_iter(std::move(first), last, f).value |
| 4661 | +\end{codeblock} |
| 4662 | +\end{itemdescr} |
| 4663 | + |
| 4664 | +\indexlibraryglobal{fold_right}% |
| 4665 | +\begin{itemdecl} |
| 4666 | +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 4667 | + @\exposconcept{indirectly-binary-right-foldable}@<T, I> F> |
| 4668 | + constexpr auto ranges::fold_right(I first, S last, T init, F f); |
| 4669 | +template<@\libconcept{bidirectional_range}@ R, class T, |
| 4670 | + @\exposconcept{indirectly-binary-right-foldable}@<T, iterator_t<R>> F> |
| 4671 | + constexpr auto ranges::fold_right(R&& r, T init, F f); |
| 4672 | +\end{itemdecl} |
| 4673 | + |
| 4674 | +\begin{itemdescr} |
| 4675 | +\pnum |
| 4676 | +\effects |
| 4677 | +Equivalent to: |
| 4678 | +\begin{codeblock} |
| 4679 | +using U = decay_t<invoke_result_t<F&, iter_reference_t<I>, T>>; |
| 4680 | +if (first == last) |
| 4681 | + return U(std::move(init)); |
| 4682 | +I tail = ranges::next(first, last); |
| 4683 | +U accum = invoke(f, *--tail, std::move(init)); |
| 4684 | +while (first != tail) |
| 4685 | + accum = invoke(f, *--tail, std::move(accum)); |
| 4686 | +return accum; |
| 4687 | +\end{codeblock} |
| 4688 | +\end{itemdescr} |
| 4689 | + |
| 4690 | +\indexlibraryglobal{fold_right_last}% |
| 4691 | +\begin{itemdecl} |
| 4692 | +template<@\libconcept{bidirectional_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 4693 | + @\exposconcept{indirectly-binary-right-foldable}@<iter_value_t<I>, I> F> |
| 4694 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 4695 | + constexpr auto ranges::fold_right_last(I first, S last, F f); |
| 4696 | +template<@\libconcept{bidirectional_range}@ R, |
| 4697 | + @\exposconcept{indirectly-binary-right-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 4698 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 4699 | + constexpr auto ranges::fold_right_last(R&& r, F f); |
| 4700 | +\end{itemdecl} |
| 4701 | + |
| 4702 | +\begin{itemdescr} |
| 4703 | +\pnum |
| 4704 | +Let \tcode{U} be |
| 4705 | +\tcode{decltype(ranges::fold_right(first, last, iter_value_t<I>(*first), f))}. |
| 4706 | + |
| 4707 | +\pnum |
| 4708 | +\effects |
| 4709 | +Equivalent to: |
| 4710 | +\begin{codeblock} |
| 4711 | +if (first == last) |
| 4712 | + return optional<U>(); |
| 4713 | +I tail = ranges::prev(ranges::next(first, std::move(last))); |
| 4714 | +return optional<U>(in_place, |
| 4715 | + ranges::fold_right(std::move(first), tail, iter_value_t<I>(*tail), std::move(f))); |
| 4716 | +\end{codeblock} |
| 4717 | +\end{itemdescr} |
| 4718 | + |
| 4719 | +\indexlibraryglobal{fold_left_with_iter}% |
| 4720 | +\begin{itemdecl} |
| 4721 | +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class T, |
| 4722 | + @\exposconcept{indirectly-binary-left-foldable}@<T, I> F> |
| 4723 | + constexpr @\seebelow@ ranges::fold_left_with_iter(I first, S last, T init, F f); |
| 4724 | +template<@\libconcept{input_range}@ R, class T, @\exposconcept{indirectly-binary-left-foldable}@<T, iterator_t<R>> F> |
| 4725 | + constexpr @\seebelow@ ranges::fold_left_with_iter(R&& r, T init, F f); |
| 4726 | +\end{itemdecl} |
| 4727 | + |
| 4728 | +\begin{itemdescr} |
| 4729 | +\pnum |
| 4730 | +Let \tcode{U} be \tcode{decay_t<invoke_result_t<F\&, T, iter_reference_t<I>>>}. |
| 4731 | + |
| 4732 | +\pnum |
| 4733 | +\effects |
| 4734 | +Equivalent to: |
| 4735 | +\begin{codeblock} |
| 4736 | +if (first == last) |
| 4737 | + return {std::move(first), U(std::move(init))}; |
| 4738 | +U accum = invoke(f, std::move(init), *first); |
| 4739 | +for (++first; first != last; ++first) |
| 4740 | + accum = invoke(f, std::move(accum), *first); |
| 4741 | +return {std::move(first), std::move(accum)}; |
| 4742 | +\end{codeblock} |
| 4743 | + |
| 4744 | +\pnum |
| 4745 | +\remarks |
| 4746 | +The return type is |
| 4747 | +\tcode{fold_left_with_iter_result<I, U>} for the first overload and |
| 4748 | +\tcode{fold_left_with_iter_result<borrowed_iterator_t<R>, U>} |
| 4749 | +for the second overload. |
| 4750 | +\end{itemdescr} |
| 4751 | + |
| 4752 | +\indexlibraryglobal{fold_left_first_with_iter}% |
| 4753 | +\begin{itemdecl} |
| 4754 | +template<@\libconcept{input_iterator}@ I, @\libconcept{sentinel_for}@<I> S, |
| 4755 | + @\exposconcept{indirectly-binary-left-foldable}@<iter_value_t<I>, I> F> |
| 4756 | + requires @\libconcept{constructible_from}@<iter_value_t<I>, iter_reference_t<I>> |
| 4757 | + constexpr @\seebelow@ ranges::fold_left_first_with_iter(I first, S last, F f); |
| 4758 | +template<@\libconcept{input_range}@ R, @\exposconcept{indirectly-binary-left-foldable}@<range_value_t<R>, iterator_t<R>> F> |
| 4759 | + requires @\libconcept{constructible_from}@<range_value_t<R>, range_reference_t<R>> |
| 4760 | + constexpr @\seebelow@ ranges::fold_left_first_with_iter(R&& r, F f); |
| 4761 | +\end{itemdecl} |
| 4762 | + |
| 4763 | +\begin{itemdescr} |
| 4764 | +\pnum |
| 4765 | +Let \tcode{U} be |
| 4766 | +\begin{codeblock} |
| 4767 | +decltype(ranges::fold_left(std::move(first), last, iter_value_t<I>(*first), f)) |
| 4768 | +\end{codeblock} |
| 4769 | + |
| 4770 | +\pnum |
| 4771 | +\effects |
| 4772 | +Equivalent to: |
| 4773 | +\begin{codeblock} |
| 4774 | +if (first == last) |
| 4775 | + return {std::move(first), optional<U>()}; |
| 4776 | +optional<U> init(in_place, *first); |
| 4777 | +for (++first; first != last; ++first) |
| 4778 | + *init = invoke(f, std::move(*init), *first); |
| 4779 | +return {std::move(first), std::move(init)}; |
| 4780 | +\end{codeblock} |
| 4781 | + |
| 4782 | +\pnum |
| 4783 | +\remarks |
| 4784 | +The return type is |
| 4785 | +\tcode{fold_left_first_with_iter_result<I, optional<U>>} |
| 4786 | +for the first overload and |
| 4787 | +\tcode{fold_left_first_with_iter_result<borrowed_iterator_t<R>, optional<U>>} |
| 4788 | +for the second overload. |
| 4789 | +\end{itemdescr} |
| 4790 | + |
4521 | 4791 | \rSec1[alg.modifying.operations]{Mutating sequence operations}
|
4522 | 4792 |
|
4523 | 4793 | \rSec2[alg.copy]{Copy}
|
|
0 commit comments