1 // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
2 
3 template<typename T> requires sizeof(T) >= 4
4 bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
5 
6 template<typename T> requires sizeof(T) >= 4 && sizeof(T) <= 10
7 bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
8 
9 bool av = a<unsigned>(); // expected-error {{call to 'a' is ambiguous}}
10 
11 template<typename T>
12 concept C1 = sizeof(T) >= 4;
13 
14 template<typename T> requires C1<T>
15 constexpr bool b() { return false; }
16 
17 template<typename T> requires C1<T> && sizeof(T) <= 10
18 constexpr bool b() { return true; }
19 
20 static_assert(b<int>());
21 static_assert(!b<int[10]>());
22 
23 template<typename T>
24 concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
25 
26 template<typename T>
27 bool c() { return false; }
28 
29 template<typename T> requires C1<T>
30 bool c() { return true; }
31 
32 template<typename T> requires C1<T>
33 constexpr bool d() { return false; }
34 
35 template<typename T>
36 constexpr bool d() { return true; }
37 
38 static_assert(!d<int>());
39 
40 template<typename T>
41 constexpr int e() { return 1; }
42 
43 template<typename T> requires C1<T> && C2<T>
44 constexpr int e() { return 2; }
45 
46 template<typename T> requires C1<T> || C2<T>
47 constexpr int e() { return 3; }
48 
49 static_assert(e<unsigned>() == 2);
50 static_assert(e<char[10]>() == 3);
51 static_assert(e<char>() == 1);
52 
53 template<class T, class U>
54 concept BiggerThan = sizeof(T) > sizeof(U);
55 
56 template<class T>
57 concept BiggerThanInt = BiggerThan<T, int>;
58 
59 template<class T, class U> requires BiggerThan<T, U>
60 void f() { }
61 // expected-note@-1 {{candidate function [with T = long long, U = int]}}
62 
63 template<class T, class U> requires BiggerThanInt<T>
64 void f() { }
65 // expected-note@-1 {{candidate function [with T = long long, U = int]}}
66 
67 static_assert(sizeof(f<long long, int>()));
68 // expected-error@-1 {{call to 'f' is ambiguous}}
69 
70 template<typename T>
71 concept C3 = true;
72 
73 template<typename T>
74 concept C4 = true && C3<T>;
75 
76 template<typename T> requires C3<void>
77 int g() { }
78 
79 template<typename T> requires C4<void>
80 int g() { }
81 
82 static_assert(sizeof(g<int>()));
83 
84 // Regression - used template parameter detection when only first out of
85 // multiple parameters are used
86 template <unsigned> struct X {};
87 template <class...> int h(X<0>);
88 template <unsigned b, class...> int h(X<b>);
89 static_assert(sizeof(h(X<0>{})));