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