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

FreeBSD Manual Pages

  
 
  

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

NAME
       std::set_difference - std::set_difference

Synopsis
	  Defined in header <algorithm>
	  template< class InputIt1, class InputIt2, class
	  OutputIt >

	  OutputIt   set_difference(  InputIt1	first1,			(until
       C++20)
	  InputIt1 last1,
	  InputIt2 first2, InputIt2 last2,

	  OutputIt d_first );
	  template< class InputIt1, class InputIt2, class
	  OutputIt >

	  constexpr  OutputIt  set_difference(	InputIt1		(since
       C++20)
	  first1, InputIt1 last1,
	  InputIt2 first2, InputIt2 last2,

	  OutputIt d_first );
	  template< class ExecutionPolicy, class
	  ForwardIt1, class ForwardIt2,

	  class	ForwardIt3 >
	  ForwardIt3   set_difference(	ExecutionPolicy&&	   (2)	(since
       C++17)
	  policy,
	  ForwardIt1 first1, ForwardIt1	last1,
	  ForwardIt2 first2, ForwardIt2	last2,

	  ForwardIt3 d_first );				   (1)
	  template< class InputIt1, class InputIt2,

	  class	OutputIt, class	Compare	>
	  OutputIt	    set_difference(	     InputIt1	       first1,
       (until C++20)
	  InputIt1 last1,
	  InputIt2 first2, InputIt2 last2,

	  OutputIt d_first, Compare comp );
	  template< class InputIt1, class InputIt2,

	  class	OutputIt, class	Compare	>
	  constexpr	     OutputIt	      set_difference(	      InputIt1
       (since C++20)
	  first1, InputIt1 last1,			       (3)
	  InputIt2 first2, InputIt2 last2,

	  OutputIt d_first, Compare comp );
	  template< class ExecutionPolicy, class
	  ForwardIt1, class ForwardIt2,

	  class	ForwardIt3, class Compare >
	  ForwardIt3   set_difference(	  ExecutionPolicy&&		   (4)
       (since C++17)
	  policy,
	  ForwardIt1 first1, ForwardIt1	last1,
	  ForwardIt2 first2, ForwardIt2	last2,

	  ForwardIt3 d_first, Compare comp );

	  Copies  the elements from the	sorted range [first1, last1) which are
       not found in the
	  sorted range [first2,	last2) to the range beginning at d_first.

	  The resulting	range is also sorted. Equivalent elements are  treated
       individually,
	  that	is,  if	some element is	found m	times in [first1, last1) and n
       times in	[first2,
	  last2), it will be copied to d_first exactly std::max(m-n, 0)	times.
       The resulting
	  range	cannot overlap with either of the input	ranges.

	  1) Elements are compared using operator<  and	 the  ranges  must  be
       sorted with respect
	  to the same.
	  3)  Elements are compared using the given binary comparison function
       comp and	the
	  ranges must be sorted	with respect to	the same.
	  2,4) Same as (1,3), but executed according to	 policy.  These	 over-
       loads do	not
	  participate in overload resolution unless
	  std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>
	  (until C++20)
	  std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>
	  (since C++20)	is true.

Parameters
	  first1, last1	- the range of elements	to examine
	  first2, last2	- the range of elements	to search for
	  d_first	- the beginning	of the destination range
	  policy	 -  the	 execution policy to use. See execution	policy
       for details.
			  comparison function object (i.e. an object that sat-
       isfies the
			  requirements of Compare) which returns true  if  the
       first argument
			  is less than (i.e. is	ordered	before)	the second.

			  The  signature  of the comparison function should be
       equivalent to the
			  following:

			  bool cmp(const Type1 &a, const Type2 &b);
	  comp		-
			  While	the signature does not need to have  const  &,
       the function must
			  not modify the objects passed	to it and must be able
       to accept all
			  values  of type (possibly const) Type1 and Type2 re-
       gardless	of value
			  category (thus, Type1	& is not allowed
			  , nor	is Type1 unless	for Type1 a move is equivalent
       to a copy
			  (since C++11)).
			  The types Type1 and Type2 must be such that  objects
       of types
			  InputIt1  and	 InputIt2 can be dereferenced and then
       implicitly
			  converted to both Type1 and Type2.

Type requirements
	  -
	  InputIt1, InputIt2 must meet the requirements	 of  LegacyInputItera-
       tor.
	  -
	  OutputIt must	meet the requirements of LegacyOutputIterator.
	  -
	  ForwardIt1, ForwardIt2, ForwardIt3 must meet the requirements	of
	  LegacyForwardIterator.

