Home | History | Annotate | Download | only in temp.class.spec
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 // Test class template partial specializations of member templates.
      4 template<typename T>
      5 struct X0 {
      6   template<typename U> struct Inner0 {
      7     static const unsigned value = 0;
      8   };
      9 
     10   template<typename U> struct Inner0<U*> {
     11     static const unsigned value = 1;
     12   };
     13 };
     14 
     15 template<typename T> template<typename U>
     16 struct X0<T>::Inner0<const U*> {
     17   static const unsigned value = 2;
     18 };
     19 
     20 int array0[X0<int>::Inner0<int>::value == 0? 1 : -1];
     21 int array1[X0<int>::Inner0<int*>::value == 1? 1 : -1];
     22 int array2[X0<int>::Inner0<const int*>::value == 2? 1 : -1];
     23 
     24 // Make sure we can provide out-of-line class template partial specializations
     25 // for member templates (and instantiate them).
     26 template<class T> struct A {
     27   struct C {
     28     template<class T2> struct B;
     29   };
     30 };
     31 
     32 // partial specialization of A<T>::C::B<T2>
     33 template<class T> template<class T2> struct A<T>::C::B<T2*> { };
     34 
     35 A<short>::C::B<int*> absip;
     36 
     37 // Check for conflicts during template instantiation.
     38 template<typename T, typename U>
     39 struct Outer {
     40   template<typename X, typename Y> struct Inner;
     41   template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous}}
     42   template<typename Y> struct Inner<U, Y> {}; // expected-error{{cannot be redeclared}}
     43 };
     44 
     45 Outer<int, int> outer; // expected-note{{instantiation}}
     46 
     47 // Test specialization of class template partial specialization members.
     48 template<> template<typename Z>
     49 struct X0<float>::Inner0<Z*> {
     50   static const unsigned value = 3;
     51 };
     52 
     53 int array3[X0<float>::Inner0<int>::value == 0? 1 : -1];
     54 int array4[X0<float>::Inner0<int*>::value == 3? 1 : -1];
     55 int array5[X0<float>::Inner0<const int*>::value == 2? 1 : -1];
     56 
     57 namespace rdar8651930 {
     58   template<typename OuterT>
     59   struct Outer {
     60     template<typename T, typename U>
     61     struct Inner;
     62 
     63     template<typename T>
     64     struct Inner<T, T> {
     65       static const bool value = true;
     66     };
     67 
     68     template<typename T, typename U>
     69     struct Inner {
     70       static const bool value = false;
     71     };
     72   };
     73 
     74   int array0[Outer<int>::Inner<int, int>::value? 1 : -1];
     75   int array1[Outer<int>::Inner<int, float>::value? -1 : 1];
     76 }
     77