27 Algorithms library [algorithms]

27.7 Mutating sequence operations [alg.modifying.operations]

27.7.9 Unique [alg.unique]

template<class ForwardIterator> constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); template<class ExecutionPolicy, class ForwardIterator> ForwardIterator unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); template<class ForwardIterator, class BinaryPredicate> constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator, class BinaryPredicate> ForwardIterator unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred); template<permutable I, sentinel_­for<I> S, class Proj = identity, indirect_­equivalence_­relation<projected<I, Proj>> C = ranges::equal_to> constexpr subrange<I> ranges::unique(I first, S last, C comp = {}, Proj proj = {}); template<forward_­range R, class Proj = identity, indirect_­equivalence_­relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to> requires permutable<iterator_t<R>> constexpr borrowed_subrange_t<R> ranges::unique(R&& r, C comp = {}, Proj proj = {});
Let pred be equal_­to{} for the overloads with no parameter pred, and let E be
  • bool(pred(*(i - 1), *i)) for the overloads in namespace std;
  • bool(invoke(comp, invoke(proj, *(i - 1)), invoke(proj, *i))) for the overloads in namespace ranges.
Preconditions: For the overloads in namepace std, pred is an equivalence relation and the type of *first meets the Cpp17MoveAssignable requirements (Table 34).
Effects: For a nonempty range, eliminates all but the first element from every consecutive group of equivalent elements referred to by the iterator i in the range [first + 1, last) for which E is true.
Returns: Let j be the end of the resulting range.
Returns:
  • j for the overloads in namespace std.
  • {j, last} for the overloads in namespace ranges.
Complexity: For nonempty ranges, exactly (last - first) - 1 applications of the corresponding predicate and no more than twice as many applications of any projection.
template<class InputIterator, class OutputIterator> constexpr OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> ForwardIterator2 unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); template<class InputIterator, class OutputIterator, class BinaryPredicate> constexpr OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred); template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator2 unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred); template<input_­iterator I, sentinel_­for<I> S, weakly_­incrementable O, class Proj = identity, indirect_­equivalence_­relation<projected<I, Proj>> C = ranges::equal_to> requires indirectly_­copyable<I, O> && (forward_­iterator<I> || (input_­iterator<O> && same_­as<iter_value_t<I>, iter_value_t<O>>) || indirectly_­copyable_­storable<I, O>) constexpr ranges::unique_copy_result<I, O> ranges::unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); template<input_­range R, weakly_­incrementable O, class Proj = identity, indirect_­equivalence_­relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to> requires indirectly_­copyable<iterator_t<R>, O> && (forward_­iterator<iterator_t<R>> || (input_­iterator<O> && same_­as<range_value_t<R>, iter_value_t<O>>) || indirectly_­copyable_­storable<iterator_t<R>, O>) constexpr ranges::unique_copy_result<borrowed_iterator_t<R>, O> ranges::unique_copy(R&& r, O result, C comp = {}, Proj proj = {});
Let pred be equal_­to{} for the overloads in namespace std with no parameter pred, and let E be
  • bool(pred(*i, *(i - 1))) for the overloads in namespace std;
  • bool(invoke(comp, invoke(proj, *i), invoke(proj, *(i - 1)))) for the overloads in namespace ranges.
Mandates: *first is writable ([iterator.requirements.general]) to result.
Preconditions:
  • The ranges [first, last) and [result, result+(last-first)) do not overlap.
  • For the overloads in namespace std:
    • The comparison function is an equivalence relation.
    • For the overloads with no ExecutionPolicy, let T be the value type of InputIterator.
      If InputIterator models forward_­iterator ([iterator.concept.forward]), then there are no additional requirements for T.
      Otherwise, if OutputIterator meets the Cpp17ForwardIterator requirements and its value type is the same as T, then T meets the Cpp17CopyAssignable (Table 35) requirements.
      Otherwise, T meets both the Cpp17CopyConstructible (Table 33) and Cpp17CopyAssignable requirements.
      [Note 1:
      For the overloads with an ExecutionPolicy, there might be a performance cost if the value type of ForwardIterator1 does not meet both the Cpp17CopyConstructible and Cpp17CopyAssignable requirements.
      — end note]
Effects: Copies only the first element from every consecutive group of equal elements referred to by the iterator i in the range [first, last) for which E holds.
Returns:
  • result + N for the overloads in namespace std.
  • {last, result + N} for the overloads in namespace ranges.
Complexity: Exactly last - first - 1 applications of the corresponding predicate and no more than twice as many applications of any projection.