// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 // Template argument deduction with template template parameters. template<typename T, template<T> class A> struct X0 { static const unsigned value = 0; }; template<template<int> class A> struct X0<int, A> { static const unsigned value = 1; }; template<int> struct X0i; template<long> struct X0l; int array_x0a[X0<long, X0l>::value == 0? 1 : -1]; int array_x0b[X0<int, X0i>::value == 1? 1 : -1]; template<typename T, typename U> struct is_same { static const bool value = false; }; template<typename T> struct is_same<T, T> { static const bool value = true; }; template<typename T> struct allocator { }; template<typename T, typename Alloc = allocator<T> > struct vector {}; // Fun with meta-lambdas! struct _1 {}; struct _2 {}; // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T. template<typename T, typename Arg1, typename Arg2> struct Replace { typedef T type; }; // Replacement of the whole type. template<typename Arg1, typename Arg2> struct Replace<_1, Arg1, Arg2> { typedef Arg1 type; }; template<typename Arg1, typename Arg2> struct Replace<_2, Arg1, Arg2> { typedef Arg2 type; }; // Replacement through cv-qualifiers template<typename T, typename Arg1, typename Arg2> struct Replace<const T, Arg1, Arg2> { typedef typename Replace<T, Arg1, Arg2>::type const type; }; // Replacement of templates template<template<typename> class TT, typename T1, typename Arg1, typename Arg2> struct Replace<TT<T1>, Arg1, Arg2> { typedef TT<typename Replace<T1, Arg1, Arg2>::type> type; }; template<template<typename, typename> class TT, typename T1, typename T2, typename Arg1, typename Arg2> struct Replace<TT<T1, T2>, Arg1, Arg2> { typedef TT<typename Replace<T1, Arg1, Arg2>::type, typename Replace<T2, Arg1, Arg2>::type> type; }; // Just for kicks... template<template<typename, typename> class TT, typename T1, typename Arg1, typename Arg2> struct Replace<TT<T1, _2>, Arg1, Arg2> { typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type; }; int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1]; int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1]; int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1]; int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1]; int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1]; // PR5911 template <typename T, int N> void f(const T (&a)[N]); int iarr[] = { 1 }; void test_PR5911() { f(iarr); } // Must not examine base classes of incomplete type during template argument // deduction. namespace PR6257 { template <typename T> struct X { template <typename U> X(const X<U>& u); }; struct A; void f(A& a); void f(const X<A>& a); void test(A& a) { (void)f(a); } } // PR7463 namespace PR7463 { const int f (); template <typename T_> void g (T_&); // expected-note{{T_ = int}} void h (void) { g(f()); } // expected-error{{no matching function for call}} } namespace test0 { template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}} char *char_maker(); void test() { make(char_maker); // expected-error {{no matching function for call to 'make'}} } } namespace test1 { template<typename T> void foo(const T a[3][3]); void test() { int a[3][3]; foo(a); } } // PR7708 namespace test2 { template<typename T> struct Const { typedef void const type; }; template<typename T> void f(T, typename Const<T>::type*); template<typename T> void f(T, void const *); void test() { void *p = 0; f(0, p); } } // rdar://problem/8537391 namespace test3 { struct Foo { template <void F(char)> static inline void foo(); }; class Bar { template<typename T> static inline void wobble(T ch); public: static void madness() { Foo::foo<wobble<char> >(); } }; } // Verify that we can deduce enum-typed arguments correctly. namespace test14 { enum E { E0, E1 }; template <E> struct A {}; template <E e> void foo(const A<e> &a) {} void test() { A<E0> a; foo(a); } } namespace PR21536 { template<typename ...T> struct X; template<typename A, typename ...B> struct S { static_assert(sizeof...(B) == 1, ""); void f() { using T = A; using T = int; using U = X<B...>; using U = X<int>; } }; template<typename ...T> void f(S<T...>); void g() { f(S<int, int>()); } } namespace PR19372 { template <template<typename...> class C, typename ...Us> struct BindBack { template <typename ...Ts> using apply = C<Ts..., Us...>; }; template <typename, typename...> struct Y; template <typename ...Ts> using Z = Y<Ts...>; using T = BindBack<Z, int>::apply<>; using T = Z<int>; using U = BindBack<Z, int, int>::apply<char>; using U = Z<char, int, int>; namespace BetterReduction { template<typename ...> struct S; template<typename ...A> using X = S<A...>; // expected-note {{parameter}} template<typename ...A> using Y = X<A..., A...>; template<typename ...A> using Z = X<A..., 1, 2, 3>; // expected-error {{must be a type}} using T = Y<int>; using T = S<int, int>; } } namespace PR18645 { template<typename F> F Quux(F &&f); auto Baz = Quux(Quux<float>); } namespace NonDeducedNestedNameSpecifier { template<typename T> struct A { template<typename U> struct B { B(int) {} }; }; template<typename T> int f(A<T>, typename A<T>::template B<T>); int k = f(A<int>(), 0); } namespace PR27601_RecursivelyInheritedBaseSpecializationsDeductionAmbiguity { namespace ns1 { template<class...> struct B { }; template<class H, class ... Ts> struct B<H, Ts...> : B<> { }; template<class ... Ts> struct D : B<Ts...> { }; template<class T, class ... Ts> void f(B<T, Ts...> &) { } int main() { D<int, char> d; f<int>(d); } } //end ns1 namespace ns2 { template <int i, typename... Es> struct tup_impl; template <int i> struct tup_impl<i> {}; // empty tail template <int i, typename Head, typename... Tail> struct tup_impl<i, Head, Tail...> : tup_impl<i + 1, Tail...> { using value_type = Head; Head head; }; template <typename... Es> struct tup : tup_impl<0, Es...> {}; template <typename Head, int i, typename... Tail> Head &get_helper(tup_impl<i, Head, Tail...> &t) { return t.head; } template <typename Head, int i, typename... Tail> Head const &get_helper(tup_impl<i, Head, Tail...> const &t) { return t.head; } int main() { tup<int, double, char> t; get_helper<double>(t); return 0; } } // end ns2 }