1 // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
3 static_assert(requires
{ { 0 }; });
4 static_assert(requires
{ { "aaaa" }; });
5 static_assert(requires
{ { (0).da
}; }); // expected-error{{member reference base type 'int' is not a structure or union}}
8 static_assert(requires
{ { foo() }; });
10 // Substitution failure in expression
14 B
operator+(const B
&other
) const { return other
; }
17 C
operator+(C
&other
) const { return other
; }
20 template<typename T
> requires
requires (T a
, const T
& b
) { { a
+ b
}; } // expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('A' and 'const A')}} expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('C' and 'const C')}}
24 using r1i2
= r1
<A
>; // expected-error{{constraints not satisfied for class template 'r1' [with T = A]}}
26 using r1i4
= r1
<C
>; // expected-error{{constraints not satisfied for class template 'r1' [with T = C]}}
28 struct D
{ void foo() {} };
30 template<typename T
> requires
requires (T a
) { { a
.foo() }; } // expected-note{{because 'a.foo()' would be invalid: no member named 'foo' in 'A'}} expected-note{{because 'a.foo()' would be invalid: member reference base type 'int' is not a structure or union}} expected-note{{because 'a.foo()' would be invalid: 'this' argument to member function 'foo' has type 'const D', but function is not marked const}}
33 using r2i1
= r2
<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
34 using r2i2
= r2
<A
>; // expected-error{{constraints not satisfied for class template 'r2' [with T = A]}}
36 using r2i4
= r2
<const D
>; // expected-error{{constraints not satisfied for class template 'r2' [with T = const D]}}
38 template<typename T
> requires requires
{ { sizeof(T
) }; } // expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}} expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'nonexistent'}}
44 using r3i4
= r3
<void>; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}}
45 using r3i4
= r3
<class nonexistent
>; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}}
47 // Non-dependent expressions
49 template<typename T
> requires
requires (T t
) { { 0 }; { "a" }; { (void)'a' }; }
53 using r4i2
= r4
<int[10]>;
54 using r4i3
= r4
<int(int)>;
56 // Noexcept requirement
58 static_assert(!requires
{ { maythrow() } noexcept
; });
59 static_assert(requires
{ { 1 } noexcept
; });
61 struct E
{ void operator++(int) noexcept
; };
62 struct F
{ void operator++(int); };
64 template<typename T
> requires
requires (T t
) { { t
++ } noexcept
; } // expected-note{{because 't ++' may throw an exception}}
69 using r5i2
= r5
<F
>; // expected-error{{constraints not satisfied for class template 'r5' [with T = F]}}
71 template<typename T
> requires
requires (T t
) { { t
.foo() } noexcept
; } // expected-note{{because 't.foo()' would be invalid: no member named 'foo' in 'E'}}
74 using r6i
= r6
<E
>; // expected-error{{constraints not satisfied for class template 'r6' [with T = E]}}
76 template<typename T
, typename U
>
77 constexpr bool is_same_v
= false;
80 constexpr bool is_same_v
<T
, T
> = true;
82 template<typename T
> struct remove_reference
{ using type
= T
; };
83 template<typename T
> struct remove_reference
<T
&> { using type
= T
; };
85 template<typename T
, typename U
>
86 concept Same
= is_same_v
<T
, U
>;
89 concept Large
= sizeof(typename remove_reference
<T
>::type
) >= 4;
90 // expected-note@-1{{because 'sizeof(typename remove_reference<short &>::type) >= 4' (2 >= 4) evaluated to false}}
92 template<typename T
> requires
requires (T t
) { { t
} -> Large
; } // expected-note{{because 'short &' does not satisfy 'Large':}}
96 using r7i2
= r7
<short>; // expected-error{{constraints not satisfied for class template 'r7' [with T = short]}}
98 template<typename T
> requires
requires (T t
) { { t
} -> Same
<T
&>; }
101 using r8i1
= r8
<int>;
102 using r8i2
= r8
<short*>;
104 // Substitution failure in type constraint
106 template<typename T
> requires
requires (T t
) { { t
} -> Same
<typename
T::type
&>; }
107 // expected-note@-1{{because 'Same<expr-type, typename T::type &>' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
110 struct M
{ using type
= M
; };
113 using r9i2
= r9
<int>; // expected-error{{constraints not satisfied for class template 'r9' [with T = int]}}
115 // Substitution failure in both expression and return type requirement
117 template<typename T
> requires
requires (T t
) { { t
.foo() } -> Same
<typename
T::type
>; } // expected-note{{because 't.foo()' would be invalid: member reference base type 'int' is not a structure or union}}
120 using r10i
= r10
<int>; // expected-error{{constraints not satisfied for class template 'r10' [with T = int]}}
122 // Non-type concept in type constraint
125 concept IsEven
= (T
% 2) == 0;
127 template<typename T
> requires
requires (T t
) { { t
} -> IsEven
; } // expected-error{{concept named in type constraint is not a type concept}}
133 requires
requires (int b
) {
137 { static_cast<int&&>(a
) } -> Same
<int&&>;
139 template void f1
<>();
141 // C++ [expr.prim.req.compound] Example
142 namespace std_example
{
143 template<typename T
> concept C1
=
148 template<typename T
, typename U
> constexpr bool is_same_v
= false;
149 template<typename T
> constexpr bool is_same_v
<T
, T
> = true;
151 template<typename T
, typename U
> concept same_as
= is_same_v
<T
, U
>;
152 // expected-note@-1 {{because 'is_same_v<int, int *>' evaluated to false}}
154 static_assert(C1
<int>);
155 static_assert(C1
<int*>);
156 template<C1 T
> struct C1_check
{};
157 using c1c1
= C1_check
<int>;
158 using c1c2
= C1_check
<int[10]>;
160 template<typename T
> concept C2
=
162 {*x
} -> same_as
<typename
T::inner
>;
163 // expected-note@-1{{because type constraint 'same_as<int, typename T2::inner>' was not satisfied:}}
164 // expected-note@-2{{because '*x' would be invalid: indirection requires pointer operand ('int' invalid)}}
169 inner
operator *() { return 0; }
173 int operator *() { return 0; }
175 static_assert(C2
<T1
>);
176 template<C2 T
> struct C2_check
{}; // expected-note{{because 'int' does not satisfy 'C2'}} expected-note{{because 'std_example::T2' does not satisfy 'C2'}}
177 using c2c1
= C2_check
<int>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = int]}}
178 using c2c2
= C2_check
<T2
>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::T2]}}
181 void g(T t
) noexcept(sizeof(T
) == 1) {}
183 template<typename T
> concept C5
=
185 {g(x
)} noexcept
; // expected-note{{because 'g(x)' may throw an exception}}
188 static_assert(C5
<char>);
189 template<C5 T
> struct C5_check
{}; // expected-note{{because 'short' does not satisfy 'C5'}}
190 using c5
= C5_check
<short>; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}}
193 namespace access_checks
{
194 namespace in_return_type_requirement
{
196 // https://github.com/llvm/llvm-project/issues/93788
197 template <typename From
, typename To
>
198 concept is_assignable
= requires(From from
, To to
) {
202 template <typename T
>
205 using public_type
= int;
207 using private_type
= int;
210 template <typename T
>
211 concept has_field
= requires(T t
) {
212 { t
.field
} -> is_assignable
<typename trait
<T
>::private_type
>; // expected-note {{'private_type' is a private member}}
214 template <typename T
>
215 concept has_field2
= requires(T t
) {
216 { t
.field
} -> is_assignable
<typename trait
<T
>::public_type
>;
222 static_assert(has_field
<A
>); // expected-error {{static assertion failed}} \
223 // expected-note {{because 'A' does not satisfy 'has_field'}}
224 static_assert(has_field2
<A
>);
226 } // namespace access_checks
227 } // namespace in_return_type_requirement