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

FreeBSD Manual Pages

  
 
  

home | help
std::ranges::adjacent_find(3) C++ Standard Libarystd::ranges::adjacent_find(3)

NAME
       std::ranges::adjacent_find - std::ranges::adjacent_find

Synopsis
	  Defined in header <algorithm>
	  Call signature
	  template< std::forward_iterator I, std::sentinel_for<I> S, class
	  Proj = std::identity,

		    std::indirect_binary_predicate<
			std::projected<I,				Proj>,
       (1) (since C++20)
			std::projected<I, Proj>> Pred =	ranges::equal_to >
	  constexpr I

	      adjacent_find( I first, S	last, Pred pred	= {}, Proj proj	= {}
	  );
	  template< ranges::forward_range R, class Proj	= std::identity,

		    std::indirect_binary_predicate<
			std::projected<ranges::iterator_t<R>, Proj>,
			std::projected<ranges::iterator_t<R>,  Proj>>  Pred  =
       (2) (since C++20)
	  ranges::equal_to >
	  constexpr ranges::borrowed_iterator_t<R>

	      adjacent_find( R&& r, Pred pred =	{}, Proj proj =	{} );

	  Searches the range [first, last) for two consecutive equal elements.

	  1)  Elements are compared using pred (after projecting with the pro-
       jection proj).
	  2) Same as (1), but  uses  r	as  the	 source	 range,	 as  if	 using
       ranges::begin(r)	as
	  first	and ranges::end(r) as last.

	  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 examine
	  r	      -	the range of the elements to examine
	  pred	      -	predicate to apply to the projected elements
	  proj	      -	projection to apply to the elements

Return value
	  An iterator to the first of the first	pair  of  identical  elements,
       that is,	the first
	  iterator  it	such  that  bool(std::invoke(pred,  std::invoke(proj1,
       *it),
	  std::invoke(proj, *(it + 1)))) is true.

	  If no	such elements are found, an iterator  equal  to	 last  is  re-
       turned.

Complexity
	  Exactly  min((result	- first) + 1, (last - first) - 1) applications
       of the predicate
	  and projection where result is the return value.

Possible implementation
	struct adjacent_find_fn
	{
	    template<std::forward_iterator I,  std::sentinel_for<I>  S,	 class
       Proj = std::identity,
		     std::indirect_binary_predicate<
			 std::projected<I, Proj>,
			 std::projected<I, Proj>> Pred = ranges::equal_to>
	    constexpr  I operator()(I first, S last, Pred pred = {}, Proj proj
       = {}) const
	    {
		if (first == last)
		    return first;
		auto next = ranges::next(first);
		for (; next != last; ++next, ++first)
		    if (std::invoke(pred, std::invoke(proj, *first),  std::in-
       voke(proj, *next)))
			return first;
		return next;
	    }

	    template<ranges::forward_range R, class Proj = std::identity,
		     std::indirect_binary_predicate<
			 std::projected<ranges::iterator_t<R>, Proj>,
			 std::projected<ranges::iterator_t<R>,	Proj>>	Pred =
       ranges::equal_to>
	    constexpr ranges::borrowed_iterator_t<R>
		operator()(R&& r, Pred pred = {}, Proj proj = {}) const
	    {
		return	      (*this)(ranges::begin(r),	       ranges::end(r),
       std::ref(pred), std::ref(proj));
	    }
	};

	inline constexpr adjacent_find_fn adjacent_find;

Example
       // Run this code

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

	constexpr bool some_of(auto&& r, auto&&	pred) // some but not all
	{
	    return std::ranges::cend(r)	!= std::ranges::adjacent_find(r,
		[&pred](auto const& x, auto const& y)
		{
		    return pred(x) != pred(y);
		});
	}

	// test	some_of
	constexpr auto a = {0, 0, 0, 0}, b = {1, 1, 1, 0}, c = {1, 1, 1, 1};
	auto is_one = [](auto x){ return x == 1; };
	static_assert(!some_of(a, is_one) && some_of(b,	is_one)	&& !some_of(c,
       is_one));

	int main()
	{
	    const auto v = {0, 1, 2, 3,	40, 40,	41, 41,	5}; /*
					^^	    ^^	     */
	    namespace ranges = std::ranges;

	    if	(auto  it  =  ranges::adjacent_find(v.begin(), v.end()); it ==
       v.end())
		std::cout << "No matching adjacent elements\n";
	    else
		std::cout << "The first	adjacent pair of equal elements	is  at
       ["
			  << ranges::distance(v.begin(), it) <<	"] == "	<< *it
       << '\n';

	    if	(auto  it = ranges::adjacent_find(v, ranges::greater()); it ==
       v.end())
		std::cout << "The entire vector	is  sorted  in	ascending  or-
       der\n";
	    else
		std::cout  <<  "The  last element in the non-decreasing	subse-
       quence is at ["
			  << ranges::distance(v.begin(), it) <<	"] == "	<< *it
       << '\n';
	}

Output:
	The first adjacent pair	of equal elements is at	[4] == 40
	The last element in the	non-decreasing subsequence is at [7] ==	41

See also
	  ranges::unique removes consecutive duplicate elements	in a range
	  (C++20)	 (niebloid)
			 finds the first two adjacent items that are equal (or
       satisfy a given
	  adjacent_find	 predicate)
			 (function template)

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

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

home | help