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 13 // template<class T, class U = T> struct compare_three_way_result; 14 // template<class T, class U = T> 15 // using compare_three_way_result_t = typename compare_three_way_result<T, U>::type; 16 17 #include <compare> 18 19 #include "test_macros.h" 20 21 template<class T> 22 concept has_no_nested_type = !requires { typename T::type; }; 23 24 ASSERT_SAME_TYPE(std::compare_three_way_result_t<int>, std::strong_ordering); 25 ASSERT_SAME_TYPE(std::compare_three_way_result_t<float>, std::partial_ordering); 26 ASSERT_SAME_TYPE(std::compare_three_way_result_t<unsigned>, std::strong_ordering); 27 28 ASSERT_SAME_TYPE(std::compare_three_way_result_t<int, int>, std::strong_ordering); 29 ASSERT_SAME_TYPE(std::compare_three_way_result_t<int, float>, std::partial_ordering); 30 ASSERT_SAME_TYPE(std::compare_three_way_result_t<float, int>, std::partial_ordering); 31 ASSERT_SAME_TYPE(std::compare_three_way_result_t<float, float>, std::partial_ordering); 32 ASSERT_SAME_TYPE(std::compare_three_way_result_t<float, unsigned>, std::partial_ordering); 33 ASSERT_SAME_TYPE(std::compare_three_way_result_t<unsigned, float>, std::partial_ordering); 34 ASSERT_SAME_TYPE(std::compare_three_way_result_t<unsigned, unsigned>, std::strong_ordering); 35 36 ASSERT_SAME_TYPE(std::compare_three_way_result_t<const int&>, std::strong_ordering); 37 ASSERT_SAME_TYPE(std::compare_three_way_result_t<const int&, int>, std::strong_ordering); 38 ASSERT_SAME_TYPE(std::compare_three_way_result_t<const int*>, std::strong_ordering); 39 ASSERT_SAME_TYPE(std::compare_three_way_result_t<const int*, int*>, std::strong_ordering); 40 41 static_assert(has_no_nested_type<std::compare_three_way_result<void>>); 42 static_assert(has_no_nested_type<std::compare_three_way_result<void, void>>); 43 static_assert(has_no_nested_type<std::compare_three_way_result<int, void>>); 44 static_assert(has_no_nested_type<std::compare_three_way_result<int, int*>>); 45 static_assert(has_no_nested_type<std::compare_three_way_result<int, unsigned>>); 46 static_assert(has_no_nested_type<std::compare_three_way_result<unsigned, int>>); 47 48 struct A { 49 float operator<=>(const A&) const; // a non-comparison-category type is OK 50 }; 51 ASSERT_SAME_TYPE(std::compare_three_way_result_t<A>, float); 52 ASSERT_SAME_TYPE(std::compare_three_way_result_t<A, A>, float); 53 54 struct B { 55 using T = int(&)(); 56 T operator<=>(const B&) const; // no decay takes place either 57 }; 58 ASSERT_SAME_TYPE(std::compare_three_way_result_t<B>, int(&)()); 59 ASSERT_SAME_TYPE(std::compare_three_way_result_t<B, B>, int(&)()); 60 61 struct C { 62 std::strong_ordering operator<=>(C&); // C isn't const-comparable 63 }; 64 static_assert(has_no_nested_type<std::compare_three_way_result<C>>); 65 static_assert(has_no_nested_type<std::compare_three_way_result<C&>>); 66 static_assert(has_no_nested_type<std::compare_three_way_result<C&&>>); 67 68 static_assert(has_no_nested_type<std::compare_three_way_result<C, C>>); 69 static_assert(has_no_nested_type<std::compare_three_way_result<C&, C&>>); 70 static_assert(has_no_nested_type<std::compare_three_way_result<C&&, C&&>>); 71 72 struct D { 73 std::strong_ordering operator<=>(D&) &; 74 std::strong_ordering operator<=>(D&&) &&; 75 std::weak_ordering operator<=>(const D&) const&; // comparison is always done by const& 76 std::strong_ordering operator<=>(const D&&) const&&; 77 }; 78 ASSERT_SAME_TYPE(std::compare_three_way_result_t<D>, std::weak_ordering); 79 ASSERT_SAME_TYPE(std::compare_three_way_result_t<D&>, std::weak_ordering); 80 ASSERT_SAME_TYPE(std::compare_three_way_result_t<D&&>, std::weak_ordering); 81 ASSERT_SAME_TYPE(std::compare_three_way_result_t<const D&>, std::weak_ordering); 82 ASSERT_SAME_TYPE(std::compare_three_way_result_t<const D&&>, std::weak_ordering); 83 84 ASSERT_SAME_TYPE(std::compare_three_way_result_t<D, D>, std::weak_ordering); 85 ASSERT_SAME_TYPE(std::compare_three_way_result_t<D&, D&>, std::weak_ordering); 86 ASSERT_SAME_TYPE(std::compare_three_way_result_t<D&&, D&&>, std::weak_ordering); 87 ASSERT_SAME_TYPE(std::compare_three_way_result_t<const D&, const D&>, std::weak_ordering); 88 ASSERT_SAME_TYPE(std::compare_three_way_result_t<const D&&, const D&&>, std::weak_ordering); 89