From bbdf2f4611f3b3638d8d8015ce064ff0d4df2fc3 Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Thu, 12 Jan 2023 21:16:26 +0100 Subject: [PATCH 1/7] Implement P2404R3 --- stl/inc/compare | 21 ++++--- stl/inc/concepts | 17 +++++ stl/inc/yvals_core.h | 5 ++ tests/std/test.lst | 1 + .../env.lst | 4 ++ .../test.compile.pass.cpp | 62 +++++++++++++++++++ .../test.compile.pass.cpp | 10 ++- 7 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/env.lst create mode 100644 tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp diff --git a/stl/inc/compare b/stl/inc/compare index 64eabc340b2..76723bf8162 100644 --- a/stl/inc/compare +++ b/stl/inc/compare @@ -290,23 +290,26 @@ struct common_comparison_category { template concept _Compares_as = same_as, _Cat>; -// clang-format off _EXPORT_STD template concept three_way_comparable = _Half_equality_comparable<_Ty, _Ty> && _Half_ordered<_Ty, _Ty> - && requires(const remove_reference_t<_Ty>& __a, const remove_reference_t<_Ty>& __b) { - { __a <=> __b } -> _Compares_as<_Cat>; - }; + && requires(const remove_reference_t<_Ty>& __a, const remove_reference_t<_Ty>& __b) { + { __a <=> __b } -> _Compares_as<_Cat>; + }; _EXPORT_STD template -concept three_way_comparable_with = three_way_comparable<_Ty1, _Cat> && three_way_comparable<_Ty2, _Cat> +concept three_way_comparable_with = + three_way_comparable<_Ty1, _Cat> && three_way_comparable<_Ty2, _Cat> +#if _HAS_CXX23 + && _Comparison_common_type_with<_Ty1, _Ty2> +#else // ^^^ C++23 / C++20 vvv && common_reference_with&, const remove_reference_t<_Ty2>&> +#endif // C++20 && three_way_comparable&, const remove_reference_t<_Ty2>&>, _Cat> && _Weakly_equality_comparable_with<_Ty1, _Ty2> && _Partially_ordered_with<_Ty1, _Ty2> && requires(const remove_reference_t<_Ty1>& __t, const remove_reference_t<_Ty2>& __u) { - { __t <=> __u } -> _Compares_as<_Cat>; - { __u <=> __t } -> _Compares_as<_Cat>; - }; -// clang-format on + { __t <=> __u } -> _Compares_as<_Cat>; + { __u <=> __t } -> _Compares_as<_Cat>; + }; _EXPORT_STD template using compare_three_way_result_t = diff --git a/stl/inc/concepts b/stl/inc/concepts index c00665e58a2..35845c6c674 100644 --- a/stl/inc/concepts +++ b/stl/inc/concepts @@ -206,9 +206,26 @@ concept _Weakly_equality_comparable_with = _EXPORT_STD template concept equality_comparable = _Half_equality_comparable<_Ty, _Ty>; +#if _HAS_CXX23 +template > +concept _Comparison_common_type_with_impl = + same_as<_Ref, common_reference_t> + && requires { + requires convertible_to || convertible_to<_Ty1, const _Ref&>; + requires convertible_to || convertible_to<_Ty2, const _Ref&>; + }; + +template +concept _Comparison_common_type_with = _Comparison_common_type_with_impl, remove_cvref_t<_Ty2>>; +#endif // _HAS_CXX23 + _EXPORT_STD template concept equality_comparable_with = equality_comparable<_Ty1> && equality_comparable<_Ty2> +#if _HAS_CXX23 + && _Comparison_common_type_with<_Ty1, _Ty2> +#else // ^^^ C++23 / C++20 vvv && common_reference_with&, const remove_reference_t<_Ty2>&> +#endif // C++20 && equality_comparable&, const remove_reference_t<_Ty2>&>> && _Weakly_equality_comparable_with<_Ty1, _Ty2>; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 88cf2c26aeb..ed6acd9ad1a 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -333,6 +333,7 @@ // (missing views::zip_transform, views::adjacent, and views::adjacent_transform) // P2322R6 ranges::fold_left, ranges::fold_right, Etc. // P2387R3 Pipe Support For User-Defined Range Adaptors +// P2404R3 Move-Only Types For Comparison Concepts // P2417R2 More constexpr bitset // P2438R2 string::substr() && // P2440R1 ranges::iota, ranges::shift_left, ranges::shift_right @@ -1565,7 +1566,11 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #if _HAS_CXX20 #if !defined(__EDG__) || defined(__INTELLISENSE__) // TRANSITION, GH-395 +#if _HAS_CXX23 +#define __cpp_lib_concepts 202207L +#else // ^^^ C++23 / C++20 vvv #define __cpp_lib_concepts 202002L +#endif // C++20 #endif // !defined(__EDG__) || defined(__INTELLISENSE__) #ifdef __cpp_lib_concepts diff --git a/tests/std/test.lst b/tests/std/test.lst index 9652c56a554..81c12978219 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -567,6 +567,7 @@ tests\P2322R6_ranges_alg_fold tests\P2387R3_bind_back tests\P2387R3_pipe_support_for_user_defined_range_adaptors tests\P2401R0_conditional_noexcept_for_exchange +tests\P2404R3_move_only_types_for_comparison_concepts tests\P2408R5_ranges_iterators_to_classic_algorithms tests\P2415R2_owning_view tests\P2417R2_constexpr_bitset diff --git a/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/env.lst b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/env.lst new file mode 100644 index 00000000000..18e2d7c71ec --- /dev/null +++ b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\concepts_latest_matrix.lst diff --git a/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp new file mode 100644 index 00000000000..b688d7d7b7f --- /dev/null +++ b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +using namespace std; + +struct MoveOnly { + MoveOnly(int); // not defined + MoveOnly(const MoveOnly&) = delete; + MoveOnly& operator=(const MoveOnly&) = delete; + MoveOnly(MoveOnly&&) = default; + MoveOnly& operator=(MoveOnly&&) = default; + + strong_ordering operator<=>(const MoveOnly&) const = default; + strong_ordering operator<=>(int) const; // not defined +}; + +// Check three_way_comparable_with +static_assert(three_way_comparable_with); +static_assert(three_way_comparable_with); +static_assert(three_way_comparable_with); +static_assert(three_way_comparable_with); + +// Check equality_comparable_with +static_assert(equality_comparable_with); +static_assert(equality_comparable_with); +static_assert(equality_comparable_with, nullptr_t>); +static_assert(equality_comparable_with>); + +// Check totally_ordered_with +static_assert(totally_ordered_with); +static_assert(totally_ordered_with); + +// Check [diff.cpp20.concepts] +// clang-format off +template + requires equality_comparable_with +bool attempted_equals(const T&, const U& u); + +template + requires common_reference_with&, const remove_reference_t&> +bool attempted_equals(const T& t, const U& u); +// clang-format on + +template +bool test(T val) { + return attempted_equals(val, nullptr); // ill-formed; previously well-formed +} + +template +constexpr bool diff_cpp20_concepts = requires(T val) { test(val); }; + +#if _HAS_CXX23 +static_assert(!diff_cpp20_concepts>); +#else // ^^^ C++23 / C++20 vvv +static_assert(diff_cpp20_concepts>); +#endif // C++20 + +int main() {} // COMPILE-ONLY diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index d2c679c1dc9..4e15042f407 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -458,7 +458,15 @@ STATIC_ASSERT(__cpp_lib_clamp == 201603L); STATIC_ASSERT(__cpp_lib_complex_udls == 201309L); #endif -#if _HAS_CXX20 && !defined(__EDG__) // TRANSITION, GH-395 +#if _HAS_CXX23 && !defined(__EDG__) // TRANSITION, GH-395 +#ifndef __cpp_lib_concepts +#error __cpp_lib_concepts is not defined +#elif __cpp_lib_concepts != 202207L +#error __cpp_lib_concepts is not 202207L +#else +STATIC_ASSERT(__cpp_lib_concepts == 202207L); +#endif +#elif _HAS_CXX20 && !defined(__EDG__) // TRANSITION, GH-395 #ifndef __cpp_lib_concepts #error __cpp_lib_concepts is not defined #elif __cpp_lib_concepts != 202002L From 02ed7c6a589286785bc80b3dc51e465ee943d6ec Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Thu, 12 Jan 2023 23:54:13 +0100 Subject: [PATCH 2/7] Skip unsupported libc++ tests --- llvm-project | 2 +- tests/libcxx/expected_results.txt | 10 ++++++++++ tests/libcxx/skipped_tests.txt | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/llvm-project b/llvm-project index 0d91b050521..725cdc451a6 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 0d91b05052140f5ae3ebbaae36304e5d1eb2bb58 +Subproject commit 725cdc451a6bb681e5d6f397a16c2d663d7d9137 diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 764505bbc2c..81b556d987b 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -54,6 +54,16 @@ std/ranges/range.access/end.pass.cpp FAIL std/ranges/range.access/rbegin.pass.cpp FAIL std/ranges/range.access/rend.pass.cpp FAIL +# libc++ has not implemented P2404R3: "Move-Only Types For Comparison Concepts" +std/algorithms/alg.sorting/alg.sort/partial.sort.copy/ranges_partial_sort_copy.pass.cpp FAIL +std/language.support/support.limits/support.limits.general/concepts.version.compile.pass.cpp FAIL +std/utilities/function.objects/range.cmp/equal_to.pass.cpp FAIL +std/utilities/function.objects/range.cmp/greater.pass.cpp FAIL +std/utilities/function.objects/range.cmp/greater_equal.pass.cpp FAIL +std/utilities/function.objects/range.cmp/less.pass.cpp FAIL +std/utilities/function.objects/range.cmp/less_equal.pass.cpp FAIL +std/utilities/function.objects/range.cmp/not_equal_to.pass.cpp FAIL + # Various bogosity (LLVM-D141004) std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp:0 FAIL std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_values.pass.cpp:0 FAIL diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index 428e61c57c8..38d1cb6bebc 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -54,6 +54,16 @@ ranges\range.access\end.pass.cpp ranges\range.access\rbegin.pass.cpp ranges\range.access\rend.pass.cpp +# libc++ has not implemented P2404R3: "Move-Only Types For Comparison Concepts" +algorithms\alg.sorting\alg.sort\partial.sort.copy\ranges_partial_sort_copy.pass.cpp +language.support\support.limits\support.limits.general\concepts.version.compile.pass.cpp +utilities\function.objects\range.cmp\equal_to.pass.cpp +utilities\function.objects\range.cmp\greater.pass.cpp +utilities\function.objects\range.cmp\greater_equal.pass.cpp +utilities\function.objects\range.cmp\less.pass.cpp +utilities\function.objects\range.cmp\less_equal.pass.cpp +utilities\function.objects\range.cmp\not_equal_to.pass.cpp + # Various bogosity (LLVM-D141004) utilities\utility\mem.res\mem.poly.allocator.class\mem.poly.allocator.mem\construct_pair_const_lvalue_pair.pass.cpp utilities\utility\mem.res\mem.poly.allocator.class\mem.poly.allocator.mem\construct_pair_values.pass.cpp From 57b1315eae250db1c68f5188bd151efbeb7a29b9 Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Fri, 13 Jan 2023 13:26:59 +0100 Subject: [PATCH 3/7] Fix `[diff.cpp20.concepts]` check --- llvm-project | 2 +- .../test.compile.pass.cpp | 17 ++++------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/llvm-project b/llvm-project index 725cdc451a6..0d91b050521 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 725cdc451a6bb681e5d6f397a16c2d663d7d9137 +Subproject commit 0d91b05052140f5ae3ebbaae36304e5d1eb2bb58 diff --git a/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp index b688d7d7b7f..0a85ebfb7bf 100644 --- a/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp +++ b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp @@ -38,25 +38,16 @@ static_assert(totally_ordered_with); // clang-format off template requires equality_comparable_with -bool attempted_equals(const T&, const U& u); +bool attempted_equals(const T&, const U& u); // not defined template requires common_reference_with&, const remove_reference_t&> -bool attempted_equals(const T& t, const U& u); +bool attempted_equals(const T& t, const U& u); // not defined // clang-format on template -bool test(T val) { - return attempted_equals(val, nullptr); // ill-formed; previously well-formed -} +constexpr bool check_diff_cpp20_concepts = !requires(T p) { attempted_equals(p, nullptr); }; -template -constexpr bool diff_cpp20_concepts = requires(T val) { test(val); }; - -#if _HAS_CXX23 -static_assert(!diff_cpp20_concepts>); -#else // ^^^ C++23 / C++20 vvv -static_assert(diff_cpp20_concepts>); -#endif // C++20 +static_assert(check_diff_cpp20_concepts>); int main() {} // COMPILE-ONLY From b4c1142fb9e710937398a3d07a58554d8c9c3d63 Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Tue, 24 Jan 2023 20:48:26 +0100 Subject: [PATCH 4/7] Add extra comments --- stl/inc/yvals_core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index ed6acd9ad1a..7b5b6cd85a0 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1566,10 +1566,10 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #if _HAS_CXX20 #if !defined(__EDG__) || defined(__INTELLISENSE__) // TRANSITION, GH-395 -#if _HAS_CXX23 -#define __cpp_lib_concepts 202207L +#if _HAS_CXX23 // TRANSITION, GH-395 - move down to "macros with language mode sensitivity" section +#define __cpp_lib_concepts 202207L // P2404R3 Move-Only Types For Comparison Concepts #else // ^^^ C++23 / C++20 vvv -#define __cpp_lib_concepts 202002L +#define __cpp_lib_concepts 202002L // P2408R5 Ranges Iterators As Inputs To Non-Ranges Algorithms #endif // C++20 #endif // !defined(__EDG__) || defined(__INTELLISENSE__) From 0d0071434e1d20d8d9544bea096e50e9c9c54861 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 24 Jan 2023 16:14:31 -0800 Subject: [PATCH 5/7] Fix paper citation for feature-test macro. --- stl/inc/yvals_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 7b5b6cd85a0..c3f4caef87f 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1569,7 +1569,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #if _HAS_CXX23 // TRANSITION, GH-395 - move down to "macros with language mode sensitivity" section #define __cpp_lib_concepts 202207L // P2404R3 Move-Only Types For Comparison Concepts #else // ^^^ C++23 / C++20 vvv -#define __cpp_lib_concepts 202002L // P2408R5 Ranges Iterators As Inputs To Non-Ranges Algorithms +#define __cpp_lib_concepts 202002L // P1964R2 Replacing boolean With boolean-testable #endif // C++20 #endif // !defined(__EDG__) || defined(__INTELLISENSE__) From e2a218072aa95e86ff3fc59bb32971ba18c74b21 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 24 Jan 2023 16:33:39 -0800 Subject: [PATCH 6/7] HEADERS FOR THE HEADER THRONE! --- .../test.compile.pass.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp index 0a85ebfb7bf..9438075e32f 100644 --- a/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp +++ b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp @@ -3,7 +3,9 @@ #include #include +#include #include +#include using namespace std; From 4d2318d22cb715544d98a2c4f6151458c211aea6 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 24 Jan 2023 16:41:50 -0800 Subject: [PATCH 7/7] A parameter has no name. --- .../test.compile.pass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp index 9438075e32f..6d266d217f7 100644 --- a/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp +++ b/tests/std/tests/P2404R3_move_only_types_for_comparison_concepts/test.compile.pass.cpp @@ -40,11 +40,11 @@ static_assert(totally_ordered_with); // clang-format off template requires equality_comparable_with -bool attempted_equals(const T&, const U& u); // not defined +bool attempted_equals(const T&, const U&); // not defined template requires common_reference_with&, const remove_reference_t&> -bool attempted_equals(const T& t, const U& u); // not defined +bool attempted_equals(const T&, const U&); // not defined // clang-format on template