[alg.set.operations]

# 26 Algorithms library [[algorithms]](./#algorithms)

## 26.8 Sorting and related operations [[alg.sorting]](alg.sorting#alg.set.operations)

### 26.8.7 Set operations on sorted structures [alg.set.operations]

#### [26.8.7.1](#general) General [[alg.set.operations.general]](alg.set.operations.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10265)

Subclause [alg.set.operations] defines all the basic set operations on sorted structures[.](#general-1.sentence-1)

They also work with multisets ([[multiset]](multiset "23.4.7 Class template multiset"))
containing multiple copies of equivalent elements[.](#general-1.sentence-2)

The semantics of the set operations are generalized to multisets
in a standard way by defining set_union to contain the maximum number of occurrences of every element,set_intersection to contain the minimum, and so on[.](#general-1.sentence-3)

#### [26.8.7.2](#includes) includes [[includes]](includes)

[ð](#lib:includes)

`template<class InputIterator1, class InputIterator2>
  constexpr bool includes(InputIterator1 first1, InputIterator1 last1,
                          InputIterator2 first2, InputIterator2 last2);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
  bool includes(ExecutionPolicy&& exec,
                ForwardIterator1 first1, ForwardIterator1 last1,
                ForwardIterator2 first2, ForwardIterator2 last2);

template<class InputIterator1, class InputIterator2, class Compare>
  constexpr bool includes(InputIterator1 first1, InputIterator1 last1,
                          InputIterator2 first2, InputIterator2 last2,
                          Compare comp);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare>
  bool includes(ExecutionPolicy&& exec,
                ForwardIterator1 first1, ForwardIterator1 last1,
                ForwardIterator2 first2, ForwardIterator2 last2,
                Compare comp);

template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I1, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I1> S1, [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I2> S2,
         class Proj1 = identity, class Proj2 = identity,
         [indirect_strict_weak_order](indirectcallable.indirectinvocable#concept:indirect_strict_weak_order "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<projected<I1, Proj1>,
                                    projected<I2, Proj2>> Comp = ranges::less>
  constexpr bool ranges::includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {},
                                  Proj1 proj1 = {}, Proj2 proj2 = {});
template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R1, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R2, class Proj1 = identity,
         class Proj2 = identity,
         [indirect_strict_weak_order](indirectcallable.indirectinvocable#concept:indirect_strict_weak_order "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<projected<iterator_t<R1>, Proj1>,
                                    projected<iterator_t<R2>, Proj2>> Comp = ranges::less>
  constexpr bool ranges::includes(R1&& r1, R2&& r2, Comp comp = {},
                                  Proj1 proj1 = {}, Proj2 proj2 = {});

template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I1, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I1> S1,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I2> S2,
         class Proj1 = identity, class Proj2 = identity,
         [indirect_strict_weak_order](indirectcallable.indirectinvocable#concept:indirect_strict_weak_order "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<projected<I1, Proj1>, projected<I2, Proj2>> Comp =
           ranges::less>
  bool ranges::includes(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2,
                        Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R1, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R2,
         class Proj1 = identity, class Proj2 = identity,
         [indirect_strict_weak_order](indirectcallable.indirectinvocable#concept:indirect_strict_weak_order "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<projected<iterator_t<R1>, Proj1>,
                                     projected<iterator_t<R2>, Proj2>> Comp = ranges::less>
  bool ranges::includes(Ep&& exec, R1&& r1, R2&& r2,
                        Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
`

[1](#includes-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10325)

Let comp be less{},proj1 be identity{}, andproj2 be identity{},
for the overloads with no parameters by those names[.](#includes-1.sentence-1)

[2](#includes-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10331)

*Preconditions*: The ranges [first1, last1) and [first2, last2) are sorted
with respect to comp and proj1 or proj2, respectively[.](#includes-2.sentence-1)

[3](#includes-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10336)

*Returns*: true if and only if [first2, last2) is a subsequence of [first1, last1)[.](#includes-3.sentence-1)

[*Note [1](#includes-note-1)*:

A sequence S is a subsequence of another sequence T if S can be obtained
from T by removing some, all, or none of T's elements and keeping the
remaining elements in the same order[.](#includes-3.sentence-2)

â *end note*]

[4](#includes-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10346)

*Complexity*: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons and applications of each projection[.](#includes-4.sentence-1)

#### [26.8.7.3](#set.union) set_union [[set.union]](set.union)

[ð](#lib:set_union)

`template<class InputIterator1, class InputIterator2, class OutputIterator>
  constexpr OutputIterator
    set_union(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, InputIterator2 last2,
              OutputIterator result);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
         class ForwardIterator>
  ForwardIterator
    set_union(ExecutionPolicy&& exec,
              ForwardIterator1 first1, ForwardIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2,
              ForwardIterator result);

template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
  constexpr OutputIterator
    set_union(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, InputIterator2 last2,
              OutputIterator result, Compare comp);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
         class ForwardIterator, class Compare>
  ForwardIterator
    set_union(ExecutionPolicy&& exec,
              ForwardIterator1 first1, ForwardIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2,
              ForwardIterator result, Compare comp);

template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I1, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I1> S1, [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I2> S2,
         [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
  constexpr ranges::set_union_result<I1, I2, O>
    ranges::set_union(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {},
                      Proj1 proj1 = {}, Proj2 proj2 = {});
template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R1, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R2, [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O,
         class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
  constexpr ranges::set_union_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
    ranges::set_union(R1&& r1, R2&& r2, O result, Comp comp = {},
                      Proj1 proj1 = {}, Proj2 proj2 = {});

template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I1, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I1> S1,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I2> S2,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") O, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<O> OutS, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
  ranges::set_union_result<I1, I2, O>
    ranges::set_union(Ep&& exec, I1 first1, S1 last1,
                      I2 first2, S2 last2, O result, OutS result_last,
                      Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R1, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R2,
         [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") OutR, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, iterator_t<OutR>, Comp, Proj1, Proj2>
  ranges::set_union_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>,
                           borrowed_iterator_t<OutR>>
    ranges::set_union(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {},
                      Proj1 proj1 = {}, Proj2 proj2 = {});
`

[1](#set.union-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10416)

Let:

- [(1.1)](#set.union-1.1)

comp be less{},
 and proj1 and proj2 be identity{} for the overloads with no parameters by those names;

- [(1.2)](#set.union-1.2)

M be last1 - first1 plus the number of elements in [first2, last2)
 that are not present in [first1, last1);

- [(1.3)](#set.union-1.3)

result_last be result + M for the overloads with no parameter result_last or result_r;

- [(1.4)](#set.union-1.4)

N be min(M, result_last - result)[.](#set.union-1.sentence-1)

[2](#set.union-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10433)

*Preconditions*: The ranges [first1, last1) and [first2, last2) are sorted
with respect to comp and proj1 or proj2, respectively[.](#set.union-2.sentence-1)

The resulting range does not overlap with either of the original ranges[.](#set.union-2.sentence-2)

[3](#set.union-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10439)

*Effects*: Constructs a sorted union of N elements from the two ranges;
that is, the set of elements that are present in one or both of the ranges[.](#set.union-3.sentence-1)

[4](#set.union-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10444)

*Returns*: 

- [(4.1)](#set.union-4.1)

  result_last for the overloads in namespace std[.](#set.union-4.1.sentence-1)

- [(4.2)](#set.union-4.2)

  {last1, last2, result + N} for the overloads in namespace ranges,
 if N is equal to M[.](#set.union-4.2.sentence-1)

- [(4.3)](#set.union-4.3)

  Otherwise, {j1, j2, result_last} for the overloads in namespace ranges,
 where the iterators j1 and j2 point to positions past the last copied or skipped elements
 in [first1, last1) and [first2, last2), respectively[.](#set.union-4.3.sentence-1)

[5](#set.union-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10462)

*Complexity*: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons and applications of each projection[.](#set.union-5.sentence-1)

[6](#set.union-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10467)

*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8 Requirements for stable algorithms"))[.](#set.union-6.sentence-1)

If [first1, last1) contains m elements
that are equivalent to each other and
[first2, last2) contains n elements
that are equivalent to them,
then all m elements from the first range
are copied to the output range, in order, and
then the final max(nâm,0) elements from the second range
are copied to the output range, in order[.](#set.union-6.sentence-2)

#### [26.8.7.4](#set.intersection) set_intersection [[set.intersection]](set.intersection)

[ð](#lib:set_intersection)

`template<class InputIterator1, class InputIterator2,
         class OutputIterator>
  constexpr OutputIterator
    set_intersection(InputIterator1 first1, InputIterator1 last1,
                     InputIterator2 first2, InputIterator2 last2,
                     OutputIterator result);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
         class ForwardIterator>
  ForwardIterator
    set_intersection(ExecutionPolicy&& exec,
                     ForwardIterator1 first1, ForwardIterator1 last1,
                     ForwardIterator2 first2, ForwardIterator2 last2,
                     ForwardIterator result);

template<class InputIterator1, class InputIterator2,
         class OutputIterator, class Compare>
  constexpr OutputIterator
    set_intersection(InputIterator1 first1, InputIterator1 last1,
                     InputIterator2 first2, InputIterator2 last2,
                     OutputIterator result, Compare comp);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
         class ForwardIterator, class Compare>
  ForwardIterator
    set_intersection(ExecutionPolicy&& exec,
                     ForwardIterator1 first1, ForwardIterator1 last1,
                     ForwardIterator2 first2, ForwardIterator2 last2,
                     ForwardIterator result, Compare comp);

template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I1, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I1> S1, [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I2> S2,
         [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
  constexpr ranges::set_intersection_result<I1, I2, O>
    ranges::set_intersection(I1 first1, S1 last1, I2 first2, S2 last2, O result,
                             Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R1, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R2, [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O,
         class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
  constexpr ranges::set_intersection_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
    ranges::set_intersection(R1&& r1, R2&& r2, O result,
                             Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});

template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I1, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I1> S1,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I2> S2,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") O, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<O> OutS, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
  ranges::set_intersection_result<I1, I2, O>
    ranges::set_intersection(Ep&& exec, I1 first1, S1 last1,
                      I2 first2, S2 last2, O result, OutS result_last,
                      Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R1, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R2,
         [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") OutR, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, iterator_t<OutR>, Comp, Proj1, Proj2>
  ranges::set_intersection_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>,
                                  borrowed_iterator_t<OutR>>
    ranges::set_intersection(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {},
                             Proj1 proj1 = {}, Proj2 proj2 = {});
`

[1](#set.intersection-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10546)

Let:

- [(1.1)](#set.intersection-1.1)

comp be less{},
 and proj1 and proj2 be identity{} for the overloads with no parameters by those names;

- [(1.2)](#set.intersection-1.2)

M be the number of elements in [first1, last1)
 that are present in [first2, last2);

- [(1.3)](#set.intersection-1.3)

result_last be result + M for the overloads with no parameter result_last or result_r;

- [(1.4)](#set.intersection-1.4)

N be min(M, result_last - result)[.](#set.intersection-1.sentence-1)

[2](#set.intersection-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10563)

*Preconditions*: The ranges [first1, last1) and [first2, last2) are sorted
with respect to comp and proj1 or proj2, respectively[.](#set.intersection-2.sentence-1)

The resulting range does not overlap with either of the original ranges[.](#set.intersection-2.sentence-2)

[3](#set.intersection-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10569)

*Effects*: Constructs a sorted intersection of N elements from the two ranges;
that is, the set of elements that are present in both of the ranges[.](#set.intersection-3.sentence-1)

[4](#set.intersection-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10574)

*Returns*: 

- [(4.1)](#set.intersection-4.1)

  result_last for the overloads in namespace std[.](#set.intersection-4.1.sentence-1)

- [(4.2)](#set.intersection-4.2)

  {last1, last2, result + N} for the overloads in namespace ranges,
 if N is equal to M[.](#set.intersection-4.2.sentence-1)

- [(4.3)](#set.intersection-4.3)

  Otherwise, {j1, j2, result_last} for the overloads in namespace ranges,
 where the iterators j1 and j2 point to positions past the last copied or skipped elements
 in [first1, last1) and [first2, last2), respectively[.](#set.intersection-4.3.sentence-1)

[5](#set.intersection-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10592)

*Complexity*: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons and applications of each projection[.](#set.intersection-5.sentence-1)

[6](#set.intersection-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10597)

*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8 Requirements for stable algorithms"))[.](#set.intersection-6.sentence-1)

If [first1, last1) contains m elements
that are equivalent to each other and
[first2, last2) contains n elements
that are equivalent to them,
the first min(m,n) elements
are copied from the first range to the output range, in order[.](#set.intersection-6.sentence-2)

#### [26.8.7.5](#set.difference) set_difference [[set.difference]](set.difference)

[ð](#lib:set_difference)

`template<class InputIterator1, class InputIterator2,
         class OutputIterator>
  constexpr OutputIterator
    set_difference(InputIterator1 first1, InputIterator1 last1,
                   InputIterator2 first2, InputIterator2 last2,
                   OutputIterator result);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
         class ForwardIterator>
  ForwardIterator
    set_difference(ExecutionPolicy&& exec,
                   ForwardIterator1 first1, ForwardIterator1 last1,
                   ForwardIterator2 first2, ForwardIterator2 last2,
                   ForwardIterator result);

template<class InputIterator1, class InputIterator2,
         class OutputIterator, class Compare>
  constexpr OutputIterator
    set_difference(InputIterator1 first1, InputIterator1 last1,
                   InputIterator2 first2, InputIterator2 last2,
                   OutputIterator result, Compare comp);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
         class ForwardIterator, class Compare>
  ForwardIterator
    set_difference(ExecutionPolicy&& exec,
                   ForwardIterator1 first1, ForwardIterator1 last1,
                   ForwardIterator2 first2, ForwardIterator2 last2,
                   ForwardIterator result, Compare comp);

template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I1, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I1> S1, [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I2> S2,
         [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
  constexpr ranges::set_difference_result<I1, O>
    ranges::set_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result,
                           Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R1, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R2, [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O,
         class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
  constexpr ranges::set_difference_result<borrowed_iterator_t<R1>, O>
    ranges::set_difference(R1&& r1, R2&& r2, O result,
                           Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});

template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I1, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I1> S1,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I2> S2,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") O, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<O> OutS, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
  ranges::set_difference_result<I1, O>
    ranges::set_difference(Ep&& exec, I1 first1, S1 last1,
                           I2 first2, S2 last2, O result, OutS result_last,
                           Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R1, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R2,
         [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") OutR, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, iterator_t<OutR>, Comp, Proj1, Proj2>
  ranges::set_difference_result<borrowed_iterator_t<R1>, borrowed_iterator_t<OutR>>
    ranges::set_difference(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r, Comp comp = {},
                           Proj1 proj1 = {}, Proj2 proj2 = {});
`

[1](#set.difference-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10673)

Let:

- [(1.1)](#set.difference-1.1)

comp be less{},
 and proj1 and proj2 be identity{} for the overloads with no parameters by those names;

- [(1.2)](#set.difference-1.2)

M be the number of elements in [first1, last1)
 that are not present in [first2, last2);

- [(1.3)](#set.difference-1.3)

result_last be result + M for the overloads with no parameter result_last or result_r;

- [(1.4)](#set.difference-1.4)

N be min(M, result_last - result)[.](#set.difference-1.sentence-1)

[2](#set.difference-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10690)

*Preconditions*: The ranges [first1, last1) and [first2, last2) are sorted
with respect to comp and proj1 or proj2, respectively[.](#set.difference-2.sentence-1)

The resulting range does not overlap with either of the original ranges[.](#set.difference-2.sentence-2)

[3](#set.difference-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10696)

*Effects*: Copies N elements of the range [first1, last1)
which are not present in the range [first2, last2)
to the range [result, result + N)[.](#set.difference-3.sentence-1)

The elements in the constructed range are sorted[.](#set.difference-3.sentence-2)

[4](#set.difference-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10703)

*Returns*: 

- [(4.1)](#set.difference-4.1)

  result_last for the overloads in namespace std[.](#set.difference-4.1.sentence-1)

- [(4.2)](#set.difference-4.2)

  {last1, result + N} for the overloads in namespace ranges,
 if N is equal to M[.](#set.difference-4.2.sentence-1)

- [(4.3)](#set.difference-4.3)

  Otherwise, {j1, result_last} for the overloads in namespace ranges,
 where the iterator j1 points to positions past the last copied or skipped elements
 in [first1, last1) and [first2, last2), respectively[.](#set.difference-4.3.sentence-1)

[5](#set.difference-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10721)

*Complexity*: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons and applications of each projection[.](#set.difference-5.sentence-1)

[6](#set.difference-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10726)

*Remarks*: If [first1, last1) contains m elements
that are equivalent to each other and
[first2, last2) contains n elements
that are equivalent to them,
the last max(mân,0) elements from [first1, last1)
are copied to the output range, in order[.](#set.difference-6.sentence-1)

#### [26.8.7.6](#set.symmetric.difference) set_symmetric_difference [[set.symmetric.difference]](set.symmetric.difference)

[ð](#lib:set_symmetric_difference)

`template<class InputIterator1, class InputIterator2,
         class OutputIterator>
  constexpr OutputIterator
    set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             OutputIterator result);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
         class ForwardIterator>
  ForwardIterator
    set_symmetric_difference(ExecutionPolicy&& exec,
                             ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2, ForwardIterator2 last2,
                             ForwardIterator result);

template<class InputIterator1, class InputIterator2,
         class OutputIterator, class Compare>
  constexpr OutputIterator
    set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             OutputIterator result, Compare comp);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
         class ForwardIterator, class Compare>
  ForwardIterator
    set_symmetric_difference(ExecutionPolicy&& exec,
                             ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2, ForwardIterator2 last2,
                             ForwardIterator result, Compare comp);

template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I1, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I1> S1, [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]")<I2> S2,
         [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
  constexpr ranges::set_symmetric_difference_result<I1, I2, O>
    ranges::set_symmetric_difference(I1 first1, S1 last1, I2 first2, S2 last2, O result,
                                     Comp comp = {}, Proj1 proj1 = {},
                                     Proj2 proj2 = {});
template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R1, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R2, [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O,
         class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
  constexpr ranges::set_symmetric_difference_result<borrowed_iterator_t<R1>,
                                                    borrowed_iterator_t<R2>, O>
    ranges::set_symmetric_difference(R1&& r1, R2&& r2, O result, Comp comp = {},
                                     Proj1 proj1 = {}, Proj2 proj2 = {});

template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I1, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I1> S1,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<I2> S2,
         [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") O, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<O> OutS, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
  ranges::set_symmetric_difference_result<I1, I2, O>
    ranges::set_symmetric_difference(Ep&& exec, I1 first1, S1 last1,
                                     I2 first2, S2 last2, O result, OutS result_last,
                                     Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R1, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R2,
         [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") OutR, class Comp = ranges::less,
         class Proj1 = identity, class Proj2 = identity>
  requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7 Concept mergeable [alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, iterator_t<OutR>, Comp, Proj1, Proj2>
  ranges::set_symmetric_difference_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>,
                                  borrowed_iterator_t<OutR>>
    ranges::set_symmetric_difference(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r,
                                     Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
`

[1](#set.symmetric.difference-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10804)

Let:

- [(1.1)](#set.symmetric.difference-1.1)

  comp be less{},
 and proj1 and proj2 be identity{} for the overloads with no parameters by those names;

- [(1.2)](#set.symmetric.difference-1.2)

  K be the number of elements in [first1, last1) that are not present in [first2, last2)[.](#set.symmetric.difference-1.2.sentence-1)

- [(1.3)](#set.symmetric.difference-1.3)

  M be the number of elements in [first2, last2) that are not present in [first1, last1)[.](#set.symmetric.difference-1.3.sentence-1)

- [(1.4)](#set.symmetric.difference-1.4)

  result_last be result + M + K for the overloads with no parameter result_last or result_r;

- [(1.5)](#set.symmetric.difference-1.5)

  N be min(K+M,Â result_last - result)[.](#set.symmetric.difference-1.5.sentence-1)

[2](#set.symmetric.difference-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10822)

*Preconditions*: The ranges [first1, last1) and [first2, last2) are sorted
with respect to comp and proj1 or proj2, respectively[.](#set.symmetric.difference-2.sentence-1)

The resulting range does not overlap with either of the original ranges[.](#set.symmetric.difference-2.sentence-2)

[3](#set.symmetric.difference-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10828)

*Effects*: Copies the elements of the range [first1, last1)
that are not present in the range [first2, last2),
and the elements of the range [first2, last2)
that are not present in the range [first1, last1)
to the range [result, result + N)[.](#set.symmetric.difference-3.sentence-1)

The elements in the constructed range are sorted[.](#set.symmetric.difference-3.sentence-2)

[4](#set.symmetric.difference-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10837)

*Returns*: 

- [(4.1)](#set.symmetric.difference-4.1)

  result_last for the overloads in namespace std[.](#set.symmetric.difference-4.1.sentence-1)

- [(4.2)](#set.symmetric.difference-4.2)

  {last1, last2, result + N} for the overloads in namespace ranges,
 if N is equal to M+K[.](#set.symmetric.difference-4.2.sentence-1)

- [(4.3)](#set.symmetric.difference-4.3)

  Otherwise, {j1, j2, result_last} for the overloads in namespace ranges,
 where the iterators j1 and j2 point to positions past the last copied or skipped elements
 in [first1, last1) and [first2, last2), respectively[.](#set.symmetric.difference-4.3.sentence-1)

[5](#set.symmetric.difference-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10855)

*Complexity*: At most 2 * ((last1 - first1) + (last2 - first2)) - 1 comparisons and applications of each projection[.](#set.symmetric.difference-5.sentence-1)

[6](#set.symmetric.difference-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10860)

*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8 Requirements for stable algorithms"))[.](#set.symmetric.difference-6.sentence-1)

If [first1, last1) contains m elements
that are equivalent to each other and
[first2, last2) contains n elements
that are equivalent to them,
then |mân| of those elements shall be copied to the output range:
the last mân of these elements from [first1, last1) if m>n, and
the last nâm of these elements from [first2, last2) if m<n[.](#set.symmetric.difference-6.sentence-2)

In either case, the elements are copied in order[.](#set.symmetric.difference-6.sentence-3)
