Richard Smith | 9ca5c42 | 2011-10-13 22:29:44 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
Richard Smith | 0c4a34b | 2011-05-14 15:04:18 +0000 | [diff] [blame] | 2 | |
| 3 | template<typename S> |
| 4 | struct A { |
| 5 | typedef S B; |
| 6 | template<typename T> using C = typename T::B; |
| 7 | template<typename T> struct D { |
| 8 | template<typename U> using E = typename A<U>::template C<A<T>>; |
| 9 | template<typename U> using F = A<E<U>>; |
| 10 | template<typename U> using G = C<F<U>>; |
| 11 | G<T> g; |
| 12 | }; |
| 13 | typedef decltype(D<B>().g) H; |
| 14 | D<H> h; |
| 15 | template<typename T> using I = A<decltype(h.g)>; |
| 16 | template<typename T> using J = typename A<decltype(h.g)>::template C<I<T>>; |
| 17 | }; |
| 18 | |
| 19 | A<int> a; |
| 20 | A<char>::D<double> b; |
| 21 | |
| 22 | template<typename T> T make(); |
| 23 | |
| 24 | namespace X { |
| 25 | template<typename T> struct traits { |
| 26 | typedef T thing; |
| 27 | typedef decltype(val(make<thing>())) inner_ptr; |
| 28 | |
| 29 | template<typename U> using rebind_thing = typename thing::template rebind<U>; |
| 30 | template<typename U> using rebind = traits<rebind_thing<U>>; |
| 31 | |
| 32 | inner_ptr &&alloc(); |
| 33 | void free(inner_ptr&&); |
| 34 | }; |
| 35 | |
| 36 | template<typename T> struct ptr_traits { |
| 37 | typedef T *type; |
| 38 | }; |
| 39 | template<typename T> using ptr = typename ptr_traits<T>::type; |
| 40 | |
| 41 | template<typename T> struct thing { |
| 42 | typedef T inner; |
| 43 | typedef ptr<inner> inner_ptr; |
| 44 | typedef traits<thing<inner>> traits_type; |
| 45 | |
| 46 | template<typename U> using rebind = thing<U>; |
| 47 | |
| 48 | thing(traits_type &traits) : traits(traits), val(traits.alloc()) {} |
| 49 | ~thing() { traits.free(static_cast<inner_ptr&&>(val)); } |
| 50 | |
| 51 | traits_type &traits; |
| 52 | inner_ptr val; |
| 53 | |
| 54 | friend inner_ptr val(const thing &t) { return t.val; } |
| 55 | }; |
| 56 | |
| 57 | template<> struct ptr_traits<bool> { |
| 58 | typedef bool &type; |
| 59 | }; |
| 60 | template<> bool &traits<thing<bool>>::alloc() { static bool b; return b; } |
| 61 | template<> void traits<thing<bool>>::free(bool&) {} |
| 62 | } |
| 63 | |
| 64 | typedef X::traits<X::thing<int>> itt; |
| 65 | |
| 66 | itt::thing::traits_type itr; |
| 67 | itt::thing ith(itr); |
| 68 | |
| 69 | itt::rebind<bool> btr; |
| 70 | itt::rebind_thing<bool> btt(btr); |
Richard Smith | 928be49 | 2012-01-25 02:14:59 +0000 | [diff] [blame^] | 71 | |
| 72 | namespace PR11848 { |
| 73 | template<typename T> using U = int; |
| 74 | |
| 75 | template<typename T, typename ...Ts> |
| 76 | void f(U<T> i, U<Ts> ...is) { // expected-error {{type 'U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}} |
| 77 | return i + f<Ts...>(is...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}} |
| 78 | } |
| 79 | |
| 80 | template<typename ...Ts> |
| 81 | struct S { |
| 82 | S(U<Ts>...ts); // expected-error {{does not contain any unexpanded parameter packs}} |
| 83 | }; |
| 84 | |
| 85 | template<typename T> |
| 86 | struct Hidden1 { |
| 87 | template<typename ...Ts> |
| 88 | Hidden1(typename T::template U<Ts> ...ts); |
| 89 | }; |
| 90 | |
| 91 | template<typename T, typename ...Ts> |
| 92 | struct Hidden2 { |
| 93 | Hidden2(typename T::template U<Ts> ...ts); |
| 94 | }; |
| 95 | |
| 96 | struct Hide { |
| 97 | template<typename T> using U = int; |
| 98 | }; |
| 99 | |
| 100 | // FIXME: This case crashes clang at the moment. |
| 101 | //Hidden1<Hide> h1; |
| 102 | Hidden2<Hide, double, char> h2(1, 2); |
| 103 | } |