Home | History | Annotate | Download | only in temp.arg.explicit
      1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
      2 // expected-no-diagnostics
      3 
      4 // Metafunction to extract the Nth type from a set of types.
      5 template<unsigned N, typename ...Types> struct get_nth_type;
      6 
      7 template<unsigned N, typename Head, typename ...Tail>
      8 struct get_nth_type<N, Head, Tail...> : get_nth_type<N-1, Tail...> { };
      9 
     10 template<typename Head, typename ...Tail>
     11 struct get_nth_type<0, Head, Tail...> {
     12   typedef Head type;
     13 };
     14 
     15 // Placeholder type  when get_nth_type fails.
     16 struct no_type {};
     17 
     18 template<unsigned N>
     19 struct get_nth_type<N> {
     20   typedef no_type type;
     21 };
     22 
     23 template<typename ...Args>
     24 typename get_nth_type<0, Args...>::type first_arg(Args...);
     25 
     26 template<typename ...Args>
     27 typename get_nth_type<1, Args...>::type second_arg(Args...);
     28 
     29 // Test explicit specification of function template arguments.
     30 void test_explicit_spec_simple() {
     31   int *ip1 = first_arg<int *>(0);
     32   int *ip2 = first_arg<int *, float*>(0, 0);
     33   float *fp1 = first_arg<float *, double*, int*>(0, 0, 0);
     34 }
     35 
     36 // Template argument deduction can extend the sequence of template
     37 // arguments corresponding to a template parameter pack, even when the
     38 // sequence contains explicitly specified template arguments.
     39 void test_explicit_spec_extension(double *dp) {
     40   int *ip1 = first_arg<int *>(0, 0);
     41   int *ip2 = first_arg<int *, float*>(0, 0, 0, 0);
     42   float *fp1 = first_arg<float *, double*, int*>(0, 0, 0);
     43   int *i1 = second_arg<float *>(0, (int*)0, 0);
     44   double *dp1 = first_arg<>(dp);
     45 }
     46 
     47 template<typename ...Types>
     48 struct tuple { };
     49 
     50 template<typename ...Types>
     51 void accept_tuple(tuple<Types...>);
     52 
     53 void test_explicit_spec_extension_targs(tuple<int, float, double> t3) {
     54   accept_tuple(t3);
     55   accept_tuple<int, float, double>(t3);
     56   accept_tuple<int>(t3);
     57   accept_tuple<int, float>(t3);
     58 }
     59 
     60 template<typename R, typename ...ParmTypes>
     61 void accept_function_ptr(R(*)(ParmTypes...));
     62 
     63 void test_explicit_spec_extension_funcparms(int (*f3)(int, float, double)) {
     64   accept_function_ptr(f3);
     65   accept_function_ptr<int>(f3);
     66   accept_function_ptr<int, int>(f3);
     67   accept_function_ptr<int, int, float>(f3);
     68   accept_function_ptr<int, int, float, double>(f3);
     69 }
     70