C++ Logo

std-proposals

Advanced search

[std-proposals] Introduction of std::is_uniqued()

From: LoS <aurumpuro_at_[hidden]>
Date: Fri, 14 Apr 2023 17:01:51 +0200
 As suggested in a reply to my previous proposal, I drafted a proposal to
introduce the std::is_uniqued() function.

Since it was developed from Arthur's idea, I would be very happy if you
took part in the proposal.


I. Motivation

The std::is_uniqued() function can be used to check if a range of elements
has no consecutive equal elements.

Even if there is already the std::adjacent_find() function, that can be
used to get the same effect, the introduction of the function
std::is_uniqued makes the check clearer, like std::contains() and
std::is_sorted() do.


II. Impact on the standard

This proposal simply adds new standard functions into the algorithm header.
It does not require any changes in core language. It has been implemented
in standard C++.


III. Design decisions

template< class ForwardIt >
constexpr bool is_uniqued( ForwardIt first, ForwardIt last );


template< class ForwardIt , class BinaryPredicate>
constexpr bool is_uniqued( ForwardIt first, ForwardIt last, BinaryPredicate
pred );


template< class ExecutionPolicy, class ForwardIt >
bool is_uniqued( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last
);


template< class ExecutionPolicy, class ForwardIt, class BinaryPredicate>
bool is_uniqued(ExecutionPolicy policy, ForwardIt first, ForwardIt last,
BinaryPredicate pred );


Checks if the elements in the range [first, last) are unique.

A sequence is uniqued with respect to a binary predicate pred if any
iterator it pointing to the sequence and the consecutive ++it iterator
pointing to an element in the sequence, pred(*it, *(++it)) evaluates to
false.

1) elements are compared using operator==. The behavior is undefined if it
is not an equivalence relation.

2) elements are compared using the given binary predicate pred. The
behavior is undefined if it is not an equivalence relation.

3, 4) Same as (1, 2), but executed according to policy. These overloads do
not partecipate in overload resolution unless
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> is true.


Preconditions:

ForwardIt must meet the requirements of LegacyForwardIterator.


Complexity:

At most std::distance(first, last).


Exceptions:

If execution of a function invoked as part of the algorithm throws an
exception and ExecutionPolicy is one of the standard policies,
std::terminate is called. For any other ExecutionPolicy, the behavior is
implementation-defined.

If the algorithm fails to allocate memory, std::bad_alloc is thrown.


/* Ranges */

template< std::forward_iterator I, std::sentinel_for<I> S, class Proj =
std::identity, std::indirect_equivalence_relation Proj>> Pred =
ranges::equal_to >
constexpr bool is_uniqued( I first, S last, Pred pred = {}, Proj proj = {}
);

template< ranges::forward_range R, class Proj = std::identity,
std::indirect_equivalent_relation<std::projected<ranges::iterator_t<R>,
Proj>,
std::projected<ranges::iterator_t<R>, Proj> Pred = ranges::equal_to>
constexpr bool is_uniqued( R&& r, Pred pred = {}, Proj proj = {} );


1) elements are compared using the given binary predicate pred.

2) Same as (1), but uses r as the source range, as if using
ranges::begin(r) as first and ranges::end(r) as last.


Complexity:

1) At most std::distance(first, last).

2) At most ranges::distance(r).

Received on 2023-04-14 15:02:05