aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate/alias-templates.cpp
blob: cd796b8603d23df9d440fba671ebacc09d1c87a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s

template<typename S>
struct A {
  typedef S B;
  template<typename T> using C = typename T::B;
  template<typename T> struct D {
    template<typename U> using E = typename A<U>::template C<A<T>>;
    template<typename U> using F = A<E<U>>;
    template<typename U> using G = C<F<U>>;
    G<T> g;
  };
  typedef decltype(D<B>().g) H;
  D<H> h;
  template<typename T> using I = A<decltype(h.g)>;
  template<typename T> using J = typename A<decltype(h.g)>::template C<I<T>>;
};

A<int> a;
A<char>::D<double> b;

template<typename T> T make();

namespace X {
  template<typename T> struct traits {
    typedef T thing;
    typedef decltype(val(make<thing>())) inner_ptr;

    template<typename U> using rebind_thing = typename thing::template rebind<U>;
    template<typename U> using rebind = traits<rebind_thing<U>>;

    inner_ptr &&alloc();
    void free(inner_ptr&&);
  };

  template<typename T> struct ptr_traits {
    typedef T *type;
  };
  template<typename T> using ptr = typename ptr_traits<T>::type;

  template<typename T> struct thing {
    typedef T inner;
    typedef ptr<inner> inner_ptr;
    typedef traits<thing<inner>> traits_type;

    template<typename U> using rebind = thing<U>;

    thing(traits_type &traits) : traits(traits), val(traits.alloc()) {}
    ~thing() { traits.free(static_cast<inner_ptr&&>(val)); }

    traits_type &traits;
    inner_ptr val;

    friend inner_ptr val(const thing &t) { return t.val; }
  };

  template<> struct ptr_traits<bool> {
    typedef bool &type;
  };
  template<> bool &traits<thing<bool>>::alloc() { static bool b; return b; }
  template<> void traits<thing<bool>>::free(bool&) {}
}

typedef X::traits<X::thing<int>> itt;

itt::thing::traits_type itr;
itt::thing ith(itr);

itt::rebind<bool> btr;
itt::rebind_thing<bool> btt(btr);

namespace PR11848 {
  template<typename T> using U = int;

  template<typename T, typename ...Ts>
  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}}
    return i + f<Ts...>(is...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
  }

  template<typename ...Ts>
  struct S {
    S(U<Ts>...ts); // expected-error {{does not contain any unexpanded parameter packs}}
  };

  template<typename T>
  struct Hidden1 {
    template<typename ...Ts>
    Hidden1(typename T::template U<Ts> ...ts); // expected-error{{type 'typename Hide::U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}}
  };

  template<typename T, typename ...Ts>
  struct Hidden2 {
    Hidden2(typename T::template U<Ts> ...ts);
  };

  struct Hide {
    template<typename T> using U = int;
  };

  Hidden1<Hide> h1;  // expected-note{{in instantiation of template class 'PR11848::Hidden1<PR11848::Hide>' requested here}}
  Hidden2<Hide, double, char> h2(1, 2);
}

namespace PR13243 {
  template<typename A> struct X {};
  template<int I> struct C {};
  template<int I> using Ci = C<I>;

  template<typename A, int I> void f(X<A>, Ci<I>) {}
  template void f(X<int>, C<0>);
}

namespace PR13136 {
  template <typename T, T... Numbers>
  struct NumberTuple { };

  template <unsigned int... Numbers>
  using MyNumberTuple = NumberTuple<unsigned int, Numbers...>;

  template <typename U, unsigned int... Numbers>
  void foo(U&&, MyNumberTuple<Numbers...>);

  template <typename U, unsigned int... Numbers>
  void bar(U&&, NumberTuple<unsigned int, Numbers...>);

  int main() {
    foo(1, NumberTuple<unsigned int, 0, 1>());
    bar(1, NumberTuple<unsigned int, 0, 1>());
  }
}