1 // RUN: %clang_cc1 -std=c++2a -x c++ -verify %s 2 3 template<typename T> requires (sizeof(T) >= 4) 4 // expected-note@-1{{similar constraint expressions not considered equivalen}} 5 class A{}; // expected-note{{template is declared here}} 6 7 template<typename T> requires (sizeof(T) >= 4 && sizeof(T) <= 10) 8 // expected-note@-1{{similar constraint expression here}} 9 10 class A<T>{}; // expected-error{{class template partial specialization is not more specialized than the primary template}} 11 12 template<typename T> 13 concept C1 = sizeof(T) >= 4; 14 15 template<typename T> requires C1<T> 16 class B{}; 17 18 template<typename T> requires (C1<T> && sizeof(T) <= 10) 19 class B<T>{}; 20 21 template<typename T> 22 concept C2 = sizeof(T) > 1 && sizeof(T) <= 8; 23 24 template<typename T> 25 class C{}; 26 27 template<typename T> requires C1<T> 28 class C<T>{}; 29 30 template<typename T> 31 class D{}; // expected-note{{previous definition is here}} 32 33 template<typename T> 34 class D<T>{}; // expected-error{{class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}} expected-error{{redefinition of 'D'}} 35 36 template<typename T> requires C1<T> // expected-note{{previous template declaration is here}} 37 class E{}; 38 39 template<typename T> // expected-error{{requires clause differs in template redeclaration}} 40 class E<T>{}; // expected-error{{class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}} 41 42 template<typename T> 43 struct F{ enum{ value = 1 }; }; 44 45 template<typename T> requires C1<T> && C2<T> 46 struct F<T>{ enum{ value = 2 }; }; 47 48 template<typename T> requires C1<T> || C2<T> 49 struct F<T>{ enum{ value = 3 }; }; 50 51 static_assert(F<unsigned>::value == 2); 52 static_assert(F<char[10]>::value == 3); 53 static_assert(F<char>::value == 1); 54 55 // Make sure atomic constraints subsume each other only if their parameter 56 // mappings are identical. 57 58 template<typename T, typename U> requires C2<T> 59 struct I { }; // expected-note {{template is declared here}} 60 61 template<typename T, typename U> requires C2<U> 62 struct I<T, U> { }; // expected-error {{class template partial specialization is not more specialized than the primary template}} 63 64 template<typename T, typename U> requires C2<T> && C2<U> 65 struct I<T, U> { }; 66