Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::ranges::fold_left(3)     C++ Standard Libary    std::ranges::fold_left(3)

NAME
       std::ranges::fold_left -	std::ranges::fold_left

Synopsis
	  Defined in header <algorithm>
	  Call signature
	  template< std::input_iterator	I, std::sentinel_for<I>
	  S, class T,
									(since
		    /* indirectly-binary-left-foldable */<T, I>		C++23)
	  F >								(until
									C++26)
	  constexpr auto fold_left( I first, S last, T init, F
	  f );
	  template< std::input_iterator	I, std::sentinel_for<I>
	  S,

		    class T = std::iter_value_t<I>,			(since
		    /* indirectly-binary-left-foldable */<T, I>		C++26)
	  F >

	  constexpr auto fold_left( I first, S last, T init, F
	  f );							(1)
	  template< ranges::input_range	R, class T,

		    /*		  indirectly-binary-left-foldable	    */
       (since C++23)
			<T,	    ranges::iterator_t<R>>	   F	     >
       (until C++26)

	  constexpr auto fold_left( R&&	r, T init, F f );
	  template< ranges::input_range	R, class T =
	  ranges::range_value_t<R>,
								    (2)
		    /*		  indirectly-binary-left-foldable	    */
       (since C++26)
			<T, ranges::iterator_t<R>> F >

	  constexpr auto fold_left( R&&	r, T init, F f );
	  Helper concepts
	  template<	class	  F,	 class	   T,	   class      I	     >
       (exposition
	  concept  /*  indirectly-binary-left-foldable	*/ = /*		   (3)
       only*)
	  see description */;

	  Left-folds the elements of given range, that is, returns the	result
       of evaluation of
	  the chain expression:
	  f(f(f(f(init,	x[1]), x[2]), ...), x[n]), where x[1], x[2], ..., x[n]
       are elements of
	  the range.

	  Informally,  ranges::fold_left  behaves like std::accumulate's over-
       load that accepts a
	  binary predicate.

	  The behavior is undefined if [first, last) is	not a valid range.

	  1) The range is [first, last). Equivalent to return
	  ranges::fold_left_with_iter(std::move(first),	last, std::move(init),
       f).value.
	  2) Same as (1), except that uses r as	the  range,  as	 if  by	 using
       ranges::begin(r)	as
	  first	and ranges::end(r) as last.
	  3) Equivalent	to:

	  Helper concepts
	  template< class F, class T, class I, class U >

	  concept /*indirectly-binary-left-foldable-impl*/ =
	      std::movable<T> &&
	      std::movable<U> &&
	      std::convertible_to<T,  U>  &&				  (3A)
       (exposition only*)
	      std::invocable<F&, U, std::iter_reference_t<I>> &&
	      std::assignable_from<U&,

		  std::invoke_result_t<F&, U,
	  std::iter_reference_t<I>>>;
	  template< class F, class T, class I >

	  concept /*indirectly-binary-left-foldable*/ =
	      std::copy_constructible<F> &&
	      std::indirectly_readable<I> &&
	      std::invocable<F&, T, std::iter_reference_t<I>> &&
	      std::convertible_to<std::invoke_result_t<F&,  T,		  (3B)
       (exposition only*)
	  std::iter_reference_t<I>>,
		  std::decay_t<std::invoke_result_t<F&,	T,
	  std::iter_reference_t<I>>>> &&
	      /*indirectly-binary-left-foldable-impl*/<F, T, I,

		  std::decay_t<std::invoke_result_t<F&,	T,
	  std::iter_reference_t<I>>>>;

	  The  function-like  entities	described  on this page	are niebloids,
       that is:

	    * Explicit template	argument lists cannot be specified when	 call-
       ing 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  in-
       hibited.

	  In  practice,	 they  may be implemented as function objects, or with
       special compiler
	  extensions.

Parameters
	  first, last -	the range of elements to fold
	  r	      -	the range of elements to fold
	  init	      -	the initial value of the fold
	  f	      -	the binary function object

Return value
	  An object of type U that contains the	result	of  left-fold  of  the
       given range over	f,
	  where	U is equivalent	to std::decay_t<std::invoke_result_t<F&, T,
	  std::iter_reference_t<I>>>.

	  If the range is empty, U(std::move(init)) is returned.

Possible implementations
       struct fold_left_fn {
	   template<std::input_iterator	 I,  std::sentinel_for<I> S, class T =
       std::iter_value_t<I>,
		    /* indirectly-binary-left-foldable */<T, I>	F>
	   constexpr auto operator()(I first, S	last, T	init, F	f) const
	   {
	       using	U    =	  std::decay_t<std::invoke_result_t<F&,	    T,
       std::iter_reference_t<I>>>;
	       if (first == last)
		   return U(std::move(init));
	       U accum = std::invoke(f,	std::move(init), *first);
	       for (++first; first != last; ++first)
		   accum = std::invoke(f, std::move(accum), *first);
	       return std::move(accum);
	   }

	   template<ranges::input_range	R, class T = ranges::range_value_t<R>,
		    /*	indirectly-binary-left-foldable	 */<T,	ranges::itera-
       tor_t<R>> F>
	   constexpr auto operator()(R&& r, T init, F f) const
	   {
	       return	     (*this)(ranges::begin(r),	       ranges::end(r),
       std::move(init),	std::ref(f));
	   } };

       inline constexpr	fold_left_fn fold_left;

