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 // template<class T> 12 // concept totally_ordered; 13 14 #include <concepts> 15 16 #include <array> 17 #include <deque> 18 #include <forward_list> 19 #include <list> 20 #include <map> 21 #include <memory> 22 #include <optional> 23 #include <set> 24 #include <unordered_map> 25 #include <unordered_set> 26 #include <vector> 27 28 #include "compare_types.h" 29 #include "test_macros.h" 30 31 // `models_totally_ordered` checks that `std::totally_ordered` subsumes 32 // `std::equality_comparable`. This overload should *never* be called. 33 template <std::equality_comparable T> models_totally_ordered()34constexpr bool models_totally_ordered() noexcept { 35 return false; 36 } 37 38 template <std::totally_ordered T> models_totally_ordered()39constexpr bool models_totally_ordered() noexcept { 40 return true; 41 } 42 43 namespace fundamentals { 44 static_assert(models_totally_ordered<int>()); 45 static_assert(models_totally_ordered<double>()); 46 static_assert(models_totally_ordered<void*>()); 47 static_assert(models_totally_ordered<char*>()); 48 static_assert(models_totally_ordered<char const*>()); 49 static_assert(models_totally_ordered<char volatile*>()); 50 static_assert(models_totally_ordered<char const volatile*>()); 51 static_assert(models_totally_ordered<wchar_t&>()); 52 static_assert(models_totally_ordered<char8_t const&>()); 53 static_assert(models_totally_ordered<char16_t volatile&>()); 54 static_assert(models_totally_ordered<char32_t const volatile&>()); 55 static_assert(models_totally_ordered<unsigned char&&>()); 56 static_assert(models_totally_ordered<unsigned short const&&>()); 57 static_assert(models_totally_ordered<unsigned int volatile&&>()); 58 static_assert(models_totally_ordered<unsigned long const volatile&&>()); 59 static_assert(models_totally_ordered<int[5]>()); 60 static_assert(models_totally_ordered<int (*)(int)>()); 61 static_assert(models_totally_ordered<int (&)(int)>()); 62 static_assert(models_totally_ordered<int (*)(int) noexcept>()); 63 static_assert(models_totally_ordered<int (&)(int) noexcept>()); 64 65 #ifndef TEST_COMPILER_GCC 66 static_assert(!std::totally_ordered<std::nullptr_t>); 67 #endif 68 69 struct S {}; 70 static_assert(!std::totally_ordered<S>); 71 static_assert(!std::totally_ordered<int S::*>); 72 static_assert(!std::totally_ordered<int (S::*)()>); 73 static_assert(!std::totally_ordered<int (S::*)() noexcept>); 74 static_assert(!std::totally_ordered<int (S::*)() &>); 75 static_assert(!std::totally_ordered<int (S::*)() & noexcept>); 76 static_assert(!std::totally_ordered<int (S::*)() &&>); 77 static_assert(!std::totally_ordered < int (S::*)() && noexcept >); 78 static_assert(!std::totally_ordered<int (S::*)() const>); 79 static_assert(!std::totally_ordered<int (S::*)() const noexcept>); 80 static_assert(!std::totally_ordered<int (S::*)() const&>); 81 static_assert(!std::totally_ordered<int (S::*)() const & noexcept>); 82 static_assert(!std::totally_ordered<int (S::*)() const&&>); 83 static_assert(!std::totally_ordered < int (S::*)() const&& noexcept >); 84 static_assert(!std::totally_ordered<int (S::*)() volatile>); 85 static_assert(!std::totally_ordered<int (S::*)() volatile noexcept>); 86 static_assert(!std::totally_ordered<int (S::*)() volatile&>); 87 static_assert(!std::totally_ordered<int (S::*)() volatile & noexcept>); 88 static_assert(!std::totally_ordered<int (S::*)() volatile&&>); 89 static_assert(!std::totally_ordered < int (S::*)() volatile&& noexcept >); 90 static_assert(!std::totally_ordered<int (S::*)() const volatile>); 91 static_assert(!std::totally_ordered<int (S::*)() const volatile noexcept>); 92 static_assert(!std::totally_ordered<int (S::*)() const volatile&>); 93 static_assert(!std::totally_ordered<int (S::*)() const volatile & noexcept>); 94 static_assert(!std::totally_ordered<int (S::*)() const volatile&&>); 95 static_assert(!std::totally_ordered < int (S::*)() const volatile&& noexcept >); 96 97 static_assert(!std::totally_ordered<void>); 98 } // namespace fundamentals 99 100 namespace standard_types { 101 static_assert(models_totally_ordered<std::array<int, 10> >()); 102 static_assert(models_totally_ordered<std::deque<int> >()); 103 static_assert(models_totally_ordered<std::forward_list<int> >()); 104 static_assert(models_totally_ordered<std::list<int> >()); 105 static_assert(models_totally_ordered<std::optional<int> >()); 106 static_assert(models_totally_ordered<std::set<int> >()); 107 static_assert(models_totally_ordered<std::vector<bool> >()); 108 static_assert(models_totally_ordered<std::vector<int> >()); 109 110 static_assert(!std::totally_ordered<std::unordered_map<int, void*> >); 111 static_assert(!std::totally_ordered<std::unordered_set<int> >); 112 113 struct A {}; 114 // FIXME(cjdb): uncomment when operator<=> is implemented for each of these types. 115 // static_assert(!std::totally_ordered<std::array<A, 10> >); 116 // static_assert(!std::totally_ordered<std::deque<A> >); 117 // static_assert(!std::totally_ordered<std::forward_list<A> >); 118 // static_assert(!std::totally_ordered<std::list<A> >); 119 // static_assert(!std::totally_ordered<std::set<A> >); 120 // static_assert(!std::totally_ordered<std::vector<A> >); 121 } // namespace standard_types 122 123 namespace types_fit_for_purpose { 124 static_assert(models_totally_ordered<member_three_way_comparable>()); 125 static_assert(models_totally_ordered<friend_three_way_comparable>()); 126 static_assert(models_totally_ordered<explicit_operators>()); 127 static_assert(models_totally_ordered<different_return_types>()); 128 static_assert(!std::totally_ordered<cxx20_member_eq>); 129 static_assert(!std::totally_ordered<cxx20_friend_eq>); 130 static_assert(!std::totally_ordered<one_member_one_friend>); 131 static_assert(!std::totally_ordered<equality_comparable_with_ec1>); 132 133 static_assert(!std::totally_ordered<no_eq>); 134 static_assert(!std::totally_ordered<no_neq>); 135 static_assert(!std::totally_ordered<no_lt>); 136 static_assert(!std::totally_ordered<no_gt>); 137 static_assert(!std::totally_ordered<no_le>); 138 static_assert(!std::totally_ordered<no_ge>); 139 140 static_assert(!std::totally_ordered<wrong_return_type_eq>); 141 static_assert(!std::totally_ordered<wrong_return_type_ne>); 142 static_assert(!std::totally_ordered<wrong_return_type_lt>); 143 static_assert(!std::totally_ordered<wrong_return_type_gt>); 144 static_assert(!std::totally_ordered<wrong_return_type_le>); 145 static_assert(!std::totally_ordered<wrong_return_type_ge>); 146 static_assert(!std::totally_ordered<wrong_return_type>); 147 148 static_assert(!std::totally_ordered<cxx20_member_eq_operator_with_deleted_ne>); 149 static_assert(!std::totally_ordered<cxx20_friend_eq_operator_with_deleted_ne>); 150 static_assert( 151 !std::totally_ordered<member_three_way_comparable_with_deleted_eq>); 152 static_assert( 153 !std::totally_ordered<member_three_way_comparable_with_deleted_ne>); 154 static_assert( 155 !std::totally_ordered<friend_three_way_comparable_with_deleted_eq>); 156 static_assert( 157 !std::totally_ordered<friend_three_way_comparable_with_deleted_ne>); 158 159 static_assert(!std::totally_ordered<eq_returns_explicit_bool>); 160 static_assert(!std::totally_ordered<ne_returns_explicit_bool>); 161 static_assert(!std::totally_ordered<lt_returns_explicit_bool>); 162 static_assert(!std::totally_ordered<gt_returns_explicit_bool>); 163 static_assert(!std::totally_ordered<le_returns_explicit_bool>); 164 static_assert(!std::totally_ordered<ge_returns_explicit_bool>); 165 static_assert(std::totally_ordered<returns_true_type>); 166 static_assert(std::totally_ordered<returns_int_ptr>); 167 168 static_assert(std::totally_ordered<partial_ordering_totally_ordered_with>); 169 static_assert(std::totally_ordered<weak_ordering_totally_ordered_with>); 170 static_assert(std::totally_ordered<strong_ordering_totally_ordered_with>); 171 } // namespace types_fit_for_purpose 172 main(int,char **)173int main(int, char**) { return 0; } 174