Home | History | Annotate | Download | only in temp.variadic
      1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
      2 
      3 template<typename... Types> struct tuple;
      4 template<int I> struct int_c;
      5 
      6 template<typename T>
      7 struct identity {
      8   typedef T type;
      9 };
     10 
     11 template<typename T, typename U>
     12 struct is_same {
     13   static const bool value = false;
     14 };
     15 
     16 template<typename T>
     17 struct is_same<T, T> {
     18   static const bool value = true;
     19 };
     20 
     21 // FIXME: Several more bullets to go
     22 
     23 // In an initializer-list (8.5); the pattern is an initializer-clause.
     24 // Note: this also covers expression-lists, since expression-list is
     25 // just defined as initializer-list.
     26 void five_args(int, int, int, int, int); // expected-note{{candidate function not viable: requires 5 arguments, but 6 were provided}}
     27 
     28 template<int ...Values>
     29 void initializer_list_expansion() {
     30   int values[5] = { Values... }; // expected-error{{excess elements in array initializer}}
     31   five_args(Values...); // expected-error{{no matching function for call to 'five_args'}}
     32 }
     33 
     34 template void initializer_list_expansion<1, 2, 3, 4, 5>();
     35 template void initializer_list_expansion<1, 2, 3, 4, 5, 6>(); // expected-note{{in instantiation of function template specialization 'initializer_list_expansion<1, 2, 3, 4, 5, 6>' requested here}}
     36 
     37 namespace PR8977 {
     38   struct A { };
     39   template<typename T, typename... Args> void f(Args... args) {
     40     T t(args...);
     41   };
     42 
     43   template void f<A>();
     44 }
     45 
     46 // In a base-specifier-list (Clause 10); the pattern is a base-specifier.
     47 template<typename ...Mixins>
     48 struct HasMixins : public Mixins... {
     49   HasMixins();
     50   HasMixins(const HasMixins&);
     51   HasMixins(int i);
     52 };
     53 
     54 struct A { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A' for 1st argument}} \
     55 // expected-note{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A' for 1st argument}} \
     56 // expected-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
     57 struct B { };
     58 struct C { };
     59 struct D { };
     60 
     61 A *checkA = new HasMixins<A, B, C, D>;
     62 B *checkB = new HasMixins<A, B, C, D>;
     63 D *checkD = new HasMixins<A, B, C, D>;
     64 C *checkC = new HasMixins<A, B, D>; // expected-error{{cannot initialize a variable of type 'C *' with an rvalue of type 'HasMixins<A, B, D> *'}}
     65 HasMixins<> *checkNone = new HasMixins<>;
     66 
     67 template<typename Mixins>
     68 struct BrokenMixins : public Mixins... { }; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
     69 
     70 // In a mem-initializer-list (12.6.2); the pattern is a mem-initializer.
     71 template<typename ...Mixins>
     72 HasMixins<Mixins...>::HasMixins(): Mixins()... { }
     73 
     74 template<typename ...Mixins>
     75 HasMixins<Mixins...>::HasMixins(const HasMixins &other): Mixins(other)... { }
     76 
     77 template<typename ...Mixins>
     78 HasMixins<Mixins...>::HasMixins(int i): Mixins(i)... { } // expected-error{{no matching constructor for initialization of 'A'}}
     79 
     80 void test_has_mixins() {
     81   HasMixins<A, B> ab;
     82   HasMixins<A, B> ab2 = ab;
     83   HasMixins<A, B> ab3(17); // expected-note{{in instantiation of member function 'HasMixins<A, B>::HasMixins' requested here}}
     84 }
     85 
     86 template<typename T>
     87 struct X {
     88   T member;
     89 
     90   X() : member()... { } // expected-error{{pack expansion for initialization of member 'member'}}
     91 };
     92 
     93 // In a template-argument-list (14.3); the pattern is a template-argument.
     94 template<typename ...Types>
     95 struct tuple_of_refs {
     96   typedef tuple<Types& ...> types;
     97 };
     98 
     99 tuple<int&, float&> *t_int_ref_float_ref;
    100 tuple_of_refs<int&, float&>::types *t_int_ref_float_ref_2 =  t_int_ref_float_ref;
    101 
    102 template<typename ...Types>
    103 struct extract_nested_types {
    104   typedef tuple<typename Types::type...> types;
    105 };
    106 
    107 tuple<int, float> *t_int_float;
    108 extract_nested_types<identity<int>, identity<float> >::types *t_int_float_2
    109   = t_int_float;
    110 
    111 template<int ...N>
    112 struct tuple_of_ints {
    113   typedef tuple<int_c<N>...> type;
    114 };
    115 
    116 int check_temp_arg_1[is_same<tuple_of_ints<1, 2, 3, 4, 5>::type,
    117                              tuple<int_c<1>, int_c<2>, int_c<3>, int_c<4>,
    118                                    int_c<5>>>::value? 1 : -1];
    119 
    120 // In a dynamic-exception-specification (15.4); the pattern is a type-id.
    121 template<typename ...Types>
    122 struct f_with_except {
    123   virtual void f() throw(Types...); // expected-note{{overridden virtual function is here}}
    124 };
    125 
    126 struct check_f_with_except_1 : f_with_except<int, float> {
    127   virtual void f() throw(int, float);
    128 };
    129 
    130 struct check_f_with_except_2 : f_with_except<int, float> {
    131   virtual void f() throw(int);
    132 };
    133 
    134 struct check_f_with_except_3 : f_with_except<int, float> {
    135   virtual void f() throw(int, float, double); // expected-error{{exception specification of overriding function is more lax than base version}}
    136 };
    137