Skip to content

[libc++] P2944R3: Constrained comparisons - update reference_wrapper implementation #139368

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 15 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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|","","Implemented changes to ``reference_wrapper`` and ``pair``"
"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","Not implemented ``tuple`` and ``variant``"
"`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
8 changes: 4 additions & 4 deletions libcxx/include/__functional/reference_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H

#include <__compare/synth_three_way.h>
#include <__concepts/boolean_testable.h>
#include <__config>
#include <__functional/weak_result_type.h>
#include <__memory/addressof.h>
#include <__type_traits/desugars_to.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/invoke.h>
#include <__type_traits/is_const.h>
#include <__type_traits/is_core_convertible.h>
#include <__type_traits/remove_cvref.h>
#include <__type_traits/void_t.h>
#include <__utility/declval.h>
Expand Down Expand Up @@ -75,23 +75,23 @@ class reference_wrapper : public __weak_result_type<_Tp> {

_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, reference_wrapper __y)
requires requires {
{ __x.get() == __y.get() } -> __boolean_testable;
{ __x.get() == __y.get() } -> __core_convertible_to<bool>;
}
{
return __x.get() == __y.get();
}

_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, const _Tp& __y)
requires requires {
{ __x.get() == __y } -> __boolean_testable;
{ __x.get() == __y } -> __core_convertible_to<bool>;
}
{
return __x.get() == __y;
}

