1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // expected-no-diagnostics
3 
4 // Core issue 150: Template template parameters and default arguments
5 
6 template<typename T, typename U>
7 struct is_same {
8   static const bool value = false;
9 };
10 
11 template<typename T>
12 struct is_same<T, T> {
13   static const bool value = true;
14 };
15 
16 namespace PR9353 {
17   template<class _T, class Traits> class IM;
18 
19   template <class T, class Trt,
20             template<class _T, class Traits = int> class IntervalMap>
21   void foo(IntervalMap<T,Trt>* m) { typedef IntervalMap<int> type; }
22 
23   void f(IM<int, int>* m) { foo(m); }
24 }
25 
26 namespace PR9400 {
27   template<template <typename T, typename = T > class U> struct A
28   {
29     template<int> U<int> foo();
30   };
31 
32   template <typename T, typename = T>
33   struct s {
34   };
35 
36   void f() {
37     A<s> x;
38     x.foo<2>();
39   }
40 }
41 
42 namespace MultiReplace {
43   template<typename Z,
44            template<typename T, typename U = T *, typename V = U const> class TT>
45   struct X {
46     typedef TT<Z> type;
47   };
48 
49   template<typename T, typename = int, typename = float>
50   struct Y { };
51 
52   int check0[is_same<X<int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
53 }
54 
55 namespace MultiReplacePartial {
56   template<typename First, typename Z,
57            template<typename T, typename U = T *, typename V = U const> class TT>
58   struct X {
59     typedef TT<Z> type;
60   };
61 
62   template<typename Z,
63            template<typename T, typename U = T *, typename V = U const> class TT>
64   struct X<int, Z, TT> {
65     typedef TT<Z> type;
66   };
67 
68   template<typename T, typename = int, typename = float>
69   struct Y { };
70 
71   int check0[is_same<X<int, int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
72 }
73 
74 namespace PR9016 {
75   template<typename > struct allocator ;
76   template<typename > struct less ;
77 
78   template<class T, template<class> class Compare, class Default,
79            template<class> class Alloc>
80   struct interval_set { };
81 
82   template <class X, template<class> class = less> struct interval_type_default {
83     typedef X type;
84   };
85 
86   template <class T,
87             template<class _T, template<class> class Compare = PR9016::less,
88                      class = typename interval_type_default<_T,Compare>::type,
89                      template<class> class = allocator> class IntervalSet>
90   struct ZZZ
91   {
92     IntervalSet<T> IntervalSetT;
93   };
94 
95   template <class T,
96             template<class _T, template<class> class Compare = PR9016::less,
97                      class = typename interval_type_default<_T,Compare>::type,
98                      template<class> class = allocator> class IntervalSet>
99   void int40()
100   {
101     IntervalSet<T> IntervalSetT;
102   }
103 
104   void test() {
105     ZZZ<int, interval_set> zzz;
106     int40<int, interval_set>();
107   }
108 }
109