Skip to content
Open
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
15 changes: 13 additions & 2 deletions stl/inc/variant
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class _Ty1, class _Ty2>
_NODISCARD static constexpr auto operator()(const _Ty1& _Left, const _Ty2& _Right) //
noexcept(noexcept(_Left <=> _Right)) //
/*-*/ -> decltype(_Left <=> _Right) {
/*------*/ return _Left <=> _Right;
}
};

_EXPORT_STD template <class... _Types>
requires (three_way_comparable<_Types> && ...)
_NODISCARD constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...> operator<=>(
const variant<_Types...>& _Left, const variant<_Types...>& _Right)
noexcept(conjunction_v<is_nothrow_invocable_r<common_comparison_category_t<compare_three_way_result_t<_Types>...>,
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<compare_three_way,
using _Visitor = _Variant_relop_visitor2<_Simpler_compare_three_way,
common_comparison_category_t<compare_three_way_result_t<_Types>...>, _Types...>;
const size_t _Left_offset = _Left.index() + 1;
const size_t _Right_offset = _Right.index() + 1;
Expand Down
3 changes: 0 additions & 3 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
21 changes: 6 additions & 15 deletions tests/std/tests/P0088R3_variant/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<HasSimpleOrdering>);
Expand Down