std::ranges::fold_left_first_with_iter, std::ranges::fold_left_first_with_iter_result - cppreference.com

From cppreference.com

Defined in header

<algorithm>

Call signature

template<std::input_iteratorI,std::sentinel_for<I>S,/*indirectly-binary-left-foldable*/<std::iter_value_t<I>,I>F>requiresstd::constructible_from<std::iter_value_t<I>,std::iter_reference_t<I>>constexprranges::fold_left_first_with_iter_result<I,std::optional</* see below */>>fold_left_first_with_iter(Ifirst,Slast,Ff); (1) (since C++23)template<ranges::input_rangeR,/*indirectly-binary-left-foldable*/<ranges::range_value_t<R>,ranges::iterator_t<R>>F>requiresstd::constructible_from<ranges::range_value_t<R>,ranges::range_reference_t<R>>constexprranges::fold_left_first_with_iter_result<ranges::borrowed_iterator_t<R>,std::optional</* see below */>>fold_left_first_with_iter(R&&r,Ff); (2) (since C++23)Helper template

template<classI,classT>usingfold_left_first_with_iter_result=ranges::in_value_result<I,T>; (3) (since C++23)For the definition of /*indirectly-binary-left-foldable*/, see

this page

.

Left-

folds

the elements of the source range, that is, returns the result of evaluation of the chain expression:
f(f(f(f(x1, x2), x3), ...), xn), where x1, x2, ..., xn are elements of the source range. Also returns the past-the-end iterator of the source range.

1) The source range is [first, last).

2) The source range is r.

3) The return type alias template.

The function-like entities described on this page are

algorithm function objects

(informally known as niebloids), that is:

Explicit template argument lists cannot be specified when calling any of them.

None of them are visible to

argument-dependent lookup

.

When any of them are found by

normal unqualified lookup

as the name to the left of the function-call operator,

argument-dependent lookup

is inhibited.

Parameters

first, last - the iterator-sentinel pair defining the source

range

r - the source range f - the binary function object Return value

A ranges::fold_left_first_with_iter_result object where:

The data member

in

holds the past-the-end iterator of the source range.

The data member

value

holds an

std::optional

object containing the left-fold result, or does not contain a value if the source range is empty.

The value type of the

std::optional

in the return type is the decayed type of F's result type.

Notes

The following table compares all constrained folding algorithms. U below is the fold result type, it is the decayed type of F's result type.

Fold function template Starts from Initial value Return type ranges::fold_leftleftinitUranges::fold_left_firstleftfirst elementstd::optional<U>ranges::fold_rightrightinitUranges::fold_right_lastrightlast elementstd::optional<U>ranges::fold_left_with_iterleftinit(1) ranges::in_value_result<I,U>

(2) ranges::in_value_result<BR,U>,

where BR is ranges::borrowed_iterator_t<R>

ranges::fold_left_first_with_iterleftfirst element(1) ranges::in_value_result<I,std::optional<U>>

(2) ranges::in_value_result<BR,std::optional<U>>

where BR is ranges::borrowed_iterator_t<R>

Feature-test

macroValueStdFeature

__cpp_lib_ranges_fold

202207L

(C++23)std::ranges

fold algorithms

Possible implementations

classfold_left_first_with_iter_fn{template<classO,classI,classS,classF>constexprautoimpl(I&&first,S&&last,Ff)const{usingU=decltype(ranges::fold_left(std::move(first),last,std::iter_value_t<I>(*first),f));usingRet=ranges::fold_left_first_with_iter_result<O,std::optional<U>>;if(first==last)returnRet{std::move(first),std::optional<U>()};std::optional<U>init(std::in_place,*first);for(++first;first!=last;++first)*init=std::invoke(f,std::move(*init),*first);returnRet{std::move(first),std::move(init)};}public:template<std::input_iteratorI,std::sentinel_for<I>S,/*indirectly-binary-left-foldable*/<std::iter_value_t<I>,I>F>requiresstd::constructible_from<std::iter_value_t<I>,std::iter_reference_t<I>>constexprautooperator()(Ifirst,Slast,Ff)const{returnimpl<I>(std::move(first),std::move(last),std::ref(f));}usingBR=ranges::borrowed_iterator_t<R>;template<ranges::input_rangeR,/*indirectly-binary-left-foldable*/<ranges::range_value_t<R>,ranges::iterator_t<R>>F>requiresstd::constructible_from<ranges::range_value_t<R>,ranges::range_reference_t<R>>constexprautooperator()(R&&r,Ff)const{returnimpl<BR>(ranges::begin(r),ranges::end(r),std::ref(f));}template<ranges::forward_rangeR,/*indirectly-binary-left-foldable*/<ranges::range_value_t<R>,ranges::iterator_t<R>>F>requiresstd::constructible_from<ranges::range_value_t<R>,ranges::range_reference_t<R>>constexprautooperator()(R&&r,Ff)const{returnimpl<BR>(ranges::begin(r),ranges::next(ranges::begin(r),ranges::end(r)),std::ref(f));}};inlineconstexprfold_left_first_with_iter_fnfold_left_first_with_iter;Example

Run this code

#include<algorithm>#include<cassert>#include<functional>#include<iostream>#include<ranges>#include<utility>#include<vector>intmain(){std::vectorv{1,2,3,4,5,6,7,8};autosum=std::ranges::fold_left_first_with_iter(v.begin(),v.end(),std::plus<int>());std::cout<<"sum: "<<sum.value.value()<<'\n';assert(sum.in==v.end());automul=std::ranges::fold_left_first_with_iter(v,std::multiplies<int>());std::cout<<"mul: "<<mul.value.value()<<'\n';assert(mul.in==v.end());// get the product of the std::pair::second of all pairs in the vector:std::vector<std::pair<char,float>>data{{'A',2.f},{'B',3.f},{'C',7.f}};autosec=std::ranges::fold_left_first_with_iter(data|std::ranges::views::values,std::multiplies<>());std::cout<<"sec: "<<sec.value.value()<<'\n';// use a program defined function object (lambda-expression):autolambda=[](intx,inty){returnx+y+2;};autoval=std::ranges::fold_left_first_with_iter(v,lambda);std::cout<<"val: "<<val.value.value()<<'\n';assert(val.in==v.end());}Output:

sum: 36 mul: 40320 sec: 42 val: 50 References

C++23 standard (ISO/IEC 14882:2024):

27.6.18 Fold [alg.fold]

See also

ranges::fold_left

(C++23)

left-folds a range of elements
(algorithm function object)

[edit]

ranges::fold_left_first

(C++23)

left-folds a range of elements using the first element as an initial value
(algorithm function object)

[edit]

ranges::fold_right

(C++23)

right-folds a range of elements
(algorithm function object)

[edit]

ranges::fold_right_last

(C++23)

right-folds a range of elements using the last element as an initial value
(algorithm function object)

[edit]

ranges::fold_left_with_iter

(C++23)

left-folds a range of elements, and returns a

pair

(iterator, value)
(algorithm function object)

[edit]

accumulate

sums up or folds a range of elements
(function template)

[edit]

reduce

(C++17)

similar to

std::accumulate

, except out of order
(function template)

[edit]