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