Complexity
	  Exactly  ranges::distance(first,  last) applications of the function
       object f.

Notes
	  The following	table compares all constrained folding algorithms:

	       Fold function template	    Starts Initial		Return
       type
					     from   value
	  ranges::fold_left		    left   init	   U
	  ranges::fold_left_first	    left   first   std::optional<U>
						   element
	  ranges::fold_right		    right  init	   U
	  ranges::fold_right_last	    right  last	   std::optional<U>
						   element
							   (1)
       ranges::in_value_result<I, U>

	  ranges::fold_left_with_iter		  left	      init	   (2)
       ranges::in_value_result<BR, U>,

							   where BR is
							   ranges::bor-
       rowed_iterator_t<R>
							   (1)
       ranges::in_value_result<I,
							   std::optional<U>>

	  ranges::fold_left_first_with_iter	 left	     first	   (2)
       ranges::in_value_result<BR,
						   element std::optional<U>>

							   where BR is
							   ranges::bor-
       rowed_iterator_t<R>

		    Feature-test       macro		     Value	   Std
       Feature
	  __cpp_lib_ranges_fold			 202207L  (C++23)  std::ranges
       fold algorithms
	  __cpp_lib_algorithm_default_value_type 202403	 (C++26) List-initial-
       ization for
								 algorithms
       (1,2)

Example
       // Run this code

	#include <algorithm>
	#include <complex>
	#include <functional>
	#include <iostream>
	#include <ranges>
	#include <string>
	#include <utility>
	#include <vector>

	int main()
	{
	    namespace ranges = std::ranges;

	    std::vector	v{1, 2,	3, 4, 5, 6, 7, 8};

	    int	    sum	   =	ranges::fold_left(v.begin(),	v.end(),    0,
       std::plus<int>()); // (1)
	    std::cout << "sum: " << sum	<< '\n';

	    int	mul = ranges::fold_left(v, 1, std::multiplies<int>()); // (2)
	    std::cout << "mul: " << mul	<< '\n';

	    // 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', 3.5f}};
	    float sec =	ranges::fold_left
	    (
		data | ranges::views::values, 2.0f, std::multiplies<>()
	    );
	    std::cout << "sec: " << sec	<< '\n';

	    // use a program defined function object (lambda-expression):
	    std::string	str = ranges::fold_left
	    (
		v,  "A",  [](std::string  s,  int  x)  {  return  s  +	':'  +
       std::to_string(x); }
	    );
	    std::cout << "str: " << str	<< '\n';

	    using CD = std::complex<double>;
	    std::vector<CD> nums{{1, 1}, {2, 0}, {3, 0}};
	    #ifdef __cpp_lib_algorithm_default_value_type
		auto res = ranges::fold_left(nums, {7, 0}, std::multiplies{});
       // (2)
	    #else
		auto  res  =  ranges::fold_left(nums,  CD{7,  0},  std::multi-
       plies{}); // (2)
	    #endif
	    std::cout << "res: " << res	<< '\n';
	}

Output:
	sum: 36
	mul: 40320
	sec: 42
	str: A:1:2:3:4:5:6:7:8
	res: (42,42)

References
	    * C++23 standard (ISO/IEC 14882:2023):

	    * 27.6.18 Fold [alg.fold]

See also
	  ranges::fold_left_first	    left-folds a range of elements us-
       ing the first
	  (C++23)			    element as an initial value
					    (niebloid)
	  ranges::fold_right		    right-folds	a range	of elements
	  (C++23)			    (niebloid)
	  ranges::fold_right_last	    right-folds	a  range  of  elements
       using the last
	  (C++23)			    element as an initial value
					    (niebloid)
	  ranges::fold_left_with_iter	     left-folds	 a  range of elements,
       and returns a pair
	  (C++23)			    (iterator, value)
					    (niebloid)
					    left-folds a range of elements us-
       ing the first
	  ranges::fold_left_first_with_iter element as an initial  value,  and
       returns a pair
	  (C++23)			    (iterator, optional)
					    (niebloid)
	  accumulate			     sums  up or folds a range of ele-
       ments
					    (function template)
	  reduce			    similar to std::accumulate,	except
       out of order
	  (C++17)			    (function template)

http://cppreference.com		  2024.06.10	     std::ranges::fold_left(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::ranges::fold_left&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help