1 // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s 2 3 namespace class_templates 4 { 5 template<typename T, typename U> requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} 6 struct is_same { static constexpr bool value = false; }; 7 8 template<typename T> requires sizeof(T*) >= 4 && sizeof(T) >= 4 9 struct is_same<T*, T*> { static constexpr bool value = true; }; 10 11 static_assert(!is_same<char*, char*>::value); 12 static_assert(!is_same<short*, short*>::value); 13 static_assert(is_same<int*, int*>::value); 14 static_assert(is_same<char, char>::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}} 15 16 template<typename T> 17 struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}} 18 19 template<typename T> 20 struct B {}; 21 22 template<typename T> requires A<T>::type // expected-note{{in instantiation of template class 'class_templates::A<int *>' requested here}} 23 // expected-note@-1{{while substituting template arguments into constraint expression here}} 24 struct B<T*> {}; 25 26 template<typename T> requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} 27 struct B<T**> {}; 28 29 static_assert((B<int**>{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B<int *>' required here}} 30 // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B<int>' required here}} 31 // expected-note@-2{{during template argument deduction for class template partial specialization 'B<T *>' [with T = int *]}} 32 // expected-note@-3{{during template argument deduction for class template partial specialization 'B<T **>' [with T = int]}} 33 // expected-note@-4 2{{in instantiation of template class 'class_templates::B<int **>' requested here}} 34 } 35 36 namespace variable_templates 37 { 38 template<typename T, typename U> requires sizeof(T) >= 4 39 constexpr bool is_same_v = false; 40 41 template<typename T> requires sizeof(T*) >= 4 && sizeof(T) >= 4 42 constexpr bool is_same_v<T*, T*> = true; 43 44 static_assert(!is_same_v<char*, char*>); 45 static_assert(!is_same_v<short*, short*>); 46 static_assert(is_same_v<int*, int*>); 47 48 template<typename T> 49 struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}} 50 51 template<typename T> 52 constexpr bool v1 = false; 53 54 template<typename T> requires A<T>::type // expected-note{{in instantiation of template class 'variable_templates::A<int *>' requested here}} 55 // expected-note@-1{{while substituting template arguments into constraint expression here}} 56 constexpr bool v1<T*> = true; 57 58 template<typename T> requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} 59 constexpr bool v1<T**> = true; 60 61 static_assert(v1<int**>); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1<int *>' required here}} 62 // expected-note@-1{{while checking constraint satisfaction for variable template partial specialization 'v1<int>' required here}} 63 // expected-note@-2{{during template argument deduction for variable template partial specialization 'v1<T *>' [with T = int *]}} 64 // expected-note@-3{{during template argument deduction for variable template partial specialization 'v1<T **>' [with T = int]}} 65 // expected-error@-4{{static_assert failed due to requirement 'v1<int **>'}} 66 67 }