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).

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