_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, reference_wrapper<const _Tp> __y)
requires(!is_const_v<_Tp>) && requires {
{ __x.get() == __y.get() } -> __boolean_testable;
{ __x.get() == __y.get() } -> __core_convertible_to<bool>;
}
{
return __x.get() == __y.get();
Expand Down
6 changes: 3 additions & 3 deletions libcxx/include/version
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ __cpp_lib_constexpr_tuple 201811L <tuple>
__cpp_lib_constexpr_typeinfo 202106L <typeinfo>
__cpp_lib_constexpr_utility 201811L <utility>
__cpp_lib_constexpr_vector 201907L <vector>
__cpp_lib_constrained_equality 202403L <optional> <tuple> <utility>
<variant>
__cpp_lib_constrained_equality 202411L <expected> <optional> <tuple>
<utility> <variant>
__cpp_lib_containers_ranges 202202L <deque> <forward_list> <list>
<map> <queue> <set>
<stack> <string> <unordered_map>
Expand Down Expand Up @@ -545,7 +545,7 @@ __cpp_lib_void_t 201411L <type_traits>
# if !defined(_LIBCPP_ABI_VCRUNTIME)
# define __cpp_lib_constexpr_new 202406L
# endif
// # define __cpp_lib_constrained_equality 202403L
// # define __cpp_lib_constrained_equality 202411L
// # define __cpp_lib_copyable_function 202306L
// # define __cpp_lib_debugging 202311L
// # define __cpp_lib_default_template_type_for_algorithm_values 202403L
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ constexpr std::size_t N{1};
static_assert(std::three_way_comparable<std::array<int, N>>);

// Thanks to SFINAE, the following is not a compiler error but returns `false`
struct NonComparable {};
static_assert(!std::three_way_comparable<std::array<NonComparable, N>>);

// Implementation detail of `test_sequence_container_array_spaceship`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

#if TEST_STD_VER < 14

# ifdef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should not be defined before c++26"
# endif

# ifdef __cpp_lib_expected
# error "__cpp_lib_expected should not be defined before c++23"
# endif
Expand All @@ -30,6 +34,10 @@

#elif TEST_STD_VER == 14

# ifdef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should not be defined before c++26"
# endif

# ifdef __cpp_lib_expected
# error "__cpp_lib_expected should not be defined before c++23"
# endif
Expand All @@ -40,6 +48,10 @@

#elif TEST_STD_VER == 17

# ifdef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should not be defined before c++26"
# endif

# ifdef __cpp_lib_expected
# error "__cpp_lib_expected should not be defined before c++23"
# endif
Expand All @@ -50,6 +62,10 @@

#elif TEST_STD_VER == 20

# ifdef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should not be defined before c++26"
# endif

# ifdef __cpp_lib_expected
# error "__cpp_lib_expected should not be defined before c++23"
# endif
Expand All @@ -60,6 +76,10 @@

#elif TEST_STD_VER == 23

# ifdef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should not be defined before c++26"
# endif

# ifndef __cpp_lib_expected
# error "__cpp_lib_expected should be defined in c++23"
# endif
Expand All @@ -73,6 +93,19 @@

#elif TEST_STD_VER > 23

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should be defined in c++26"
# endif
# if __cpp_lib_constrained_equality != 202411L
# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# else
# ifdef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!"
# endif
# endif

# ifndef __cpp_lib_expected
# error "__cpp_lib_expected should be defined in c++26"
# endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@
# ifndef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should be defined in c++26"
# endif
# if __cpp_lib_constrained_equality != 202403L
# error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
# if __cpp_lib_constrained_equality != 202411L
# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# else
# ifdef __cpp_lib_constrained_equality
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@
# ifndef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should be defined in c++26"
# endif
# if __cpp_lib_constrained_equality != 202403L
# error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
# if __cpp_lib_constrained_equality != 202411L
# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# else
# ifdef __cpp_lib_constrained_equality
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,8 @@
# ifndef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should be defined in c++26"
# endif
# if __cpp_lib_constrained_equality != 202403L
# error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
# if __cpp_lib_constrained_equality != 202411L
# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# else
# ifdef __cpp_lib_constrained_equality
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@
# ifndef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should be defined in c++26"
# endif
# if __cpp_lib_constrained_equality != 202403L
# error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
# if __cpp_lib_constrained_equality != 202411L
# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# else
# ifdef __cpp_lib_constrained_equality
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6494,8 +6494,8 @@
# ifndef __cpp_lib_constrained_equality
# error "__cpp_lib_constrained_equality should be defined in c++26"
# endif
# if __cpp_lib_constrained_equality != 202403L
# error "__cpp_lib_constrained_equality should have the value 202403L in c++26"
# if __cpp_lib_constrained_equality != 202411L
# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# else
# ifdef __cpp_lib_constrained_equality
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
#include <type_traits>
#include <utility>

#include "test_comparisons.h"
#include "test_macros.h"
#include "../../types.h"

#if TEST_STD_VER >= 26
// https://wg21.link/P3379R0
static_assert(CanCompare<std::expected<int, int>, int>);
static_assert(CanCompare<std::expected<int, int>, EqualityComparable>);
static_assert(!CanCompare<std::expected<int, int>, NonComparable>);
static_assert(HasOperatorEqual<std::expected<int, int>, int>);
static_assert(HasOperatorEqual<std::expected<int, int>, EqualityComparable>);
static_assert(!HasOperatorEqual<std::expected<int, int>, NonComparable>);
#endif

constexpr bool test() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,26 @@
#include <type_traits>
#include <utility>

#include "test_comparisons.h"
#include "test_macros.h"
#include "../../types.h"

// Test constraint
static_assert(!CanCompare<NonComparable, NonComparable>);
static_assert(!HasOperatorEqual<NonComparable, NonComparable>);

static_assert(CanCompare<std::expected<int, int>, std::expected<int, int>>);
static_assert(CanCompare<std::expected<int, int>, std::expected<short, short>>);
static_assert(HasOperatorEqual<std::expected<int, int>, std::expected<int, int>>);
static_assert(HasOperatorEqual<std::expected<int, int>, std::expected<short, short>>);

#if TEST_STD_VER >= 26
// https://wg21.link/P3379R0
static_assert(!CanCompare<std::expected<int, int>, std::expected<void, int>>);
static_assert(CanCompare<std::expected<int, int>, std::expected<int, int>>);
static_assert(!CanCompare<std::expected<NonComparable, int>, std::expected<NonComparable, int>>);
static_assert(!CanCompare<std::expected<int, NonComparable>, std::expected<int, NonComparable>>);
static_assert(!CanCompare<std::expected<NonComparable, int>, std::expected<int, NonComparable>>);
static_assert(!CanCompare<std::expected<int, NonComparable>, std::expected<NonComparable, int>>);
static_assert(!HasOperatorEqual<std::expected<int, int>, std::expected<void, int>>);
static_assert(HasOperatorEqual<std::expected<int, int>, std::expected<int, int>>);
static_assert(!HasOperatorEqual<std::expected<NonComparable, int>, std::expected<NonComparable, int>>);
static_assert(!HasOperatorEqual<std::expected<int, NonComparable>, std::expected<int, NonComparable>>);
static_assert(!HasOperatorEqual<std::expected<NonComparable, int>, std::expected<int, NonComparable>>);
static_assert(!HasOperatorEqual<std::expected<int, NonComparable>, std::expected<NonComparable, int>>);
#else
// Note this is true because other overloads in expected<non-void> are unconstrained
static_assert(CanCompare<std::expected<void, int>, std::expected<int, int>>);
static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<int, int>>);
#endif
constexpr bool test() {
// x.has_value() && y.has_value()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
#include <type_traits>
#include <utility>

#include "test_comparisons.h"
#include "test_macros.h"
#include "../../types.h"

#if TEST_STD_VER >= 26
// https://wg21.link/P3379R0
static_assert(CanCompare<std::expected<EqualityComparable, EqualityComparable>, std::unexpected<int>>);
static_assert(CanCompare<std::expected<EqualityComparable, int>, std::unexpected<EqualityComparable>>);
static_assert(!CanCompare<std::expected<EqualityComparable, NonComparable>, std::unexpected<int>>);
static_assert(HasOperatorEqual<std::expected<EqualityComparable, EqualityComparable>, std::unexpected<int>>);
static_assert(HasOperatorEqual<std::expected<EqualityComparable, int>, std::unexpected<EqualityComparable>>);
static_assert(!HasOperatorEqual<std::expected<EqualityComparable, NonComparable>, std::unexpected<int>>);
#endif

constexpr bool test() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,26 @@
#include <type_traits>
#include <utility>

#include "test_comparisons.h"
#include "test_macros.h"
#include "../../types.h"

struct Foo{};
static_assert(!CanCompare<Foo, Foo>);
static_assert(!HasOperatorEqual<Foo, Foo>);

static_assert(CanCompare<std::expected<void, int>, std::expected<void, int>>);
static_assert(CanCompare<std::expected<void, int>, std::expected<void, short>>);
static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<void, int>>);
static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<void, short>>);

