deduction.cpp revision db0d4b751e83b8841b8f48f913f17e50467f13d4
1// RUN: clang-cc -fsyntax-only %s
2
3// Template argument deduction with template template parameters.
4template<typename T, template<T> class A>
5struct X0 {
6  static const unsigned value = 0;
7};
8
9template<template<int> class A>
10struct X0<int, A> {
11  static const unsigned value = 1;
12};
13
14template<int> struct X0i;
15template<long> struct X0l;
16int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
17int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
18
19template<typename T, typename U>
20struct is_same {
21  static const bool value = false;
22};
23
24template<typename T>
25struct is_same<T, T> {
26  static const bool value = true;
27};
28
29template<typename T> struct allocator { };
30template<typename T, typename Alloc = allocator<T> > struct vector {};
31
32// Fun with meta-lambdas!
33struct _1 {};
34struct _2 {};
35
36// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
37template<typename T, typename Arg1, typename Arg2>
38struct Replace {
39  typedef T type;
40};
41
42// Replacement of the whole type.
43template<typename Arg1, typename Arg2>
44struct Replace<_1, Arg1, Arg2> {
45  typedef Arg1 type;
46};
47
48template<typename Arg1, typename Arg2>
49struct Replace<_2, Arg1, Arg2> {
50  typedef Arg2 type;
51};
52
53// Replacement through cv-qualifiers
54template<typename T, typename Arg1, typename Arg2>
55struct Replace<const T, Arg1, Arg2> {
56  typedef typename Replace<T, Arg1, Arg2>::type const type;
57};
58
59// Replacement of templates
60template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
61struct Replace<TT<T1>, Arg1, Arg2> {
62  typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
63};
64
65template<template<typename, typename> class TT, typename T1, typename T2,
66         typename Arg1, typename Arg2>
67struct Replace<TT<T1, T2>, Arg1, Arg2> {
68  typedef TT<typename Replace<T1, Arg1, Arg2>::type,
69             typename Replace<T2, Arg1, Arg2>::type> type;
70};
71
72// Just for kicks...
73template<template<typename, typename> class TT, typename T1,
74         typename Arg1, typename Arg2>
75struct Replace<TT<T1, _2>, Arg1, Arg2> {
76  typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
77};
78
79int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
80int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
81int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
82int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
83int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
84