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.
32template <std::equality_comparable T>
33constexpr bool models_totally_ordered() noexcept {
34 return false;
35}
36
37template <std::totally_ordered T>
38constexpr bool models_totally_ordered() noexcept {
39 return true;
40}
41
42namespace fundamentals {
43static_assert(models_totally_ordered<int>());
44static_assert(models_totally_ordered<double>());
45static_assert(models_totally_ordered<void*>());
46static_assert(models_totally_ordered<char*>());
47static_assert(models_totally_ordered<char const*>());
48static_assert(models_totally_ordered<char volatile*>());
49static_assert(models_totally_ordered<char const volatile*>());
50static_assert(models_totally_ordered<wchar_t&>());
51static_assert(models_totally_ordered<char8_t const&>());
52static_assert(models_totally_ordered<char16_t volatile&>());
53static_assert(models_totally_ordered<char32_t const volatile&>());
54static_assert(models_totally_ordered<unsigned char&&>());
55static_assert(models_totally_ordered<unsigned short const&&>());
56static_assert(models_totally_ordered<unsigned int volatile&&>());
57static_assert(models_totally_ordered<unsigned long const volatile&&>());
58// Array comparisons are ill-formed in C++26
59#if TEST_STD_VER <= 23
60static_assert(models_totally_ordered<int[5]>());
61#endif
62static_assert(models_totally_ordered<int (*)(int)>());
63static_assert(models_totally_ordered<int (&)(int)>());
64static_assert(models_totally_ordered<int (*)(int) noexcept>());
65static_assert(models_totally_ordered<int (&)(int) noexcept>());
66
67#ifndef TEST_COMPILER_GCC
68static_assert(!std::totally_ordered<std::nullptr_t>);
69#endif
70
71struct S {};
72static_assert(!std::totally_ordered<S>);
73static_assert(!std::totally_ordered<int S::*>);
74static_assert(!std::totally_ordered<int (S::*)()>);
75static_assert(!std::totally_ordered<int (S::*)() noexcept>);
76static_assert(!std::totally_ordered<int (S::*)() &>);
77static_assert(!std::totally_ordered<int (S::*)() & noexcept>);
78static_assert(!std::totally_ordered<int (S::*)() &&>);
79static_assert(!std::totally_ordered < int(S::*)() && noexcept >);
80static_assert(!std::totally_ordered<int (S::*)() const>);
81static_assert(!std::totally_ordered<int (S::*)() const noexcept>);
82static_assert(!std::totally_ordered<int (S::*)() const&>);
83static_assert(!std::totally_ordered<int (S::*)() const & noexcept>);
84static_assert(!std::totally_ordered<int (S::*)() const&&>);
85static_assert(!std::totally_ordered < int(S::*)() const&& noexcept >);
86static_assert(!std::totally_ordered<int (S::*)() volatile>);
87static_assert(!std::totally_ordered<int (S::*)() volatile noexcept>);
88static_assert(!std::totally_ordered<int (S::*)() volatile&>);
89static_assert(!std::totally_ordered<int (S::*)() volatile & noexcept>);
90static_assert(!std::totally_ordered<int (S::*)() volatile&&>);
91static_assert(!std::totally_ordered < int(S::*)() volatile && noexcept >);
92static_assert(!std::totally_ordered<int (S::*)() const volatile>);
93static_assert(!std::totally_ordered<int (S::*)() const volatile noexcept>);
94static_assert(!std::totally_ordered<int (S::*)() const volatile&>);
95static_assert(!std::totally_ordered<int (S::*)() const volatile & noexcept>);
96static_assert(!std::totally_ordered<int (S::*)() const volatile&&>);
97static_assert(!std::totally_ordered < int(S::*)() const volatile&& noexcept >);
98
99static_assert(!std::totally_ordered<void>);
100} // namespace fundamentals
101
102namespace standard_types {
103static_assert(models_totally_ordered<std::array<int, 10> >());
104static_assert(models_totally_ordered<std::deque<int> >());
105static_assert(models_totally_ordered<std::forward_list<int> >());
106static_assert(models_totally_ordered<std::list<int> >());
107static_assert(models_totally_ordered<std::optional<int> >());
108static_assert(models_totally_ordered<std::set<int> >());
109static_assert(models_totally_ordered<std::vector<bool> >());
110static_assert(models_totally_ordered<std::vector<int> >());
111
112static_assert(!std::totally_ordered<std::unordered_map<int, void*> >);
113static_assert(!std::totally_ordered<std::unordered_set<int> >);
114
115struct A {};
116static_assert(!std::totally_ordered<std::array<A, 10> >);
117static_assert(!std::totally_ordered<std::deque<A> >);
118static_assert(!std::totally_ordered<std::forward_list<A> >);
119static_assert(!std::totally_ordered<std::list<A> >);
120static_assert(!std::totally_ordered<std::set<A> >);
121static_assert(!std::totally_ordered<std::vector<A> >);
122} // namespace standard_types
123
124namespace types_fit_for_purpose {
125static_assert(models_totally_ordered<member_three_way_comparable>());
126static_assert(models_totally_ordered<friend_three_way_comparable>());
127static_assert(models_totally_ordered<explicit_operators>());
128static_assert(models_totally_ordered<different_return_types>());
129static_assert(!std::totally_ordered<cxx20_member_eq>);
130static_assert(!std::totally_ordered<cxx20_friend_eq>);
131static_assert(!std::totally_ordered<one_member_one_friend>);
132static_assert(!std::totally_ordered<equality_comparable_with_ec1>);
133
134static_assert(!std::totally_ordered<no_eq>);
135static_assert(!std::totally_ordered<no_neq>);
136static_assert(!std::totally_ordered<no_lt>);
137static_assert(!std::totally_ordered<no_gt>);
138static_assert(!std::totally_ordered<no_le>);
139static_assert(!std::totally_ordered<no_ge>);
140
141static_assert(!std::totally_ordered<wrong_return_type_eq>);
142static_assert(!std::totally_ordered<wrong_return_type_ne>);
143static_assert(!std::totally_ordered<wrong_return_type_lt>);
144static_assert(!std::totally_ordered<wrong_return_type_gt>);
145static_assert(!std::totally_ordered<wrong_return_type_le>);
146static_assert(!std::totally_ordered<wrong_return_type_ge>);
147static_assert(!std::totally_ordered<wrong_return_type>);
148
149static_assert(!std::totally_ordered<cxx20_member_eq_operator_with_deleted_ne>);
150static_assert(!std::totally_ordered<cxx20_friend_eq_operator_with_deleted_ne>);
151static_assert(!std::totally_ordered<member_three_way_comparable_with_deleted_eq>);
152static_assert(!std::totally_ordered<member_three_way_comparable_with_deleted_ne>);
153static_assert(!std::totally_ordered<friend_three_way_comparable_with_deleted_eq>);
154static_assert(!std::totally_ordered<friend_three_way_comparable_with_deleted_ne>);
155
156static_assert(!std::totally_ordered<eq_returns_explicit_bool>);
157static_assert(!std::totally_ordered<ne_returns_explicit_bool>);
158static_assert(!std::totally_ordered<lt_returns_explicit_bool>);
159static_assert(!std::totally_ordered<gt_returns_explicit_bool>);
160static_assert(!std::totally_ordered<le_returns_explicit_bool>);
161static_assert(!std::totally_ordered<ge_returns_explicit_bool>);
162static_assert(std::totally_ordered<returns_true_type>);
163static_assert(std::totally_ordered<returns_int_ptr>);
164
165static_assert(std::totally_ordered<partial_ordering_totally_ordered_with>);
166static_assert(std::totally_ordered<weak_ordering_totally_ordered_with>);
167static_assert(std::totally_ordered<strong_ordering_totally_ordered_with>);
168} // namespace types_fit_for_purpose
169

source code of libcxx/test/std/concepts/concepts.compare/concepts.totallyordered/totally_ordered.compile.pass.cpp