1 // RUN: %clang_cc1 -std=c++2a -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 template<typename T, typename U = double> 36 concept same_as = is_same<T, U>::value; 37 38 template<same_as<bool> T> requires A<T>::type 39 struct B<T*> {}; 40 // expected-note@-1{{previous}} 41 42 template<same_as<bool> T> requires A<T>::type 43 struct B<T*> {}; 44 // expected-error@-1{{redefinition}} 45 46 template<same_as T> requires A<T>::type 47 struct B<T*> {}; 48 49 template<same_as<int> T> requires A<T>::type 50 struct B<T*> {}; 51 } 52 53 namespace variable_templates 54 { 55 template<typename T, typename U> requires (sizeof(T) >= 4) 56 constexpr bool is_same_v = false; 57 58 template<typename T> requires (sizeof(T*) >= 4 && sizeof(T) >= 4) 59 constexpr bool is_same_v<T*, T*> = true; 60 61 static_assert(!is_same_v<char*, char*>); 62 static_assert(!is_same_v<short*, short*>); 63 static_assert(is_same_v<int*, int*>); 64 65 template<typename T> 66 struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}} 67 68 template<typename T> 69 constexpr bool v1 = false; 70 71 template<typename T> requires A<T>::type // expected-note{{in instantiation of template class 'variable_templates::A<int *>' requested here}} 72 // expected-note@-1{{while substituting template arguments into constraint expression here}} 73 constexpr bool v1<T*> = true; 74 75 template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} 76 constexpr bool v1<T**> = true; 77 78 static_assert(v1<int**>); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1<int *>' required here}} 79 // expected-note@-1{{while checking constraint satisfaction for variable template partial specialization 'v1<int>' required here}} 80 // expected-note@-2{{during template argument deduction for variable template partial specialization 'v1<T *>' [with T = int *]}} 81 // expected-note@-3{{during template argument deduction for variable template partial specialization 'v1<T **>' [with T = int]}} 82 // expected-error@-4{{static_assert failed due to requirement 'v1<int **>'}} 83 84 }