1 // RUN: %clang_cc1 -std=c++2a -x c++ -verify %s
3 template<typename T
> requires (sizeof(T
) >= 4)
4 // expected-note@-1{{similar constraint expressions not considered equivalen}}
5 class A
{}; // expected-note{{template is declared here}}
7 template<typename T
> requires (sizeof(T
) >= 4 && sizeof(T
) <= 10)
8 // expected-note@-1{{similar constraint expression here}}
10 class A
<T
>{}; // expected-error{{class template partial specialization is not more specialized than the primary template}}
13 concept C1
= sizeof(T
) >= 4;
15 template<typename T
> requires C1
<T
>
18 template<typename T
> requires (C1
<T
> && sizeof(T
) <= 10)
22 concept C2
= sizeof(T
) > 1 && sizeof(T
) <= 8;
27 template<typename T
> requires C1
<T
>
31 class D
{}; // expected-note{{previous definition is here}}
34 class D
<T
>{}; // expected-error{{class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}} expected-error{{redefinition of 'D'}}
36 template<typename T
> requires C1
<T
> // expected-note{{previous template declaration is here}}
39 template<typename T
> // expected-error{{requires clause differs in template redeclaration}}
40 class E
<T
>{}; // expected-error{{class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
43 struct F
{ enum{ value
= 1 }; };
45 template<typename T
> requires C1
<T
> && C2
<T
>
46 struct F
<T
>{ enum{ value
= 2 }; };
48 template<typename T
> requires C1
<T
> || C2
<T
>
49 struct F
<T
>{ enum{ value
= 3 }; };
51 static_assert(F
<unsigned>::value
== 2);
52 static_assert(F
<char[10]>::value
== 3);
53 static_assert(F
<char>::value
== 1);
63 requires C1
<T
> && C2
<T
>
69 requires C1
<T
> || C2
<T
>
75 static_assert(S
<1>::F
<unsigned>::value
== 2);
76 static_assert(S
<1>::F
<char[10]>::value
== 3);
77 static_assert(S
<1>::F
<char>::value
== 1);
79 // Make sure atomic constraints subsume each other only if their parameter
80 // mappings are identical.
82 template<typename T
, typename U
> requires C2
<T
>
83 struct I
{ }; // expected-note {{template is declared here}}
85 template<typename T
, typename U
> requires C2
<U
>
86 struct I
<T
, U
> { }; // expected-error {{class template partial specialization is not more specialized than the primary template}}
88 template<typename T
, typename U
> requires C2
<T
> && C2
<U
>