diff --git a/stl/inc/variant b/stl/inc/variant index 8948643a39e..0e2f45d6105 100644 --- a/stl/inc/variant +++ b/stl/inc/variant @@ -1376,15 +1376,26 @@ _NODISCARD constexpr bool operator>=(const variant<_Types...>& _Left, const vari } #if _HAS_CXX20 +// This is equivalent to `compare_three_way`, +// except for no support for non-const comparison, simpler constraints, and explicit return type. +struct _Simpler_compare_three_way { + template + _NODISCARD static constexpr auto operator()(const _Ty1& _Left, const _Ty2& _Right) // + noexcept(noexcept(_Left <=> _Right)) // + /*-*/ -> decltype(_Left <=> _Right) { + /*------*/ return _Left <=> _Right; + } +}; + _EXPORT_STD template requires (three_way_comparable<_Types> && ...) _NODISCARD constexpr common_comparison_category_t...> operator<=>( const variant<_Types...>& _Left, const variant<_Types...>& _Right) noexcept(conjunction_v...>, - compare_three_way, const _Types&, const _Types&>...>) /* strengthened */ { + _Simpler_compare_three_way, const _Types&, const _Types&>...>) /* strengthened */ { // determine the three-way comparison of _Left's and _Right's index, if equal // return the three-way comparison of the contained values of _Left and _Right - using _Visitor = _Variant_relop_visitor2...>, _Types...>; const size_t _Left_offset = _Left.index() + 1; const size_t _Right_offset = _Right.index() + 1; diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 68e9d9f6fdd..a947cee74d3 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -1161,9 +1161,6 @@ std/algorithms/alg.sorting/alg.set.operations/set.symmetric.difference/ranges_se std/algorithms/alg.sorting/alg.set.operations/set.union/ranges_set_union.pass.cpp:0 SKIPPED std/algorithms/alg.sorting/alg.set.operations/set.union/ranges_set_union.pass.cpp:1 SKIPPED -# Not analyzed. Clang emits a -Wundefined-inline warning. -std/utilities/variant/variant.relops/three_way.pass.cpp:2 FAIL - # Not analyzed. # MSVC error C2719: '_Fun_': formal parameter with requested alignment of 128 won't be aligned # Clang error: unknown attribute 'no_unique_address' ignored [-Werror,-Wunknown-attributes] diff --git a/tests/std/tests/P0088R3_variant/test.cpp b/tests/std/tests/P0088R3_variant/test.cpp index 8a5beedb993..2466cd68169 100644 --- a/tests/std/tests/P0088R3_variant/test.cpp +++ b/tests/std/tests/P0088R3_variant/test.cpp @@ -1465,29 +1465,20 @@ concept has_three_way_op = requires (T& t, U& u) { t <=> u; }; using std::three_way_comparable; struct HasSimpleOrdering { - constexpr bool operator==(const HasSimpleOrdering&) const; - constexpr bool operator<(const HasSimpleOrdering&) const; + bool operator==(const HasSimpleOrdering&) const; + bool operator<(const HasSimpleOrdering&) const; }; struct HasOnlySpaceship { - constexpr bool operator==(const HasOnlySpaceship&) const = delete; - constexpr std::weak_ordering operator<=>(const HasOnlySpaceship&) const; + bool operator==(const HasOnlySpaceship&) const = delete; + std::weak_ordering operator<=>(const HasOnlySpaceship&) const; }; -#ifdef __clang__ // TRANSITION, not yet investigated -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundefined-inline" -#endif // ^^^ workaround ^^^ - struct HasFullOrdering { - constexpr bool operator==(const HasFullOrdering&) const; - constexpr std::weak_ordering operator<=>(const HasFullOrdering&) const; + bool operator==(const HasFullOrdering&) const; + std::weak_ordering operator<=>(const HasFullOrdering&) const; }; -#ifdef __clang__ // TRANSITION, not yet investigated -#pragma clang diagnostic pop -#endif // ^^^ workaround ^^^ - // operator<=> must resolve the return types of all its union types' // operator<=>s to determine its own return type, so it is detectable by SFINAE static_assert(!has_three_way_op);