Title
`unique_copy` passes arguments to its predicate backwards
Status
new
Section
[alg.unique]
Submitter
Jonathan Wakely

Created on 2025-05-29.00:00:00 last changed 3 days ago

Messages

Date: 2025-05-29.16:57:38

Proposed resolution:

This wording is relative to N5008.

  1. Modify [alg.unique] as indicated:

    6. Let `pred` be `equal_to{}` for the overloads with no parameter `pred`, and let E be
    1. (6.1) — bool(pred(*i, *(i - 1)), *i) for the overloads in namespace `std`;
    2. (6.2) — bool(invoke(comp, invoke(proj, *i), invoke(proj, *(i - 1)), invoke(proj, *i))) for the overloads in namespace `ranges`.
Date: 2025-05-29.00:00:00

For the `unique` algorithms, [alg.unique] p1 says:

1. Let `pred` be `equal_to{}` for the overloads with no parameter `pred`, and let E be
  1. (1.1) — `bool(pred(*(i - 1), *i))` for the overloads in namespace `std`;
  2. (1.2) — `bool(invoke(comp, invoke(proj, *(i - 1)), invoke(proj, *i)))` for the overloads in namespace `ranges`.

However for the `unique_copy` algorithms, [alg.unique] p6 says that the arguments `*i` and `*(i-1)` should be reversed:

6. Let `pred` be `equal_to{}` for the overloads with no parameter `pred`, and let E be
  1. (6.1) — `bool(pred(*i, *(i - 1)))` for the overloads in namespace `std`;
  2. (6.2) — `bool(invoke(comp, invoke(proj, *i), invoke(proj, *(i - 1))))` for the overloads in namespace `ranges`.

This reversed order is consistent with the documentation for SGI STL `unique_copy`, although the docs for SGI STL `unique` show reversed arguments too, and the C++ standard doesn't match that.

A survey of known implementations shows that all three of libstdc++, libc++, and MSVC STL use the `pred(*(i - 1), *i)` order for all of `std::unique`, `std::unique_copy`, `ranges::unique`, and `ranges::unique_copy`. The range-v3 library did the same, and even the SGI STL did too (despite what its docs said). Only two implementations were found which match the spec and use a different argument order for `unique` and `unique_copy`, Casey Carter's (cmcstl2) and Fraser Gordon's.

In the absence of any known rationale for `unique` and `unique_copy` to differ, it seems sensible to make `unique_copy` more consistent with `unique` (and with the majority of implementations stretching back three decades).

History
Date User Action Args
2025-05-29 16:57:38adminsetmessages: + msg14773
2025-05-29 00:00:00admincreate