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 regular = see below;
14 
15 #include <concepts>
16 
17 #include <deque>
18 #include <forward_list>
19 #include <list>
20 #include <map>
21 #include <memory>
22 #include <optional>
23 #include <stdexcept>
24 #include <tuple>
25 #include <unordered_map>
26 #include <vector>
27 
28 #include "type_classification/moveconstructible.h"
29 #include "type_classification/semiregular.h"
30 
31 static_assert(std::regular<int>);
32 static_assert(std::regular<float>);
33 static_assert(std::regular<double>);
34 static_assert(std::regular<long double>);
35 static_assert(std::regular<int volatile>);
36 static_assert(std::regular<void*>);
37 static_assert(std::regular<int*>);
38 static_assert(std::regular<int const*>);
39 static_assert(std::regular<int volatile*>);
40 static_assert(std::regular<int volatile const*>);
41 static_assert(std::regular<int (*)()>);
42 
43 struct S {};
44 static_assert(!std::regular<S>);
45 static_assert(std::regular<int S::*>);
46 static_assert(std::regular<int (S::*)()>);
47 static_assert(std::regular<int (S::*)() noexcept>);
48 static_assert(std::regular<int (S::*)() &>);
49 static_assert(std::regular<int (S::*)() & noexcept>);
50 static_assert(std::regular<int (S::*)() &&>);
51 static_assert(std::regular<int (S::*)() && noexcept>);
52 static_assert(std::regular<int (S::*)() const>);
53 static_assert(std::regular<int (S::*)() const noexcept>);
54 static_assert(std::regular<int (S::*)() const&>);
55 static_assert(std::regular<int (S::*)() const & noexcept>);
56 static_assert(std::regular<int (S::*)() const&&>);
57 static_assert(std::regular<int (S::*)() const && noexcept>);
58 static_assert(std::regular<int (S::*)() volatile>);
59 static_assert(std::regular<int (S::*)() volatile noexcept>);
60 static_assert(std::regular<int (S::*)() volatile&>);
61 static_assert(std::regular<int (S::*)() volatile & noexcept>);
62 static_assert(std::regular<int (S::*)() volatile&&>);
63 static_assert(std::regular<int (S::*)() volatile && noexcept>);
64 static_assert(std::regular<int (S::*)() const volatile>);
65 static_assert(std::regular<int (S::*)() const volatile noexcept>);
66 static_assert(std::regular<int (S::*)() const volatile&>);
67 static_assert(std::regular<int (S::*)() const volatile & noexcept>);
68 static_assert(std::regular<int (S::*)() const volatile&&>);
69 static_assert(std::regular<int (S::*)() const volatile && noexcept>);
70 
71 union U {};
72 static_assert(!std::regular<U>);
73 static_assert(std::regular<int U::*>);
74 static_assert(std::regular<int (U::*)()>);
75 static_assert(std::regular<int (U::*)() noexcept>);
76 static_assert(std::regular<int (U::*)() &>);
77 static_assert(std::regular<int (U::*)() & noexcept>);
78 static_assert(std::regular<int (U::*)() &&>);
79 static_assert(std::regular<int (U::*)() && noexcept>);
80 static_assert(std::regular<int (U::*)() const>);
81 static_assert(std::regular<int (U::*)() const noexcept>);
82 static_assert(std::regular<int (U::*)() const&>);
83 static_assert(std::regular<int (U::*)() const & noexcept>);
84 static_assert(std::regular<int (U::*)() const&&>);
85 static_assert(std::regular<int (U::*)() const && noexcept>);
86 static_assert(std::regular<int (U::*)() volatile>);
87 static_assert(std::regular<int (U::*)() volatile noexcept>);
88 static_assert(std::regular<int (U::*)() volatile&>);
89 static_assert(std::regular<int (U::*)() volatile & noexcept>);
90 static_assert(std::regular<int (U::*)() volatile&&>);
91 static_assert(std::regular<int (U::*)() volatile && noexcept>);
92 static_assert(std::regular<int (U::*)() const volatile>);
93 static_assert(std::regular<int (U::*)() const volatile noexcept>);
94 static_assert(std::regular<int (U::*)() const volatile&>);
95 static_assert(std::regular<int (U::*)() const volatile & noexcept>);
96 static_assert(std::regular<int (U::*)() const volatile&&>);
97 static_assert(std::regular<int (U::*)() const volatile && noexcept>);
98 
99 static_assert(std::regular<std::vector<int> >);
100 static_assert(std::regular<std::deque<int> >);
101 static_assert(std::regular<std::forward_list<int> >);
102 static_assert(std::regular<std::list<int> >);
103 static_assert(std::regular<std::shared_ptr<std::unique_ptr<int> > >);
104 static_assert(std::regular<std::optional<std::vector<int> > >);
105 static_assert(std::regular<std::vector<int> >);
106 static_assert(std::regular<std::vector<std::unique_ptr<int> > >);
107 static_assert(std::semiregular<std::in_place_t> &&
108               !std::regular<std::in_place_t>);
109 
110 static_assert(!std::regular<has_volatile_member>);
111 static_assert(!std::regular<has_array_member>);
112 
113 // Not objects
114 static_assert(!std::regular<void>);
115 static_assert(!std::regular<int&>);
116 static_assert(!std::regular<int const&>);
117 static_assert(!std::regular<int volatile&>);
118 static_assert(!std::regular<int const volatile&>);
119 static_assert(!std::regular<int&&>);
120 static_assert(!std::regular<int const&&>);
121 static_assert(!std::regular<int volatile&&>);
122 static_assert(!std::regular<int const volatile&&>);
123 static_assert(!std::regular<int()>);
124 static_assert(!std::regular<int (&)()>);
125 static_assert(!std::regular<int[5]>);
126 
127 // not copyable
128 static_assert(!std::regular<std::unique_ptr<int> >);
129 static_assert(!std::regular<int const>);
130 static_assert(!std::regular<int const volatile>);
131 static_assert(!std::regular<volatile_copy_assignment volatile>);
132 static_assert(!std::regular<no_copy_constructor>);
133 static_assert(!std::regular<no_copy_assignment>);
134 static_assert(!std::regular<no_copy_assignment_mutable>);
135 static_assert(!std::regular<derived_from_noncopyable>);
136 static_assert(!std::regular<has_noncopyable>);
137 static_assert(!std::regular<has_const_member>);
138 static_assert(!std::regular<has_cv_member>);
139 static_assert(!std::regular<has_lvalue_reference_member>);
140 static_assert(!std::regular<has_rvalue_reference_member>);
141 static_assert(!std::regular<has_function_ref_member>);
142 static_assert(!std::regular<deleted_assignment_from_const_rvalue>);
143 
144 // not default_initializable
145 static_assert(!std::regular<std::runtime_error>);
146 static_assert(
147     !std::regular<std::tuple<std::runtime_error, std::overflow_error> >);
148 static_assert(!std::regular<std::nullopt_t>);
149 static_assert(!std::regular<no_copy_constructor>);
150 static_assert(!std::regular<no_copy_assignment>);
151 static_assert(std::is_copy_assignable_v<no_copy_assignment_mutable> &&
152               !std::regular<no_copy_assignment_mutable>);
153 static_assert(!std::regular<derived_from_noncopyable>);
154 static_assert(!std::regular<has_noncopyable>);
155 
156 static_assert(!std::regular<derived_from_non_default_initializable>);
157 static_assert(!std::regular<has_non_default_initializable>);
158 
159 // not equality_comparable
160 static_assert(!std::regular<const_copy_assignment const>);
161 static_assert(!std::regular<cv_copy_assignment const volatile>);
162 
163 struct is_equality_comparable {
164   bool operator==(is_equality_comparable const&) const = default;
165 };
166 static_assert(std::regular<is_equality_comparable>);
167 
168 int main(int, char**) { return 0; }
169