Skip to content
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

Remove obsolete conditional compilation from <compare> #1049

Merged
merged 12 commits into from
Jul 20, 2020
66 changes: 9 additions & 57 deletions stl/inc/compare
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ using _Compare_t = signed char;
// These "pretty" enumerator names are safe since they reuse names of user-facing entities.
enum class _Compare_eq : _Compare_t { equal = 0, equivalent = equal };
enum class _Compare_ord : _Compare_t { less = -1, greater = 1 };
enum class _Compare_ncmp : _Compare_t { unordered = -127 };
enum class _Compare_ncmp : _Compare_t { unordered = -128 };
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved

// CLASS partial_ordering
class partial_ordering {
Expand All @@ -53,21 +53,7 @@ public:
return _Val._Value == 0;
}

#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L
_NODISCARD friend constexpr bool operator==(const partial_ordering&, const partial_ordering&) noexcept = default;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
#else // ^^^ supports <=> and P1185 / supports neither vvv
_NODISCARD friend constexpr bool operator!=(const partial_ordering _Val, _Literal_zero) noexcept {
return _Val._Value != 0;
}

_NODISCARD friend constexpr bool operator==(_Literal_zero, const partial_ordering _Val) noexcept {
return 0 == _Val._Value;
}

_NODISCARD friend constexpr bool operator!=(_Literal_zero, const partial_ordering _Val) noexcept {
return 0 != _Val._Value;
}
#endif // defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L

_NODISCARD friend constexpr bool operator<(const partial_ordering _Val, _Literal_zero) noexcept {
return _Val._Value == static_cast<_Compare_t>(_Compare_ord::less);
Expand All @@ -78,38 +64,36 @@ public:
}

_NODISCARD friend constexpr bool operator<=(const partial_ordering _Val, _Literal_zero) noexcept {
return _Val._Value <= 0 && _Val._Is_ordered();
return static_cast<signed char>(static_cast<unsigned char>(_Val._Value) - 1) < 0;
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
}

_NODISCARD friend constexpr bool operator>=(const partial_ordering _Val, _Literal_zero) noexcept {
return _Val._Value >= 0;
}

_NODISCARD friend constexpr bool operator<(_Literal_zero, const partial_ordering _Val) noexcept {
return 0 < _Val._Value;
return _Val._Value > 0;
}

_NODISCARD friend constexpr bool operator>(_Literal_zero, const partial_ordering _Val) noexcept {
return 0 > _Val._Value && _Val._Is_ordered();
return _Val._Value == static_cast<_Compare_t>(_Compare_ord::less);
}

_NODISCARD friend constexpr bool operator<=(_Literal_zero, const partial_ordering _Val) noexcept {
return 0 <= _Val._Value;
return _Val._Value >= 0;
}

_NODISCARD friend constexpr bool operator>=(_Literal_zero, const partial_ordering _Val) noexcept {
return 0 >= _Val._Value && _Val._Is_ordered();
return static_cast<signed char>(static_cast<unsigned char>(_Val._Value) - 1) < 0;
}

#ifdef __cpp_impl_three_way_comparison
_NODISCARD friend constexpr partial_ordering operator<=>(const partial_ordering _Val, _Literal_zero) noexcept {
return _Val;
}

_NODISCARD friend constexpr partial_ordering operator<=>(_Literal_zero, const partial_ordering _Val) noexcept {
return partial_ordering{static_cast<_Compare_ord>(-_Val._Value)};
return partial_ordering{static_cast<_Compare_ord>(0 - static_cast<unsigned>(_Val._Value))};
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
}
#endif // __cpp_impl_three_way_comparison

private:
_NODISCARD constexpr bool _Is_ordered() const noexcept {
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -144,21 +128,7 @@ public:
return _Val._Value == 0;
}

#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L
_NODISCARD friend constexpr bool operator==(const weak_ordering&, const weak_ordering&) noexcept = default;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
#else // ^^^ supports <=> and P1185 / supports neither vvv
_NODISCARD friend constexpr bool operator!=(const weak_ordering _Val, _Literal_zero) noexcept {
return _Val._Value != 0;
}

