xref: /llvm-project/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp (revision 76476efd68951907a94def92b2bb6ba6e32ca5b4)
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