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