_NODISCARD friend constexpr bool operator==(_Literal_zero, const weak_ordering _Val) noexcept {
return 0 == _Val._Value;
}

_NODISCARD friend constexpr bool operator!=(_Literal_zero, const weak_ordering _Val) noexcept {
return 0 != _Val._Value;
}
#endif // defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L

_NODISCARD friend constexpr bool operator<(const weak_ordering _Val, _Literal_zero) noexcept {
return _Val._Value < 0;
Expand Down Expand Up @@ -192,15 +162,13 @@ public:
return 0 >= _Val._Value;
}

#ifdef __cpp_impl_three_way_comparison
_NODISCARD friend constexpr weak_ordering operator<=>(const weak_ordering _Val, _Literal_zero) noexcept {
return _Val;
}

_NODISCARD friend constexpr weak_ordering operator<=>(_Literal_zero, const weak_ordering _Val) noexcept {
return weak_ordering{static_cast<_Compare_ord>(-_Val._Value)};
}
#endif // __cpp_impl_three_way_comparison

private:
_Compare_t _Value;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -235,21 +203,7 @@ public:
return _Val._Value == 0;
}

#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L
_NODISCARD friend constexpr bool operator==(const strong_ordering&, const strong_ordering&) noexcept = default;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
#else // ^^^ supports <=> and P1185 / supports neither vvv
_NODISCARD friend constexpr bool operator!=(const strong_ordering _Val, _Literal_zero) noexcept {
return _Val._Value != 0;
}

_NODISCARD friend constexpr bool operator==(_Literal_zero, const strong_ordering _Val) noexcept {
return 0 == _Val._Value;
}

_NODISCARD friend constexpr bool operator!=(_Literal_zero, const strong_ordering _Val) noexcept {
return 0 != _Val._Value;
}
#endif // defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201902L

_NODISCARD friend constexpr bool operator<(const strong_ordering _Val, _Literal_zero) noexcept {
return _Val._Value < 0;
Expand Down Expand Up @@ -283,15 +237,13 @@ public:
return 0 >= _Val._Value;
}

#ifdef __cpp_impl_three_way_comparison
_NODISCARD friend constexpr strong_ordering operator<=>(const strong_ordering _Val, _Literal_zero) noexcept {
return _Val;
}

_NODISCARD friend constexpr strong_ordering operator<=>(_Literal_zero, const strong_ordering _Val) noexcept {
return strong_ordering{static_cast<_Compare_ord>(-_Val._Value)};
}
#endif // __cpp_impl_three_way_comparison

private:
_Compare_t _Value;
Expand Down Expand Up @@ -364,7 +316,7 @@ struct common_comparison_category {
using type = common_comparison_category_t<_Types...>;
};

#if defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
#ifdef __cpp_lib_concepts
// clang-format off
template <class _Ty, class _Cat>
concept _Compares_as = same_as<common_comparison_category_t<_Ty, _Cat>, _Cat>;
Expand Down Expand Up @@ -409,7 +361,7 @@ struct compare_three_way {
using is_transparent = int;
};
// clang-format on
#endif // defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
#endif // __cpp_lib_concepts

