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