#if TEST_STD_VER >= 26
// https://wg21.link/P3379R0
static_assert(!CanCompare<std::expected<void, int>, std::expected<int, int>>);
static_assert(CanCompare<std::expected<void, int>, std::expected<void, int>>);
static_assert(CanCompare<std::expected<void, int>, std::expected<void, int>>);
static_assert(!CanCompare<std::expected<void, NonComparable>, std::expected<void, NonComparable>>);
static_assert(!CanCompare<std::expected<void, int>, std::expected<void, NonComparable>>);
static_assert(!CanCompare<std::expected<void, NonComparable>, std::expected<void, int>>);
static_assert(!HasOperatorEqual<std::expected<void, int>, std::expected<int, int>>);
static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<void, int>>);
static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<void, int>>);
static_assert(!HasOperatorEqual<std::expected<void, NonComparable>, std::expected<void, NonComparable>>);
static_assert(!HasOperatorEqual<std::expected<void, int>, std::expected<void, NonComparable>>);
static_assert(!HasOperatorEqual<std::expected<void, NonComparable>, std::expected<void, int>>);
#else
// Note this is true because other overloads in expected<non-void> are unconstrained
static_assert(CanCompare<std::expected<void, int>, std::expected<int, int>>);
static_assert(HasOperatorEqual<std::expected<void, int>, std::expected<int, int>>);
#endif

constexpr bool test() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
#include <type_traits>
#include <utility>

#include "test_comparisons.h"
#include "test_macros.h"
#include "../../types.h"

#if TEST_STD_VER >= 26
// https://wg21.link/P3379R0
static_assert(CanCompare<std::expected<void, EqualityComparable>, std::unexpected<int>>);
static_assert(CanCompare<std::expected<void, int>, std::unexpected<EqualityComparable>>);
static_assert(!CanCompare<std::expected<void, NonComparable>, std::unexpected<int>>);
static_assert(HasOperatorEqual<std::expected<void, EqualityComparable>, std::unexpected<int>>);
static_assert(HasOperatorEqual<std::expected<void, int>, std::unexpected<EqualityComparable>>);
static_assert(!HasOperatorEqual<std::expected<void, NonComparable>, std::unexpected<int>>);
#endif

constexpr bool test() {
Expand Down
13 changes: 0 additions & 13 deletions libcxx/test/std/utilities/expected/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,17 +336,4 @@ struct CheckForInvalidWrites : public CheckForInvalidWritesBase<WithPaddedExpect
}
};

struct NonComparable {};

struct EqualityComparable {
int i;
constexpr EqualityComparable(int ii) : i(ii) {}

friend constexpr bool operator==(const EqualityComparable& data, int ii) { return data.i == ii; }
};

// Test constraint
template <class T1, class T2>
concept CanCompare = requires(T1 t1, T2 t2) { t1 == t2; };

#endif // TEST_STD_UTILITIES_EXPECTED_TYPES_H
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
// REQUIRES: std-at-least-c++26

// <functional>

Expand All @@ -23,16 +23,13 @@
#include "test_comparisons.h"
#include "test_macros.h"

#include "helper_concepts.h"
#include "helper_types.h"

// Test SFINAE.

static_assert(HasSpaceshipOperatorWithInt<std::reference_wrapper<StrongOrder>>);
static_assert(HasSpaceshipOperatorWithInt<std::reference_wrapper<WeakOrder>>);
static_assert(HasSpaceshipOperatorWithInt<std::reference_wrapper<PartialOrder>>);
static_assert(HasOperatorSpaceship<std::reference_wrapper<StrongOrder>, int>);
static_assert(HasOperatorSpaceship<std::reference_wrapper<WeakOrder>, int>);
static_assert(HasOperatorSpaceship<std::reference_wrapper<PartialOrder>, int>);

static_assert(!HasSpaceshipOperatorWithInt<std::reference_wrapper<NonComparable>>);
static_assert(!HasOperatorSpaceship<std::reference_wrapper<NonComparable>, int>);

// Test comparisons.

Expand Down
Loading
Loading