1 // RUN: %clang_cc1 -std=c++2a -x c++ -verify %s 2 3 template<typename T> requires (sizeof(T) >= 2) // expected-note{{because 'sizeof(char) >= 2' (1 >= 2) evaluated to false}} 4 struct A { 5 static constexpr int value = sizeof(T); 6 }; 7 8 static_assert(A<int>::value == 4); 9 static_assert(A<char>::value == 1); // expected-error{{constraints not satisfied for class template 'A' [with T = char]}} 10 11 template<typename T, typename U> 12 requires (sizeof(T) != sizeof(U) // expected-note{{because 'sizeof(int) != sizeof(char [4])' (4 != 4) evaluated to false}} 13 && sizeof(T) >= 4) // expected-note{{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} 14 constexpr int SizeDiff = sizeof(T) > sizeof(U) ? sizeof(T) - sizeof(U) : sizeof(U) - sizeof(T); 15 16 static_assert(SizeDiff<int, char> == 3); 17 static_assert(SizeDiff<int, char[4]> == 0); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = int, U = char [4]]}} 18 static_assert(SizeDiff<char, int> == 3); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = char, U = int]}} 19 20 template<typename... Ts> 21 requires ((sizeof(Ts) == 4) || ...) // expected-note{{because 'sizeof(char) == 4' (1 == 4) evaluated to false}} expected-note{{'sizeof(long long) == 4' (8 == 4) evaluated to false}} expected-note{{'sizeof(int [20]) == 4' (80 == 4) evaluated to false}} 22 constexpr auto SumSizes = (sizeof(Ts) + ...); 23 24 static_assert(SumSizes<char, long long, int> == 13); 25 static_assert(SumSizes<char, long long, int[20]> == 89); // expected-error{{constraints not satisfied for variable template 'SumSizes' [with Ts = <char, long long, int [20]>]}} 26 27 template<typename T> 28 concept IsBig = sizeof(T) > 100; // expected-note{{because 'sizeof(int) > 100' (4 > 100) evaluated to false}} 29 30 template<typename T> 31 requires IsBig<T> // expected-note{{'int' does not satisfy 'IsBig'}} 32 using BigPtr = T*; 33 34 static_assert(sizeof(BigPtr<int>)); // expected-error{{constraints not satisfied for alias template 'BigPtr' [with T = int]}}}} 35 36 template<typename T> requires T::value // expected-note{{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}} 37 struct S { static constexpr bool value = true; }; 38 39 struct S2 { static constexpr bool value = true; }; 40 41 static_assert(S<int>::value); // expected-error{{constraints not satisfied for class template 'S' [with T = int]}} 42 static_assert(S<S2>::value); 43 44 template<typename T> 45 struct AA 46 { 47 template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} 48 struct B 49 { 50 static constexpr int a = 0; 51 }; 52 53 template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} 54 static constexpr int b = 1; 55 56 template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} getBAA57 static constexpr int getB() { // expected-note{{candidate template ignored: constraints not satisfied [with U = int [2]]}} 58 return 2; 59 } 60 fooAA61 static auto foo() 62 { 63 return B<T[2]>::a; // expected-error{{constraints not satisfied for class template 'B' [with U = int [2]]}} 64 } 65 foo1AA66 static auto foo1() 67 { 68 return b<T[2]>; // expected-error{{constraints not satisfied for variable template 'b' [with U = int [2]]}} 69 } 70 foo2AA71 static auto foo2() 72 { 73 return AA<T>::getB<T[2]>(); // expected-error{{no matching function for call to 'getB'}} 74 } 75 }; 76 77 constexpr auto x = AA<int>::foo(); // expected-note{{in instantiation of member function 'AA<int>::foo' requested here}} 78 constexpr auto x1 = AA<int>::foo1(); // expected-note{{in instantiation of member function 'AA<int>::foo1' requested here}} 79 constexpr auto x2 = AA<int>::foo2(); // expected-note{{in instantiation of member function 'AA<int>::foo2' requested here}} 80 81 template<typename T> 82 struct B { using type = typename T::type; }; // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} 83 84 template<typename T> requires B<T>::type // expected-note{{in instantiation of template class 'B<int>' requested here}} 85 // expected-note@-1{{while substituting template arguments into constraint expression here}} 86 struct C { }; 87 88 template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} 89 struct D { }; 90 91 static_assert(C<int>{}); // expected-note{{while checking constraint satisfaction for template 'C<int>' required here}} 92 static_assert(D<int>{}); // expected-note{{while checking constraint satisfaction for template 'D<int>' required here}} 93