// Other components not yet implemented
_STD_END
Expand Down
110 changes: 98 additions & 12 deletions tests/std/tests/P0768R1_spaceship_operator/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ constexpr bool test_ord(T val) {
assert((0 == val) == (Z == comp::equal));
assert((val != 0) == (Z != comp::equal));
assert((0 != val) == (Z != comp::equal));
#ifdef __cpp_impl_three_way_comparison
assert(((val <=> 0) == 0) == (Z == comp::equal));
assert(((0 <=> val) == 0) == (Z == comp::equal));
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved

#if __cpp_impl_three_way_comparison >= 201907L
assert(val == val);
assert(!(val != val));
#endif // __cpp_impl_three_way_comparison >= 201907L
#endif // __cpp_impl_three_way_comparison
assert(std::is_eq(val) == (Z == comp::equal));
assert(std::is_neq(val) == (Z != comp::equal));

Expand All @@ -35,15 +31,11 @@ constexpr bool test_ord(T val) {
assert((0 >= val) == (Z != comp::greater && Z != comp::unordered));
assert((val >= 0) == (Z != comp::less && Z != comp::unordered));
assert((0 <= val) == (Z != comp::less && Z != comp::unordered));
#ifdef __cpp_impl_three_way_comparison
assert(((val <=> 0) < 0) == (Z == comp::less));
assert(((0 <=> val) < 0) == (Z == comp::greater));
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved

#if __cpp_impl_three_way_comparison >= 201907L
assert(val == val);
assert(!(val != val));
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
#endif // __cpp_impl_three_way_comparison >= 201907L
#endif // __cpp_impl_three_way_comparison
assert(std::is_lt(val) == (Z == comp::less));
assert(std::is_lteq(val) == (Z != comp::greater && Z != comp::unordered));
assert(std::is_gt(val) == (Z == comp::greater));
Expand Down Expand Up @@ -121,7 +113,7 @@ static_assert(test_common_type<std::strong_ordering, std::partial_ordering>());
static_assert(test_common_type<std::strong_ordering, std::weak_ordering>());
static_assert(test_common_type<std::strong_ordering, std::strong_ordering>());

#if defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
#ifdef __cpp_lib_concepts
constexpr auto my_cmp_three_way = [](const auto& left, const auto& right) { return left <=> right; };

template <class Left, class Right>
Expand Down Expand Up @@ -187,7 +179,101 @@ void test_algorithm() {
assert((test_algorithm2<Ty1, Ty2>()));
assert((test_algorithm2<Ty2, Ty1>()));
}
#endif // defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
#endif // __cpp_lib_concepts

// Guard against regression of GH-1050: 0 <=> partial_ordering::unordered returns invalid value
static_assert(!(std::partial_ordering::less == 0));
static_assert(std::partial_ordering::less != 0);
static_assert(std::partial_ordering::less < 0);
static_assert(!(std::partial_ordering::less > 0));
static_assert(std::partial_ordering::less <= 0);
static_assert(!(std::partial_ordering::less >= 0));
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved

static_assert(std::partial_ordering::equivalent == 0);
static_assert(!(std::partial_ordering::equivalent != 0));
static_assert(!(std::partial_ordering::equivalent < 0));
static_assert(!(std::partial_ordering::equivalent > 0));
static_assert(std::partial_ordering::equivalent <= 0);
static_assert(std::partial_ordering::equivalent >= 0);

static_assert(!(std::partial_ordering::greater == 0));
static_assert(std::partial_ordering::greater != 0);
static_assert(!(std::partial_ordering::greater < 0));
static_assert(std::partial_ordering::greater > 0);
static_assert(!(std::partial_ordering::greater <= 0));
static_assert(std::partial_ordering::greater >= 0);

static_assert(!(std::partial_ordering::unordered == 0));
static_assert(std::partial_ordering::unordered != 0);
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
static_assert(!(std::partial_ordering::unordered < 0));
static_assert(!(std::partial_ordering::unordered > 0));
static_assert(!(std::partial_ordering::unordered <= 0));
static_assert(!(std::partial_ordering::unordered >= 0));

static_assert(std::partial_ordering::less <=> 0 == std::partial_ordering::less);
static_assert(0 <=> std::partial_ordering::less == std::partial_ordering::greater);
static_assert(std::partial_ordering::equivalent <=> 0 == std::partial_ordering::equivalent);
static_assert(0 <=> std::partial_ordering::equivalent == std::partial_ordering::equivalent);
static_assert(std::partial_ordering::greater <=> 0 == std::partial_ordering::greater);
static_assert(0 <=> std::partial_ordering::greater == std::partial_ordering::less);
static_assert(std::partial_ordering::unordered <=> 0 == std::partial_ordering::unordered);
static_assert(0 <=> std::partial_ordering::unordered == std::partial_ordering::unordered);

static_assert(!(std::weak_ordering::less == 0));
static_assert(std::weak_ordering::less != 0);
static_assert(std::weak_ordering::less < 0);
static_assert(!(std::weak_ordering::less > 0));
static_assert(std::weak_ordering::less <= 0);
static_assert(!(std::weak_ordering::less >= 0));

static_assert(std::weak_ordering::equivalent == 0);
static_assert(!(std::weak_ordering::equivalent != 0));
static_assert(!(std::weak_ordering::equivalent < 0));
static_assert(!(std::weak_ordering::equivalent > 0));
static_assert(std::weak_ordering::equivalent <= 0);
static_assert(std::weak_ordering::equivalent >= 0);

static_assert(!(std::weak_ordering::greater == 0));
static_assert(std::weak_ordering::greater != 0);
static_assert(!(std::weak_ordering::greater < 0));
static_assert(std::weak_ordering::greater > 0);
static_assert(!(std::weak_ordering::greater <= 0));
static_assert(std::weak_ordering::greater >= 0);

static_assert(std::weak_ordering::less <=> 0 == std::weak_ordering::less);
static_assert(0 <=> std::weak_ordering::less == std::weak_ordering::greater);
static_assert(std::weak_ordering::equivalent <=> 0 == std::weak_ordering::equivalent);
static_assert(0 <=> std::weak_ordering::equivalent == std::weak_ordering::equivalent);
static_assert(std::weak_ordering::greater <=> 0 == std::weak_ordering::greater);
static_assert(0 <=> std::weak_ordering::greater == std::weak_ordering::less);

static_assert(!(std::strong_ordering::less == 0));
static_assert(std::strong_ordering::less != 0);
static_assert(std::strong_ordering::less < 0);
static_assert(!(std::strong_ordering::less > 0));
static_assert(std::strong_ordering::less <= 0);
static_assert(!(std::strong_ordering::less >= 0));

static_assert(std::strong_ordering::equal == 0);
static_assert(!(std::strong_ordering::equal != 0));
static_assert(!(std::strong_ordering::equal < 0));
static_assert(!(std::strong_ordering::equal > 0));
static_assert(std::strong_ordering::equal <= 0);
static_assert(std::strong_ordering::equal >= 0);

static_assert(!(std::strong_ordering::greater == 0));
static_assert(std::strong_ordering::greater != 0);
static_assert(!(std::strong_ordering::greater < 0));
static_assert(std::strong_ordering::greater > 0);
static_assert(!(std::strong_ordering::greater <= 0));
static_assert(std::strong_ordering::greater >= 0);

static_assert(std::strong_ordering::less <=> 0 == std::strong_ordering::less);
static_assert(0 <=> std::strong_ordering::less == std::strong_ordering::greater);
static_assert(std::strong_ordering::equal <=> 0 == std::strong_ordering::equal);
static_assert(0 <=> std::strong_ordering::equal == std::strong_ordering::equal);
static_assert(std::strong_ordering::greater <=> 0 == std::strong_ordering::greater);
static_assert(0 <=> std::strong_ordering::greater == std::strong_ordering::less);

int main() {
test_ord<comp::equal>(std::partial_ordering::equivalent);
Expand All @@ -204,12 +290,12 @@ int main() {
test_ord<comp::less>(std::strong_ordering::less);
test_ord<comp::greater>(std::strong_ordering::greater);

#if defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
#ifdef __cpp_lib_concepts
test_algorithm<int>();
test_algorithm<char>();
test_algorithm<unsigned char>();
test_algorithm<int, char>();
test_algorithm<int, unsigned char>();
test_algorithm<char, unsigned char>();
#endif // defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_concepts)
#endif // __cpp_lib_concepts
}