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

NAME
     std::ranges::find_first_of - std::ranges::find_first_of

Synopsis
	Defined in header <algorithm>
	Call signature
	template< std::input_iterator I1, std::sentinel_for<I1> S1,

		  std::forward_iterator I2, std::sentinel_for<I2> S2,
		  class Pred = ranges::equal_to,
		  class Proj1 = std::identity,
		  class 	 Proj2	       =	 std::identity	       >
     (1) (since
	requires  std::indirectly_comparable<I1,   I2,	 Pred,	 Proj1,   Proj2>
     C++20)
	constexpr I1
	    find_first_of( I1 first1, S1 last1, I2 first2, S2 last2, Pred pred =
	{},

			   Proj1 proj1 = {}, Proj2 proj2 = {} );
	template< ranges::input_range R1, ranges::forward_range R2,

		  class Pred = ranges::equal_to,
		  class Proj1 = std::identity,
		  class Proj2 = std::identity >
	requires	      std::indirectly_comparable<ranges::iterator_t<R1>,
     (2) (since
					    ranges::iterator_t<R2>,
     C++20)
					    Pred, Proj1, Proj2>
	constexpr ranges::borrowed_iterator_t<R1>
	    find_first_of( R1&& r1, R2&& r2, Pred pred = {},

			   Proj1 proj1 = {}, Proj2 proj2 = {} );

	1) Searches the range [first1, last1) for any of  the  elements  in  the
     range
	[first2,  last2),  after  projecting the ranges with proj1 and proj2 re-
     spectively. The
	projected elements are compared using the binary predicate pred.
	2) Same as (1), but uses r1 as the first source range and r2 as the sec-
     ond source
	range, as if  using  ranges::begin(r1)	as  first1,  ranges::end(r1)  as
     last1,
	ranges::begin(r2) as first2, and ranges::end(r2) as last2.

	The  function-like  entities  described on this page are 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  inhib-
     ited.

	In  practice,  they may be implemented as function objects, or with spe-
     cial compiler
	extensions.

Parameters
	first1, last1 - the range of elements to examine (aka haystack)
	first2, last2 - the range of elements to search for (aka needles)
	r1	      - the range of elements to examine (aka haystack)
	r2	      - the range of elements to search for (aka needles)
	pred	      - binary predicate to compare the elements
	proj1	      - projection to apply to the elements in the first range
	proj2	      - projection to apply to the elements in the second range

Return value
	Iterator to the first element in the range [first1, last1) that is equal
     to an
	element from the range [first2, last2) after projection. If no such ele-
     ment is
	found, an iterator comparing equal to last1 is returned.

Complexity
	At most S * N applications of the predicate and each projection, where
	(1) S = ranges::distance(first2, last2) and N = ranges::distance(first1,
     last1);
	(2) S = ranges::distance(r2) and N = ranges::distance(r1).

Possible implementation
     struct find_first_of_fn {
	 template<std::input_iterator I1, std::sentinel_for<I1> S1,
		  std::forward_iterator I2, std::sentinel_for<I2> S2,
		  class Pred = ranges::equal_to,
		  class Proj1 = std::identity,
		  class Proj2 = std::identity>
	 requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
	 constexpr I1 operator()(I1 first1, S1 last1, I2 first2, S2 last2,  Pred
     pred = {},
				 Proj1 proj1 = {}, Proj2 proj2 = {}) const
	 {
	     for (; first1 != last1; ++first1)
		 for (auto i = first2; i != last2; ++i)
		     if (std::invoke(pred, std::invoke(proj1, *first1), std::in-
     voke(proj2, *i)))
			 return first1;
	     return first1;
	 }

	 template<ranges::input_range R1, ranges::forward_range R2,
		  class Pred = ranges::equal_to,
		  class Proj1 = std::identity,
		  class Proj2 = std::identity>
	 requires std::indirectly_comparable<ranges::iterator_t<R1>,
					     ranges::iterator_t<R2>,
					     Pred, Proj1, Proj2>
	 constexpr ranges::borrowed_iterator_t<R1>
	     operator()(R1&& r1, R2&& r2, Pred pred = {},
			Proj1 proj1 = {}, Proj2 proj2 = {}) const
	 {
	     return (*this)(ranges::begin(r1), ranges::end(r1),
			    ranges::begin(r2), ranges::end(r2),
			    std::move(pred),		       std::move(proj1),
     std::move(proj2));
	 } };

     inline constexpr find_first_of_fn find_first_of {};

Example
     // Run this code

      #include <algorithm>
      #include <iostream>
      #include <iterator>

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

	  constexpr static auto haystack = {1, 2, 3, 4};
	  constexpr static auto needles  = {0, 3, 4, 3};

	  constexpr   auto   found1    =    rng::find_first_of(haystack.begin(),
     haystack.end(),
						     needles.begin(),	    nee-
     dles.end());
	  static_assert(std::distance(haystack.begin(), found1) == 2);

	  constexpr auto found2 = rng::find_first_of(haystack, needles);
	  static_assert(std::distance(haystack.begin(), found2) == 2);

	  constexpr static auto negatives = {-6, -3, -4, -3};
	  constexpr auto not_found = rng::find_first_of(haystack, negatives);
	  static_assert(not_found == haystack.end());

	  constexpr auto found3 = rng::find_first_of(haystack, negatives,
	      [](int x, int y) { return x == -y; }); // uses a binary comparator
	  static_assert(std::distance(haystack.begin(), found3) == 2);

	  struct P { int x, y; };
	  constexpr static auto p1 = {P{1, -1}, P{2, -2}, P{3, -3}, P{4, -4}};
	  constexpr static auto p2 = {P{5, -5}, P{6, -3}, P{7, -5}, P{8, -3}};

	  // Compare only P::y data members by projecting them:
	  const auto found4 = rng::find_first_of(p1, p2, {}, &P::y, &P::y);
	  std::cout << "First equivalent element {" <<	found4->x  <<  ",  "  <<
     found4->y
		    <<	"}  was found at position " << std::distance(p1.begin(),
     found4)
		    << ".\n";
      }

Output:
      First equivalent element {3, -3} was found at position 2.

See also
	find_first_of	      searches for any one of a set of elements
			      (function template)
	ranges::adjacent_find finds the first two adjacent items that are  equal
     (or satisfy
	(C++20) 	      a given predicate)
			      (niebloid)
	ranges::find
	ranges::find_if
	ranges::find_if_not   finds the first element satisfying specific crite-
     ria
	(C++20) 	      (niebloid)
	(C++20)
	(C++20)
	ranges::find_end       finds  the last sequence of elements in a certain
     range
	(C++20) 	      (niebloid)
	ranges::search	      searches for a range of elements
	(C++20) 	      (niebloid)
	ranges::search_n      searches for a number consecutive copies of an el-
     ement in a
	(C++20) 	      range
			      (niebloid)

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

home | help