Home | History | Annotate | Download | only in temp.variadic
      1 // RUN: %clang_cc1 -std=c++0x -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 default constructor) not viable: requires 0 arguments, but 1 was provided}}
     56 struct B { };
     57 struct C { };
     58 struct D { };
     59 
     60 A *checkA = new HasMixins<A, B, C, D>;
     61 B *checkB = new HasMixins<A, B, C, D>;
     62 D *checkD = new HasMixins<A, B, C, D>;
     63 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> *'}}
     64 HasMixins<> *checkNone = new HasMixins<>;
     65 
     66 template<typename Mixins>
     67 struct BrokenMixins : public Mixins... { }; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
     68 
     69 // In a mem-initializer-list (12.6.2); the pattern is a mem-initializer.
     70 template<typename ...Mixins>
     71 HasMixins<Mixins...>::HasMixins(): Mixins()... { }
     72 
     73 template<typename ...Mixins>
     74 HasMixins<Mixins...>::HasMixins(const HasMixins &other): Mixins(other)... { }
     75 
     76 template<typename ...Mixins>
     77 HasMixins<Mixins...>::HasMixins(int i): Mixins(i)... { } // expected-error{{no matching constructor for initialization of 'A'}}
     78 
     79 void test_has_mixins() {
     80   HasMixins<A, B> ab;
     81   HasMixins<A, B> ab2 = ab;
     82   HasMixins<A, B> ab3(17); // expected-note{{in instantiation of member function 'HasMixins<A, B>::HasMixins' requested here}}
     83 }
     84 
     85 template<typename T>
     86 struct X {
     87   T member;
     88 
     89   X() : member()... { } // expected-error{{pack expansion for initialization of member 'member'}}
     90 };
     91 
     92 // In a template-argument-list (14.3); the pattern is a template-argument.
     93 template<typename ...Types>
     94 struct tuple_of_refs {
     95   typedef tuple<Types& ...> types;
     96 };
     97 
     98 tuple<int&, float&> *t_int_ref_float_ref;
     99 tuple_of_refs<int&, float&>::types *t_int_ref_float_ref_2 =  t_int_ref_float_ref;
    100 
    101 template<typename ...Types>
    102 struct extract_nested_types {
    103   typedef tuple<typename Types::type...> types;
    104 };
    105 
    106 tuple<int, float> *t_int_float;
    107 extract_nested_types<identity<int>, identity<float> >::types *t_int_float_2
    108   = t_int_float;
    109 
    110 template<int ...N>
    111 struct tuple_of_ints {
    112   typedef tuple<int_c<N>...> type;
    113 };
    114 
    115 int check_temp_arg_1[is_same<tuple_of_ints<1, 2, 3, 4, 5>::type,
    116                              tuple<int_c<1>, int_c<2>, int_c<3>, int_c<4>,
    117                                    int_c<5>>>::value? 1 : -1];
    118 
    119 // In a dynamic-exception-specification (15.4); the pattern is a type-id.
    120 template<typename ...Types>
    121 struct f_with_except {
    122   virtual void f() throw(Types...); // expected-note{{overridden virtual function is here}}
    123 };
    124 
    125 struct check_f_with_except_1 : f_with_except<int, float> {
    126   virtual void f() throw(int, float);
    127 };
    128 
    129 struct check_f_with_except_2 : f_with_except<int, float> {
    130   virtual void f() throw(int);
    131 };
    132 
    133 struct check_f_with_except_3 : f_with_except<int, float> {
    134   virtual void f() throw(int, float, double); // expected-error{{exception specification of overriding function is more lax than base version}}
    135 };
    136