167c608a9SSaar Raz // RUN: %clang_cc1 -std=c++2a -x c++ -verify %s 2fdf80e86SSaar Raz 3fdf80e86SSaar Raz namespace class_templates 4fdf80e86SSaar Raz { 5b65b1f32SSaar Raz template<typename T, typename U> requires (sizeof(T) >= 4) // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} 6fdf80e86SSaar Raz struct is_same { static constexpr bool value = false; }; 7fdf80e86SSaar Raz 8b65b1f32SSaar Raz template<typename T> requires (sizeof(T*) >= 4 && sizeof(T) >= 4) 9fdf80e86SSaar Raz struct is_same<T*, T*> { static constexpr bool value = true; }; 10fdf80e86SSaar Raz 11fdf80e86SSaar Raz static_assert(!is_same<char*, char*>::value); 12fdf80e86SSaar Raz static_assert(!is_same<short*, short*>::value); 13fdf80e86SSaar Raz static_assert(is_same<int*, int*>::value); 14fdf80e86SSaar Raz static_assert(is_same<char, char>::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}} 15fdf80e86SSaar Raz 16fdf80e86SSaar Raz template<typename T> 17fdf80e86SSaar Raz struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}} 18fdf80e86SSaar Raz 19fdf80e86SSaar Raz template<typename T> 20fdf80e86SSaar Raz struct B {}; 21fdf80e86SSaar Raz 22fdf80e86SSaar Raz template<typename T> requires A<T>::type // expected-note{{in instantiation of template class 'class_templates::A<int *>' requested here}} 23fdf80e86SSaar Raz // expected-note@-1{{while substituting template arguments into constraint expression here}} 24fdf80e86SSaar Raz struct B<T*> {}; 25fdf80e86SSaar Raz 26b65b1f32SSaar Raz template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} 27fdf80e86SSaar Raz struct B<T**> {}; 28fdf80e86SSaar Raz 2927a972a6SYuanfang Chen static_assert(((void)B<int**>{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B<int *>' required here}} 30fdf80e86SSaar Raz // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B<int>' required here}} 31fdf80e86SSaar Raz // expected-note@-2{{during template argument deduction for class template partial specialization 'B<T *>' [with T = int *]}} 32fdf80e86SSaar Raz // expected-note@-3{{during template argument deduction for class template partial specialization 'B<T **>' [with T = int]}} 33fdf80e86SSaar Raz // expected-note@-4 2{{in instantiation of template class 'class_templates::B<int **>' requested here}} 3462c221b5SSaar Raz 3562c221b5SSaar Raz template<typename T, typename U = double> 3662c221b5SSaar Raz concept same_as = is_same<T, U>::value; 3762c221b5SSaar Raz 3862c221b5SSaar Raz template<same_as<bool> T> requires A<T>::type 3962c221b5SSaar Raz struct B<T*> {}; 4062c221b5SSaar Raz // expected-note@-1{{previous}} 4162c221b5SSaar Raz 4262c221b5SSaar Raz template<same_as<bool> T> requires A<T>::type 4362c221b5SSaar Raz struct B<T*> {}; 4462c221b5SSaar Raz // expected-error@-1{{redefinition}} 4562c221b5SSaar Raz 4662c221b5SSaar Raz template<same_as T> requires A<T>::type 4762c221b5SSaar Raz struct B<T*> {}; 4862c221b5SSaar Raz 4962c221b5SSaar Raz template<same_as<int> T> requires A<T>::type 5062c221b5SSaar Raz struct B<T*> {}; 51fdf80e86SSaar Raz } 52fdf80e86SSaar Raz 53fdf80e86SSaar Raz namespace variable_templates 54fdf80e86SSaar Raz { 55b65b1f32SSaar Raz template<typename T, typename U> requires (sizeof(T) >= 4) 56fdf80e86SSaar Raz constexpr bool is_same_v = false; 57fdf80e86SSaar Raz 58b65b1f32SSaar Raz template<typename T> requires (sizeof(T*) >= 4 && sizeof(T) >= 4) 59fdf80e86SSaar Raz constexpr bool is_same_v<T*, T*> = true; 60fdf80e86SSaar Raz 61fdf80e86SSaar Raz static_assert(!is_same_v<char*, char*>); 62fdf80e86SSaar Raz static_assert(!is_same_v<short*, short*>); 63fdf80e86SSaar Raz static_assert(is_same_v<int*, int*>); 64fdf80e86SSaar Raz 65fdf80e86SSaar Raz template<typename T> 66fdf80e86SSaar Raz struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}} 67fdf80e86SSaar Raz 68fdf80e86SSaar Raz template<typename T> 69fdf80e86SSaar Raz constexpr bool v1 = false; 70fdf80e86SSaar Raz 71fdf80e86SSaar Raz template<typename T> requires A<T>::type // expected-note{{in instantiation of template class 'variable_templates::A<int *>' requested here}} 72fdf80e86SSaar Raz // expected-note@-1{{while substituting template arguments into constraint expression here}} 73fdf80e86SSaar Raz constexpr bool v1<T*> = true; 74fdf80e86SSaar Raz 75b65b1f32SSaar Raz template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} 76fdf80e86SSaar Raz constexpr bool v1<T**> = true; 77fdf80e86SSaar Raz 78fdf80e86SSaar Raz static_assert(v1<int**>); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1<int *>' required here}} 79fdf80e86SSaar Raz // expected-note@-1{{while checking constraint satisfaction for variable template partial specialization 'v1<int>' required here}} 80fdf80e86SSaar Raz // expected-note@-2{{during template argument deduction for variable template partial specialization 'v1<T *>' [with T = int *]}} 81fdf80e86SSaar Raz // expected-note@-3{{during template argument deduction for variable template partial specialization 'v1<T **>' [with T = int]}} 82*76476efdSMuhammad Usman Shahid // expected-error@-4{{static assertion failed due to requirement 'v1<int **>'}} 83fdf80e86SSaar Raz 84fdf80e86SSaar Raz } 85