p3.cpp revision 500d331eade2f5070b66ba51d777224f9fda6e1d
1500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor// RUN: clang-cc -fsyntax-only %s 2500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 3500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregortemplate<typename T> struct A { }; 4500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 5500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor// Top-level cv-qualifiers of P's type are ignored for type deduction. 6500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregortemplate<typename T> A<T> f0(const T); 7500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 8500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregorvoid test_f0(int i, const int ci) { 9500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor A<int> a0 = f0(i); 10500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor A<int> a1 = f0(ci); 11500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor} 12500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 13500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor// If P is a reference type, the type referred to by P is used for type 14500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor// deduction. 15500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregortemplate<typename T> A<T> f1(T&); 16500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 17500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregorvoid test_f1(int i, const int ci, volatile int vi) { 18500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor A<int> a0 = f1(i); 19500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor A<const int> a1 = f1(ci); 20500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor A<volatile int> a2 = f1(vi); 21500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor} 22500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 23500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregortemplate<typename T, unsigned N> struct B { }; 24500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregortemplate<typename T, unsigned N> B<T, N> g0(T (&array)[N]); 25500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 26500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregorvoid test_g0() { 27500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor int array0[5]; 28500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor B<int, 5> b0 = g0(array0); 29500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor const int array1[] = { 1, 2, 3}; 30500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor B<const int, 3> b1 = g0(array1); 31500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor} 32500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 33500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor// - If the original P is a reference type, the deduced A (i.e., the type 34500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor// referred to by the reference) can be more cv-qualified than the 35500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor// transformed A. 36500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregortemplate<typename T> A<T> f2(const T&); 37500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 38500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregorvoid test_f2(int i, const int ci, volatile int vi) { 39500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor A<int> a0 = f2(i); 40500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor A<int> a1 = f2(ci); 41500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor A<volatile int> a2 = f2(vi); 42500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor} 43500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor 44500d331eade2f5070b66ba51d777224f9fda6e1dDouglas Gregor// FIXME: the next two bullets require a bit of effort.