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