Home | History | Annotate | Download | only in temp.deduct.call
      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 T, typename U> struct pair { };
     23 template<typename T, typename U> pair<T, U> make_pair(T, U);
     24 
     25 // For a function parameter pack that occurs at the end of the
     26 // parameter-declaration-list, the type A of each remaining argument
     27 // of the call is compared with the type P of the declarator-id of the
     28 // function parameter pack.
     29 template<typename ...Args>
     30 typename get_nth_type<0, Args...>::type first_arg(Args...);
     31 
     32 template<typename ...Args>
     33 typename get_nth_type<1, Args...>::type second_arg(Args...);
     34 
     35 void test_simple_deduction(int *ip, float *fp, double *dp) {
     36   int *ip1 = first_arg(ip);
     37   int *ip2 = first_arg(ip, fp);
     38   int *ip3 = first_arg(ip, fp, dp);
     39   no_type nt1 = first_arg();
     40 }
     41 
     42 template<typename ...Args>
     43 typename get_nth_type<0, Args...>::type first_arg_ref(Args&...);
     44 
     45 template<typename ...Args>
     46 typename get_nth_type<1, Args...>::type second_arg_ref(Args&...);
     47 
     48 void test_simple_ref_deduction(int *ip, float *fp, double *dp) {
     49   int *ip1 = first_arg_ref(ip);
     50   int *ip2 = first_arg_ref(ip, fp);
     51   int *ip3 = first_arg_ref(ip, fp, dp);
     52   no_type nt1 = first_arg_ref();
     53 }
     54 
     55 
     56 // FIXME: Use the template parameter names in this diagnostic.
     57 template<typename ...Args1, typename ...Args2>
     58 typename get_nth_type<0, Args1...>::type first_arg_pair(pair<Args1, Args2>...); // expected-note{{candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'int'}}
     59 
     60 template<typename ...Args1, typename ...Args2>
     61 typename get_nth_type<1, Args1...>::type second_arg_pair(pair<Args1, Args2>...);
     62 
     63 void test_pair_deduction(int *ip, float *fp, double *dp) {
     64   int *ip1 = first_arg_pair(make_pair(ip, 17));
     65   int *ip2 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
     66   int *ip3 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
     67                             make_pair(dp, 17));
     68   float *fp1 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
     69   float *fp2 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
     70                                make_pair(dp, 17));
     71   no_type nt1 = first_arg_pair();
     72   no_type nt2 = second_arg_pair();
     73   no_type nt3 = second_arg_pair(make_pair(ip, 17));
     74 
     75 
     76   first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}}
     77 }
     78 
     79 // For a function parameter pack that does not occur at the end of the
     80 // parameter-declaration-list, the type of the parameter pack is a
     81 // non-deduced context.
     82 template<typename ...Types> struct tuple { };
     83 
     84 template<typename ...Types>
     85 void pack_not_at_end(tuple<Types...>, Types... values, int);
     86 
     87 void test_pack_not_at_end(tuple<int*, double*> t2) {
     88   pack_not_at_end(t2, 0, 0, 0);
     89 }
     90