[set.union]

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

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

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

#### 26.8.7.3 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](#1)

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

Let:

- [(1.1)](#1.1)

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

- [(1.2)](#1.2)

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

- [(1.3)](#1.3)

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

- [(1.4)](#1.4)

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

[2](#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[.](#2.sentence-1)

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

[3](#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[.](#3.sentence-1)

[4](#4)

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

*Returns*: 

- [(4.1)](#4.1)

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

- [(4.2)](#4.2)

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

- [(4.3)](#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[.](#4.3.sentence-1)

[5](#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[.](#5.sentence-1)

[6](#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"))[.](#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[.](#6.sentence-2)
