issue150.cpp revision 0b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68
167714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor// RUN: %clang_cc1 -fsyntax-only -verify %s
267714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor
367714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor// Core issue 150: Template template parameters and default arguments
467714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor
59a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregortemplate<typename T, typename U>
69a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregorstruct is_same {
79a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  static const bool value = false;
89a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor};
99a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
109a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregortemplate<typename T>
119a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregorstruct is_same<T, T> {
129a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  static const bool value = true;
139a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor};
149a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
1567714230a191bc3c01f33378f34f34ef377991a6Douglas Gregornamespace PR9353 {
1667714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor  template<class _T, class Traits> class IM;
1767714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor
1867714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor  template <class T, class Trt,
1967714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor            template<class _T, class Traits = int> class IntervalMap>
2067714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor  void foo(IntervalMap<T,Trt>* m) { typedef IntervalMap<int> type; }
2167714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor
2267714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor  void f(IM<int, int>* m) { foo(m); }
2367714230a191bc3c01f33378f34f34ef377991a6Douglas Gregor}
249a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
259a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregornamespace PR9400 {
269a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  template<template <typename T, typename = T > class U> struct A
279a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  {
289a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    template<int> U<int> foo();
299a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  };
309a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
319a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  template <typename T, typename = T>
329a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  struct s {
339a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  };
349a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
359a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  void f() {
369a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    A<s> x;
379a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    x.foo<2>();
389a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  }
399a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor}
409a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
419a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregornamespace MultiReplace {
429a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  template<typename Z,
439a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor           template<typename T, typename U = T *, typename V = U const> class TT>
449a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  struct X {
459a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    typedef TT<Z> type;
469a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  };
479a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
489a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  template<typename T, typename = int, typename = float>
499a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  struct Y { };
509a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
519a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  int check0[is_same<X<int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
529a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor}
539a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
549a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregornamespace MultiReplacePartial {
559a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  template<typename First, typename Z,
569a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor           template<typename T, typename U = T *, typename V = U const> class TT>
579a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  struct X {
589a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    typedef TT<Z> type;
599a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  };
609a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
619a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  template<typename Z,
629a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor           template<typename T, typename U = T *, typename V = U const> class TT>
639a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  struct X<int, Z, TT> {
649a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    typedef TT<Z> type;
659a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  };
669a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
679a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  template<typename T, typename = int, typename = float>
689a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  struct Y { };
699a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
709a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  int check0[is_same<X<int, int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
719a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor}
720b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor
730b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregornamespace PR9016 {
740b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  template<typename > struct allocator ;
750b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  template<typename > struct less ;
760b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor
770b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  template<class T, template<class> class Compare, class Default,
780b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor           template<class> class Alloc>
790b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  struct interval_set { };
800b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor
810b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  template <class X, template<class> class = less> struct interval_type_default {
820b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor    typedef X type;
830b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  };
840b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor
850b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  template <class T,
860b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor            template<class _T, template<class> class Compare = less,
870b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor                     class = typename interval_type_default<_T,Compare>::type,
880b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor                     template<class> class = allocator> class IntervalSet>
890b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  struct ZZZ
900b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  {
910b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor    IntervalSet<T> IntervalSetT;
920b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  };
930b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor
940b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  void test() {
950b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor    ZZZ<int, interval_set> zzz;
960b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor  }
970b4bcb639a9aab9c466a9e6d6e61b3bd1bb36d68Douglas Gregor}
98