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