Richard Smith | 1804174 | 2011-05-14 15:04:18 +0000 | [diff] [blame^] | 1 | // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s |
| 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); |