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

FreeBSD Manual Pages

  
 
  

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

NAME
       std::ranges::fold_right_last - std::ranges::fold_right_last

Synopsis
	  Defined in header <algorithm>
	  Call signature
	  template< std::bidirectional_iterator	I, std::sentinel_for<I>	S,

	  /*indirectly-binary-right-foldable*/<std::iter_value_t<I>, I>	F >
	  requires				      std::constructible_from<
       (1) (since C++23)
		       std::iter_value_t<I>, std::iter_reference_t<I>>
	  constexpr auto

	      fold_right_last( I first,	S last,	F f );
	  template< ranges::bidirectional_range	R,

		    /*indirectly-binary-right-foldable*/<
			ranges::range_value_t<R>, ranges::iterator_t<R>> F
	  >
	  requires				      std::constructible_from<
       (2) (since C++23)
		       ranges::range_value_t<R>,
	  ranges::range_reference_t<R>>
	  constexpr auto

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

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

	  Informally,	    ranges::fold_right_last	   behaves	  like
       std::fold_left(ranges::reverse(r),
	  *--last, /*flipped*/(f)) (assuming the range is not empty).

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

	  1)	The    range	is    [first,	 last).	  Given	  U   as   de-
       cltype(ranges::fold_right(first,	last,
	  std::iter_value_t<I>(*first),	f)), equivalent	to:

	if (first == last)
	    return std::optional<U>();
	I tail = ranges::prev(ranges::next(first, std::move(last)));
	return				       std::optional<U>(std::in_place,
       ranges::fold_right(std::move(first), tail,
	    std::iter_value_t<I>(*tail), std::move(f)));

	  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>>>>;

	  4) Equivalent	to:

	  Helper concepts
	  template< class F, class T, class I >
									      (ex-
       position
	  concept /*indirectly-binary-right-foldable*/ =		  (4A)
       only*)

	      /*indirectly-binary-left-foldable*/</*flipped*/<F>, T, I>;
	  Helper class templates
	  template< class F >

	  class	/*flipped*/
	  {
	      F		  f;		  //	      exposition	  only
       (exposition
	  public:							  (4B)
       only*)
	      template<	class T, class U >
		  requires std::invocable<F&, U, T>
	      std::invoke_result_t<F&, U, T> operator()( T&&, U&& );

	  };

	  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
	  f	      -	the binary function object

Return value
	  An object of type  std::optional<U>  that  contains  the  result  of
       right-fold of the
	  given	range over f.

	  If the range is empty, std::optional<U>() is returned.

Possible implementations
	  struct fold_right_last_fn
	  {
	      template<std::bidirectional_iterator I, std::sentinel_for<I> S,
		       /*indirectly-binary-right-fold-
       able*/<std::iter_value_t<I>, I> F>
	      requires
		  std::constructible_from<std::iter_value_t<I>,	std::iter_ref-
       erence_t<I>>
	      constexpr	auto operator()(I first, S last, F f) const
	      {
		  using	U = decltype(
		      ranges::fold_right(first,				 last,
       std::iter_value_t<I>(*first), f));

		  if (first == last)
		      return std::optional<U>();
		  I tail = ranges::prev(ranges::next(first, std::move(last)));
		  return std::optional<U>(std::in_place,
		      ranges::fold_right(std::move(first),		 tail,
       std::iter_value_t<I>(*tail),
					 std::move(f)));
	      }

	      template<ranges::bidirectional_range R,
		       /*indirectly_binary_right_foldable*/<
			   ranges::range_value_t<R>, ranges::iterator_t<R>> F>
	      requires
		  std::constructible_from<ranges::range_value_t<R>,
       ranges::range_reference_t<R>>
	      constexpr	auto operator()(R&& r, F f) const
	      {
		  return       (*this)(ranges::begin(r),       ranges::end(r),
       std::ref(f));
	      }
	  };

	  inline constexpr fold_right_last_fn fold_right_last;

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

Example
       // Run this code

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

	int main()
	{
	    auto v = {1, 2, 3, 4, 5, 6,	7, 8};
	    std::vector<std::string> vs	{"A", "B", "C",	"D"};

	    auto   r1	=   std::ranges::fold_right_last(v.begin(),   v.end(),
       std::plus<>()); // (1)
	    std::cout << "*r1: " << *r1	<< '\n';

	    auto r2 = std::ranges::fold_right_last(vs, std::plus<>()); // (2)
	    std::cout << "*r2: " << *r2	<< '\n';

	    // Use a program defined function object (lambda-expression):
	    auto  r3  =	std::ranges::fold_right_last(v,	[](int x, int y) { re-
       turn x +	y + 99;	});
	    std::cout << "*r3: " << *r3	<< '\n';

	    // Get the product of the std::pair::second	of all	pairs  in  the
       vector:
	    std::vector<std::pair<char,	float>>	data {{'A', 3.f}, {'B',	3.5f},
       {'C', 4.f}};
	    auto r4 = std::ranges::fold_right_last
	    (
		data | std::ranges::views::values, std::multiplies<>()
	    );
	    std::cout << "*r4: " << *r4	<< '\n';
	}

Output:
	*r1: 36
	*r2: ABCD
	*r3: 729
	*r4: 42

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

	    * 27.6.18 Fold [alg.fold]

See also
	  ranges::fold_right		    right-folds	a range	of elements
	  (C++23)			    (niebloid)
	  ranges::fold_left		    left-folds a range of elements
	  (C++23)			    (niebloid)
	  ranges::fold_left_first	    left-folds a range of elements us-
       ing the first
	  (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..._right_last(3)

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

home | help