deduction.cpp revision e724246b9f655801bd96b727daf9dddc44beef4d
1// RUN: %clang_cc1 -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 85// PR5911 86template <typename T, int N> void f(const T (&a)[N]); 87int iarr[] = { 1 }; 88void test_PR5911() { f(iarr); } 89