Richard Smith | 762bb9d | 2011-10-13 22:29:44 +0000 | [diff] [blame^] | 1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
Douglas Gregor | 7b976ec | 2010-12-23 01:24:45 +0000 | [diff] [blame] | 2 | |
| 3 | template<typename ...Types> struct tuple; |
Douglas Gregor | 6e4e17d | 2010-12-24 00:35:52 +0000 | [diff] [blame] | 4 | template<unsigned> struct unsigned_c; |
| 5 | |
| 6 | template<typename T, typename U> |
| 7 | struct is_same { |
| 8 | static const bool value = false; |
| 9 | }; |
| 10 | |
| 11 | template<typename T> |
| 12 | struct is_same<T, T> { |
| 13 | static const bool value = true; |
| 14 | }; |
Douglas Gregor | 7b976ec | 2010-12-23 01:24:45 +0000 | [diff] [blame] | 15 | |
| 16 | namespace PackExpansionNotAtEnd { |
| 17 | template<typename T, typename U> |
| 18 | struct tuple_same_with_int { |
| 19 | static const bool value = false; |
| 20 | }; |
| 21 | |
| 22 | template<typename ...Types> |
| 23 | struct tuple_same_with_int<tuple<Types...>, tuple<Types..., int>> { |
| 24 | static const bool value = true; |
| 25 | }; |
| 26 | |
| 27 | int tuple_same_with_int_1[tuple_same_with_int<tuple<int, float, double>, |
| 28 | tuple<int, float, double, int> |
| 29 | >::value? 1 : -1]; |
| 30 | |
| 31 | template<typename ... Types> struct UselessPartialSpec; |
| 32 | |
Douglas Gregor | 6e4e17d | 2010-12-24 00:35:52 +0000 | [diff] [blame] | 33 | template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}} |
Douglas Gregor | 7b976ec | 2010-12-23 01:24:45 +0000 | [diff] [blame] | 34 | typename Tail> // expected-note{{non-deducible template parameter 'Tail'}} |
| 35 | struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that can not be deduced; this partial specialization will never be used}} |
| 36 | } |
Douglas Gregor | 6e4e17d | 2010-12-24 00:35:52 +0000 | [diff] [blame] | 37 | |
| 38 | namespace DeduceNonTypeTemplateArgsInArray { |
| 39 | template<typename ...ArrayTypes> |
| 40 | struct split_arrays; |
| 41 | |
| 42 | template<typename ...ElementTypes, unsigned ...Bounds> |
| 43 | struct split_arrays<ElementTypes[Bounds]...> { |
| 44 | typedef tuple<ElementTypes...> element_types; |
| 45 | |
| 46 | // FIXME: Would like to have unsigned_tuple<Bounds...> here. |
| 47 | typedef tuple<unsigned_c<Bounds>...> bounds_types; |
| 48 | }; |
| 49 | |
| 50 | int check1[is_same<split_arrays<int[1], float[2], double[3]>::element_types, |
| 51 | tuple<int, float, double>>::value? 1 : -1]; |
| 52 | int check2[is_same<split_arrays<int[1], float[2], double[3]>::bounds_types, |
| 53 | tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>> |
| 54 | >::value? 1 : -1]; |
| 55 | } |