Skip to content
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
21 changes: 12 additions & 9 deletions stl/inc/compare
Original file line number Diff line number Diff line change
Expand Up @@ -290,23 +290,26 @@ struct common_comparison_category {
template <class _Ty, class _Cat>
concept _Compares_as = same_as<common_comparison_category_t<_Ty, _Cat>, _Cat>;

// clang-format off
_EXPORT_STD template <class _Ty, class _Cat = partial_ordering>
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 <class _Ty1, class _Ty2, class _Cat = partial_ordering>
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<_Ty1>&, const remove_reference_t<_Ty2>&>
#endif // C++20
&& three_way_comparable<common_reference_t<const remove_reference_t<_Ty1>&, 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 <class _Ty1, class _Ty2 = _Ty1>
using compare_three_way_result_t =
Expand Down
17 changes: 17 additions & 0 deletions stl/inc/concepts
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,26 @@ concept _Weakly_equality_comparable_with =
_EXPORT_STD template <class _Ty>
concept equality_comparable = _Half_equality_comparable<_Ty, _Ty>;

#if _HAS_CXX23
template <class _Ty1, class _Ty2, class _Ref = common_reference_t<const _Ty1&, const _Ty2&>>
concept _Comparison_common_type_with_impl =
same_as<_Ref, common_reference_t<const _Ty2&, const _Ty1&>>
&& requires {
requires convertible_to<const _Ty1&, const _Ref&> || convertible_to<_Ty1, const _Ref&>;
requires convertible_to<const _Ty2&, const _Ref&> || convertible_to<_Ty2, const _Ref&>;
};

template <class _Ty1, class _Ty2>
concept _Comparison_common_type_with = _Comparison_common_type_with_impl<remove_cvref_t<_Ty1>, remove_cvref_t<_Ty2>>;
#endif // _HAS_CXX23

_EXPORT_STD template <class _Ty1, class _Ty2>
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<_Ty1>&, const remove_reference_t<_Ty2>&>
#endif // C++20
&& equality_comparable<common_reference_t<const remove_reference_t<_Ty1>&, const remove_reference_t<_Ty2>&>>
&& _Weakly_equality_comparable_with<_Ty1, _Ty2>;

Expand Down
7 changes: 6 additions & 1 deletion stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
#define __cpp_lib_concepts 202002L
#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 // P1964R2 Replacing boolean With boolean-testable
#endif // C++20
#endif // !defined(__EDG__) || defined(__INTELLISENSE__)

#ifdef __cpp_lib_concepts
Expand Down
10 changes: 10 additions & 0 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\concepts_latest_matrix.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <compare>
#include <concepts>
#include <cstddef>
#include <memory>
#include <type_traits>

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<MoveOnly, int>);
static_assert(three_way_comparable_with<int, MoveOnly>);
static_assert(three_way_comparable_with<MoveOnly, int, strong_ordering>);
static_assert(three_way_comparable_with<int, MoveOnly, strong_ordering>);

// Check equality_comparable_with
static_assert(equality_comparable_with<MoveOnly, int>);
static_assert(equality_comparable_with<int, MoveOnly>);
static_assert(equality_comparable_with<unique_ptr<int>, nullptr_t>);
static_assert(equality_comparable_with<nullptr_t, unique_ptr<int>>);

// Check totally_ordered_with
static_assert(totally_ordered_with<MoveOnly, int>);
static_assert(totally_ordered_with<int, MoveOnly>);

// Check [diff.cpp20.concepts]
// clang-format off
template <class T, class U>
requires equality_comparable_with<T, U>
bool attempted_equals(const T&, const U&); // not defined

template <class T, class U>
requires common_reference_with<const remove_reference_t<T>&, const remove_reference_t<U>&>
bool attempted_equals(const T&, const U&); // not defined
// clang-format on

template <class T>
constexpr bool check_diff_cpp20_concepts = !requires(T p) { attempted_equals(p, nullptr); };

static_assert(check_diff_cpp20_concepts<shared_ptr<int>>);

int main() {} // COMPILE-ONLY
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down