Return value
	  Iterator past	the end	of the constructed range.

Complexity
	  At most \(\scriptsize	2\cdot(N_1+N_2)-1\)2(N
	  1+N
	  2)-1 comparisons, where \(\scriptsize	N_1\)N
	  1 and	\(\scriptsize N_2\)N
	  2 are	std::distance(first1, last1) and std::distance(first2, last2),
       respectively.

Exceptions
	  The overloads	with a template	parameter named	ExecutionPolicy	report
       errors as
	  follows:

	    *  If  execution  of  a  function invoked as part of the algorithm
       throws an exception
	      and ExecutionPolicy is one of the	standard policies, std::termi-
       nate is called.
	      For any other ExecutionPolicy, the behavior  is  implementation-
       defined.
	    *  If  the	algorithm  fails to allocate memory, std::bad_alloc is
       thrown.

Possible implementation
First version
	  template<class InputIt1, class InputIt2, class OutputIt>
	  OutputIt set_difference(InputIt1 first1, InputIt1 last1,
				  InputIt2 first2, InputIt2 last2,
				  OutputIt d_first)
	  {
	      while (first1 != last1) {
		  if  (first2  ==  last2)  return   std::copy(first1,	last1,
       d_first);

		  if (*first1 <	*first2) {
		      *d_first++ = *first1++;
		  } else {
		      if (! (*first2 < *first1)) {
			  ++first1;
		      }
		      ++first2;
		  }
	      }
	      return d_first;
	  }

Second version
	  template<class InputIt1, class InputIt2,
		   class OutputIt, class Compare>
	  OutputIt set_difference( InputIt1 first1, InputIt1 last1,
				   InputIt2 first2, InputIt2 last2,
				   OutputIt d_first, Compare comp)
	  {
	      while (first1 != last1) {
		  if   (first2	 ==  last2)  return  std::copy(first1,	last1,
       d_first);

		  if (comp(*first1, *first2)) {
		      *d_first++ = *first1++;
		  } else {
		      if (!comp(*first2, *first1)) {
			  ++first1;
		      }
		      ++first2;
		  }
	      }
	      return d_first;
	  }

Example
       // Run this code

	#include <algorithm>
	#include <iostream>
	#include <iterator>
	#include <string_view>
	#include <vector>

	auto print = [](const auto& v, std::string_view	end = "") {
	    std::cout << "{ ";
	    for	(auto i	: v) std::cout << i << ' ';
	    std::cout << "} " << end;
	};

	struct Order //	a struct with some interesting data
	{
	    int	order_id;

	    friend std::ostream&  operator<<(std::ostream&  os,	 const	Order&
       ord) {
		return os << ord.order_id << ',';
	    }
	};

	int main() {
	    const std::vector<int> v1 {1, 2, 5,	5, 5, 9};
	    const std::vector<int> v2 {2, 5, 7};
	    std::vector<int> diff;

	    std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(),
				std::inserter(diff, diff.begin()));
	    print(v1, "	");
	    print(v2, "= ");
	    print(diff,	"\n");

	    // we want to know which orders "cut" between old and new states:
	    std::vector<Order> old_orders { {1}, {2}, {5}, {9} };
	    std::vector<Order> new_orders { {2}, {5}, {7} };
	    std::vector<Order> cut_orders;

	    std::set_difference(old_orders.begin(), old_orders.end(),
				new_orders.begin(), new_orders.end(),
				std::back_inserter(cut_orders),
				[](auto&  a,  auto&  b)	 { return a.order_id <
       b.order_id; });

	    std::cout << "old orders = "; print(old_orders, "\n");
	    std::cout << "new orders = "; print(new_orders, "\n");
	    std::cout << "cut orders = "; print(cut_orders, "\n");
	}

Output:
	{ 1 2 5	5 5 9 }	 { 2 5 7 } = { 1 5 5 9 }
	old orders = { 1, 2, 5,	9, }
	new orders = { 2, 5, 7,	}
	cut orders = { 1, 9, }

See also
	  includes		   returns true	if one sequence	 is  a	subse-
       quence of another
				   (function template)
	  set_symmetric_difference  computes  the symmetric difference between
       two sets
				   (function template)
	  ranges::set_difference   computes the	difference between two sets
	  (C++20)		   (niebloid)

http://cppreference.com		  2022.07.31		std::set_difference(3)

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

home | help