1 // RUN: %clang_cc1 -std=c++2a -verify %s
3 template<typename T
> concept C
= T::f(); // #C
4 template<typename T
> concept D
= C
<T
> && T::g();
5 template<typename T
> concept F
= T::f(); // #F
6 template<template<C
> class P
> struct S1
{ }; // #S1
8 template<C
> struct X
{ };
10 template<D
> struct Y
{ }; // #Y
11 template<typename T
> struct Z
{ };
12 template<F
> struct W
{ }; // #W
15 // expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
16 // expected-note@#S1 {{'P' declared here}}
17 // expected-note@#Y {{'Y' declared here}}
20 // expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
21 // expected-note@#S1 {{'P' declared here}}
22 // expected-note@#W {{'W' declared here}}
23 // expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
24 // expected-note@#C 1-2{{similar constraint}}
26 template<template<typename
> class P
> struct S2
{ };
32 template <template <typename
...> class C
>
36 using N
= typename
T::type
;
41 template<template<typename T
> requires C
<T
> class P
> struct S4
{ }; // #S4
45 // expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
46 // expected-note@#S4 {{'P' declared here}}
47 // expected-note@#Y {{'Y' declared here}}
50 // expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
51 // expected-note@#S4 {{'P' declared here}}
52 // expected-note@#W {{'W' declared here}}
54 template<template<typename T
> requires C
<T
> typename U
> struct S5
{
55 template<typename T
> static U
<T
> V
;
60 // FIXME: Wait the standard to clarify the intent.
61 template<> template<> Z
<Nothing
> S5
<Z
>::V
<Nothing
>;
69 concept False
= false; // #False
71 template <class> struct S
{};
73 template<template<True T
> typename Wrapper
>
74 using Test
= Wrapper
<int>;
76 template<template<False T
> typename Wrapper
> // #TTP-Wrapper
77 using Test
= Wrapper
<int>; // expected-error {{constraints not satisfied for template template parameter 'Wrapper' [with T = int]}}
79 // expected-note@#TTP-Wrapper {{'int' does not satisfy 'False'}}
80 // expected-note@#False {{evaluated to false}}
82 template <typename U
, template<False
> typename T
>
83 void foo(T
<U
>); // #foo
86 foo
<int>(S
<int>{}); // expected-error {{no matching function for call to 'foo'}}
87 // expected-note@#foo {{substitution failure [with U = int]: constraints not satisfied for template template parameter 'T' [with $0 = int]}}