Daniel Dunbar | a572887 | 2009-12-15 20:14:24 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only %s |
Douglas Gregor | db0d4b7 | 2009-11-11 23:06:43 +0000 | [diff] [blame] | 2 | |
| 3 | // Template argument deduction with template template parameters. |
| 4 | template<typename T, template<T> class A> |
| 5 | struct X0 { |
| 6 | static const unsigned value = 0; |
| 7 | }; |
| 8 | |
| 9 | template<template<int> class A> |
| 10 | struct X0<int, A> { |
| 11 | static const unsigned value = 1; |
| 12 | }; |
| 13 | |
| 14 | template<int> struct X0i; |
| 15 | template<long> struct X0l; |
| 16 | int array_x0a[X0<long, X0l>::value == 0? 1 : -1]; |
| 17 | int array_x0b[X0<int, X0i>::value == 1? 1 : -1]; |
| 18 | |
| 19 | template<typename T, typename U> |
| 20 | struct is_same { |
| 21 | static const bool value = false; |
| 22 | }; |
| 23 | |
| 24 | template<typename T> |
| 25 | struct is_same<T, T> { |
| 26 | static const bool value = true; |
| 27 | }; |
| 28 | |
| 29 | template<typename T> struct allocator { }; |
| 30 | template<typename T, typename Alloc = allocator<T> > struct vector {}; |
| 31 | |
| 32 | // Fun with meta-lambdas! |
| 33 | struct _1 {}; |
| 34 | struct _2 {}; |
| 35 | |
| 36 | // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T. |
| 37 | template<typename T, typename Arg1, typename Arg2> |
| 38 | struct Replace { |
| 39 | typedef T type; |
| 40 | }; |
| 41 | |
| 42 | // Replacement of the whole type. |
| 43 | template<typename Arg1, typename Arg2> |
| 44 | struct Replace<_1, Arg1, Arg2> { |
| 45 | typedef Arg1 type; |
| 46 | }; |
| 47 | |
| 48 | template<typename Arg1, typename Arg2> |
| 49 | struct Replace<_2, Arg1, Arg2> { |
| 50 | typedef Arg2 type; |
| 51 | }; |
| 52 | |
| 53 | // Replacement through cv-qualifiers |
| 54 | template<typename T, typename Arg1, typename Arg2> |
| 55 | struct Replace<const T, Arg1, Arg2> { |
| 56 | typedef typename Replace<T, Arg1, Arg2>::type const type; |
| 57 | }; |
| 58 | |
| 59 | // Replacement of templates |
| 60 | template<template<typename> class TT, typename T1, typename Arg1, typename Arg2> |
| 61 | struct Replace<TT<T1>, Arg1, Arg2> { |
| 62 | typedef TT<typename Replace<T1, Arg1, Arg2>::type> type; |
| 63 | }; |
| 64 | |
| 65 | template<template<typename, typename> class TT, typename T1, typename T2, |
| 66 | typename Arg1, typename Arg2> |
| 67 | struct 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... |
| 73 | template<template<typename, typename> class TT, typename T1, |
| 74 | typename Arg1, typename Arg2> |
| 75 | struct Replace<TT<T1, _2>, Arg1, Arg2> { |
| 76 | typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type; |
| 77 | }; |
| 78 | |
| 79 | int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1]; |
| 80 | int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1]; |
| 81 | int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1]; |
| 82 | int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1]; |
| 83 | int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1]; |
Chandler Carruth | e724246 | 2009-12-30 04:10:01 +0000 | [diff] [blame] | 84 | |
| 85 | // PR5911 |
| 86 | template <typename T, int N> void f(const T (&a)[N]); |
| 87 | int iarr[] = { 1 }; |
| 88 | void test_PR5911() { f(iarr); } |