Skip to content

[libc++][pair] P2944R3: Constrain std::pair's equality operator #136672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2cPapers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"`P2248R8 <https://wg21.link/P2248R8>`__","Enabling list-initialization for algorithms","2024-03 (Tokyo)","","",""
"`P2810R4 <https://wg21.link/P2810R4>`__","``is_debugger_present`` ``is_replaceable``","2024-03 (Tokyo)","","",""
"`P1068R11 <https://wg21.link/P1068R11>`__","Vector API for random number generation","2024-03 (Tokyo)","","",""
"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","19","Implemented comparisons for ``reference_wrapper`` only"
"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","Implemented changes to ``reference_wrapper`` and ``pair``"
"`P2642R6 <https://wg21.link/P2642R6>`__","Padded ``mdspan`` layouts","2024-03 (Tokyo)","","",""
"`P3029R1 <https://wg21.link/P3029R1>`__","Better ``mdspan``'s CTAD","2024-03 (Tokyo)","|Complete|","19",""
"","","","","",""
Expand Down
10 changes: 9 additions & 1 deletion libcxx/include/__utility/pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <__compare/common_comparison_category.h>
#include <__compare/synth_three_way.h>
#include <__concepts/boolean_testable.h>
#include <__concepts/different_from.h>
#include <__config>
#include <__cstddef/size_t.h>
Expand Down Expand Up @@ -461,7 +462,14 @@ pair(_T1, _T2) -> pair<_T1, _T2>;

template <class _T1, class _T2, class _U1, class _U2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y)
#if _LIBCPP_STD_VER >= 26
requires requires {
{ __x.first == __y.first } -> __boolean_testable;
{ __x.second == __y.second } -> __boolean_testable;
}
Comment on lines +467 to +470
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have the same situation as in #135759? (that __boolean_testable might be too strict)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard requirements are inconsistent among these new constraints. boolean-testable is used for pair and tuple's operator==s (perhaps due to boolean-testable in old Preconditions added by P2167R3), while plain implicit convertibility is used elsewhere.

I guess the difference was because of that && (and possibly ||?) is expected to be used in pair and tuple's operator==s, but not in other mentioned operators.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @frederick-vs-ja pointed out these are described as __boolean_testable in the standard so I prefer to keep them as such for consistency with the Standard but I'll update the reference_wrapper with the proposed concept in #135759 later.

#endif
{
return __x.first == __y.first && __x.second == __y.second;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,35 @@

#include <utility>
#include <cassert>
#include <concepts>

#include "test_macros.h"

#if TEST_STD_VER >= 26

// Test SFINAE.

struct EqualityComparable {
constexpr EqualityComparable(int value) : value_{value} {};

friend constexpr bool operator==(const EqualityComparable&, const EqualityComparable&) noexcept = default;

int value_;
};

static_assert(std::equality_comparable<EqualityComparable>);

static_assert(std::equality_comparable<std::pair<EqualityComparable, EqualityComparable>>);

struct NonComparable {};

static_assert(!std::equality_comparable<NonComparable>);

static_assert(!std::equality_comparable<std::pair<EqualityComparable, NonComparable>>);
static_assert(!std::equality_comparable<std::pair<NonComparable, EqualityComparable>>);

#endif // TEST_STD_VER >= 26

int main(int, char**)
{
{
Expand Down
Loading