blob: 375d199f5899c7205e443d7755916ab9118fcfe3 [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only %s
Douglas Gregordb0d4b72009-11-11 23:06:43 +00002
3// Template argument deduction with template template parameters.
4template<typename T, template<T> class A>
5struct X0 {
6 static const unsigned value = 0;
7};
8
9template<template<int> class A>
10struct X0<int, A> {
11 static const unsigned value = 1;
12};
13
14template<int> struct X0i;
15template<long> struct X0l;
16int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
17int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
18
19template<typename T, typename U>
20struct is_same {
21 static const bool value = false;
22};
23
24template<typename T>
25struct is_same<T, T> {
26 static const bool value = true;
27};
28
29template<typename T> struct allocator { };
30template<typename T, typename Alloc = allocator<T> > struct vector {};
31
32// Fun with meta-lambdas!
33struct _1 {};
34struct _2 {};
35
36// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
37template<typename T, typename Arg1, typename Arg2>
38struct Replace {
39 typedef T type;
40};
41
42// Replacement of the whole type.
43template<typename Arg1, typename Arg2>
44struct Replace<_1, Arg1, Arg2> {
45 typedef Arg1 type;
46};
47
48template<typename Arg1, typename Arg2>
49struct Replace<_2, Arg1, Arg2> {
50 typedef Arg2 type;
51};
52
53// Replacement through cv-qualifiers
54template<typename T, typename Arg1, typename Arg2>
55struct Replace<const T, Arg1, Arg2> {
56 typedef typename Replace<T, Arg1, Arg2>::type const type;
57};
58
59// Replacement of templates
60template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
61struct Replace<TT<T1>, Arg1, Arg2> {
62 typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
63};
64
65template<template<typename, typename> class TT, typename T1, typename T2,
66 typename Arg1, typename Arg2>
67struct Replace<TT<T1, T2>, Arg1, Arg2> {
68 typedef TT<typename Replace<T1, Arg1, Arg2>::type,
69 typename Replace<T2, Arg1, Arg2>::type> type;
70};
71
72// Just for kicks...
73template<template<typename, typename> class TT, typename T1,
74 typename Arg1, typename Arg2>
75struct Replace<TT<T1, _2>, Arg1, Arg2> {
76 typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
77};
78
79int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
80int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
81int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
82int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
83int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
Chandler Carruthe7242462009-12-30 04:10:01 +000084
85// PR5911
86template <typename T, int N> void f(const T (&a)[N]);
87int iarr[] = { 1 };
88void test_PR5911() { f(iarr); }