1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
10 | |
11 | // <compare> |
12 | // <functional> |
13 | |
14 | // compare_three_way |
15 | |
16 | #include <compare> |
17 | #include <cassert> |
18 | #include <limits> |
19 | #include <type_traits> |
20 | |
21 | #include "pointer_comparison_test_helper.h" |
22 | |
23 | template<class T, class U> |
24 | constexpr auto test_sfinae(T t, U u) |
25 | -> decltype(std::compare_three_way()(t, u), std::true_type{}) |
26 | { return std::true_type{}; } |
27 | |
28 | constexpr auto test_sfinae(...) |
29 | { return std::false_type{}; } |
30 | |
31 | struct NotThreeWayComparable { |
32 | std::strong_ordering operator<=>(const NotThreeWayComparable&) const; |
33 | }; |
34 | ASSERT_SAME_TYPE(std::compare_three_way_result_t<NotThreeWayComparable>, std::strong_ordering); |
35 | static_assert(!std::three_way_comparable<NotThreeWayComparable>); // it lacks operator== |
36 | |
37 | struct WeaklyOrdered { |
38 | int i; |
39 | friend constexpr std::weak_ordering operator<=>(const WeaklyOrdered&, const WeaklyOrdered&) = default; |
40 | }; |
41 | |
42 | constexpr bool test() |
43 | { |
44 | ASSERT_SAME_TYPE(decltype(std::compare_three_way()(1, 1)), std::strong_ordering); |
45 | assert(std::compare_three_way()(1, 2) == std::strong_ordering::less); |
46 | assert(std::compare_three_way()(1, 1) == std::strong_ordering::equal); |
47 | assert(std::compare_three_way()(2, 1) == std::strong_ordering::greater); |
48 | |
49 | ASSERT_SAME_TYPE(decltype(std::compare_three_way()(WeaklyOrdered{1}, WeaklyOrdered{2})), std::weak_ordering); |
50 | assert(std::compare_three_way()(WeaklyOrdered{1}, WeaklyOrdered{2}) == std::weak_ordering::less); |
51 | assert(std::compare_three_way()(WeaklyOrdered{1}, WeaklyOrdered{1}) == std::weak_ordering::equivalent); |
52 | assert(std::compare_three_way()(WeaklyOrdered{2}, WeaklyOrdered{1}) == std::weak_ordering::greater); |
53 | |
54 | ASSERT_SAME_TYPE(decltype(std::compare_three_way()(1.0, 1.0)), std::partial_ordering); |
55 | double nan = std::numeric_limits<double>::quiet_NaN(); |
56 | assert(std::compare_three_way()(1.0, 2.0) == std::partial_ordering::less); |
57 | assert(std::compare_three_way()(1.0, 1.0) == std::partial_ordering::equivalent); |
58 | assert(std::compare_three_way()(2.0, 1.0) == std::partial_ordering::greater); |
59 | assert(std::compare_three_way()(nan, nan) == std::partial_ordering::unordered); |
60 | |
61 | // Try heterogeneous comparison. |
62 | ASSERT_SAME_TYPE(decltype(std::compare_three_way()(42.0, 42)), std::partial_ordering); |
63 | assert(std::compare_three_way()(42.0, 42) == std::partial_ordering::equivalent); |
64 | ASSERT_SAME_TYPE(decltype(std::compare_three_way()(42, 42.0)), std::partial_ordering); |
65 | assert(std::compare_three_way()(42, 42.0) == std::partial_ordering::equivalent); |
66 | |
67 | return true; |
68 | } |
69 | |
70 | int main(int, char**) |
71 | { |
72 | test(); |
73 | static_assert(test()); |
74 | |
75 | do_pointer_comparison_test(std::compare_three_way()); |
76 | |
77 | static_assert(test_sfinae(1, 2)); |
78 | static_assert(!test_sfinae(1, nullptr)); |
79 | static_assert(!test_sfinae(NotThreeWayComparable(), NotThreeWayComparable())); |
80 | |
81 | return 0; |
82 | } |
83 | |