1739b107aSDouglas Gregor // RUN: %clang_cc1 -fsyntax-only -verify %s
2*c6e68daaSAndy Gibbs // expected-no-diagnostics
3739b107aSDouglas Gregor 
4739b107aSDouglas Gregor // Core issue 150: Template template parameters and default arguments
5739b107aSDouglas Gregor 
6fd7c2255SDouglas Gregor template<typename T, typename U>
7fd7c2255SDouglas Gregor struct is_same {
8fd7c2255SDouglas Gregor   static const bool value = false;
9fd7c2255SDouglas Gregor };
10fd7c2255SDouglas Gregor 
11fd7c2255SDouglas Gregor template<typename T>
12fd7c2255SDouglas Gregor struct is_same<T, T> {
13fd7c2255SDouglas Gregor   static const bool value = true;
14fd7c2255SDouglas Gregor };
15fd7c2255SDouglas Gregor 
16739b107aSDouglas Gregor namespace PR9353 {
17739b107aSDouglas Gregor   template<class _T, class Traits> class IM;
18739b107aSDouglas Gregor 
19739b107aSDouglas Gregor   template <class T, class Trt,
20739b107aSDouglas Gregor             template<class _T, class Traits = int> class IntervalMap>
foo(IntervalMap<T,Trt> * m)21739b107aSDouglas Gregor   void foo(IntervalMap<T,Trt>* m) { typedef IntervalMap<int> type; }
22739b107aSDouglas Gregor 
f(IM<int,int> * m)23739b107aSDouglas Gregor   void f(IM<int, int>* m) { foo(m); }
24739b107aSDouglas Gregor }
25fd7c2255SDouglas Gregor 
26fd7c2255SDouglas Gregor namespace PR9400 {
27fd7c2255SDouglas Gregor   template<template <typename T, typename = T > class U> struct A
28fd7c2255SDouglas Gregor   {
29fd7c2255SDouglas Gregor     template<int> U<int> foo();
30fd7c2255SDouglas Gregor   };
31fd7c2255SDouglas Gregor 
32fd7c2255SDouglas Gregor   template <typename T, typename = T>
33fd7c2255SDouglas Gregor   struct s {
34fd7c2255SDouglas Gregor   };
35fd7c2255SDouglas Gregor 
f()36fd7c2255SDouglas Gregor   void f() {
37fd7c2255SDouglas Gregor     A<s> x;
38fd7c2255SDouglas Gregor     x.foo<2>();
39fd7c2255SDouglas Gregor   }
40fd7c2255SDouglas Gregor }
41fd7c2255SDouglas Gregor 
42fd7c2255SDouglas Gregor namespace MultiReplace {
43fd7c2255SDouglas Gregor   template<typename Z,
44fd7c2255SDouglas Gregor            template<typename T, typename U = T *, typename V = U const> class TT>
45fd7c2255SDouglas Gregor   struct X {
46fd7c2255SDouglas Gregor     typedef TT<Z> type;
47fd7c2255SDouglas Gregor   };
48fd7c2255SDouglas Gregor 
49fd7c2255SDouglas Gregor   template<typename T, typename = int, typename = float>
50fd7c2255SDouglas Gregor   struct Y { };
51fd7c2255SDouglas Gregor 
52fd7c2255SDouglas Gregor   int check0[is_same<X<int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
53fd7c2255SDouglas Gregor }
54fd7c2255SDouglas Gregor 
55fd7c2255SDouglas Gregor namespace MultiReplacePartial {
56fd7c2255SDouglas Gregor   template<typename First, typename Z,
57fd7c2255SDouglas Gregor            template<typename T, typename U = T *, typename V = U const> class TT>
58fd7c2255SDouglas Gregor   struct X {
59fd7c2255SDouglas Gregor     typedef TT<Z> type;
60fd7c2255SDouglas Gregor   };
61fd7c2255SDouglas Gregor 
62fd7c2255SDouglas Gregor   template<typename Z,
63fd7c2255SDouglas Gregor            template<typename T, typename U = T *, typename V = U const> class TT>
64fd7c2255SDouglas Gregor   struct X<int, Z, TT> {
65fd7c2255SDouglas Gregor     typedef TT<Z> type;
66fd7c2255SDouglas Gregor   };
67fd7c2255SDouglas Gregor 
68fd7c2255SDouglas Gregor   template<typename T, typename = int, typename = float>
69fd7c2255SDouglas Gregor   struct Y { };
70fd7c2255SDouglas Gregor 
71fd7c2255SDouglas Gregor   int check0[is_same<X<int, int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
72fd7c2255SDouglas Gregor }
7320bf98b5SDouglas Gregor 
7420bf98b5SDouglas Gregor namespace PR9016 {
7520bf98b5SDouglas Gregor   template<typename > struct allocator ;
7620bf98b5SDouglas Gregor   template<typename > struct less ;
7720bf98b5SDouglas Gregor 
7820bf98b5SDouglas Gregor   template<class T, template<class> class Compare, class Default,
7920bf98b5SDouglas Gregor            template<class> class Alloc>
8020bf98b5SDouglas Gregor   struct interval_set { };
8120bf98b5SDouglas Gregor 
8220bf98b5SDouglas Gregor   template <class X, template<class> class = less> struct interval_type_default {
8320bf98b5SDouglas Gregor     typedef X type;
8420bf98b5SDouglas Gregor   };
8520bf98b5SDouglas Gregor 
8620bf98b5SDouglas Gregor   template <class T,
879d9f8db4SDouglas Gregor             template<class _T, template<class> class Compare = PR9016::less,
8820bf98b5SDouglas Gregor                      class = typename interval_type_default<_T,Compare>::type,
8920bf98b5SDouglas Gregor                      template<class> class = allocator> class IntervalSet>
9020bf98b5SDouglas Gregor   struct ZZZ
9120bf98b5SDouglas Gregor   {
9220bf98b5SDouglas Gregor     IntervalSet<T> IntervalSetT;
9320bf98b5SDouglas Gregor   };
9420bf98b5SDouglas Gregor 
9543669f84SDouglas Gregor   template <class T,
969d9f8db4SDouglas Gregor             template<class _T, template<class> class Compare = PR9016::less,
9743669f84SDouglas Gregor                      class = typename interval_type_default<_T,Compare>::type,
9843669f84SDouglas Gregor                      template<class> class = allocator> class IntervalSet>
int40()9943669f84SDouglas Gregor   void int40()
10043669f84SDouglas Gregor   {
10143669f84SDouglas Gregor     IntervalSet<T> IntervalSetT;
10243669f84SDouglas Gregor   }
10343669f84SDouglas Gregor 
test()10420bf98b5SDouglas Gregor   void test() {
10520bf98b5SDouglas Gregor     ZZZ<int, interval_set> zzz;
10643669f84SDouglas Gregor     int40<int, interval_set>();
10720bf98b5SDouglas Gregor   }
10820bf98b5SDouglas Gregor }
109