1ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// RUN: %clang_cc1 -fsyntax-only -verify %s
2ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
3ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// A simple cons-style typelist
4ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct nil { };
5ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
6ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename Head, typename Tail = nil>
7ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct cons {
8ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef Head head;
9ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef Tail tail;
10ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
11ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
12ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// is_same trait, for testing
13ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename T, typename U>
14ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct is_same {
15ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  static const bool value = false;
16ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
17ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
18ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename T>
19ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct is_same<T, T> {
20ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  static const bool value = true;
21ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
22ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
23ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// metaprogram that computes the length of a list
24ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename T> struct length;
25ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
26ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename Head, typename Tail>
27ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct length<cons<Head, Tail> > {
28ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  static const unsigned value = length<Tail>::value + 1;
29ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
30ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
31ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<>
32ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct length<nil> {
33ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  static const unsigned value = 0;
34ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
35ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
36ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotypedef cons<unsigned char,
37ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao             cons<unsigned short,
38ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao                  cons<unsigned int,
39ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao                       cons<unsigned long> > > > unsigned_inttypes;
40ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoint length0[length<unsigned_inttypes>::value == 4? 1 : -1];
41ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
42ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// metaprogram that reverses a list
43ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
44ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// FIXME: I would prefer that this be a partial specialization, but
45ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// that requires partial ordering of class template partial
46ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// specializations.
47ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename T>
48ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoclass reverse {
49ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef typename reverse<typename T::tail>::type reversed_tail;
50ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
51ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef typename reverse<typename reversed_tail::tail>::type most_of_tail;
52ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
53ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaopublic:
54ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef cons<typename reversed_tail::head,
55ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao               typename reverse<cons<typename T::head, most_of_tail> >::type> type;
56ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
57ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
58ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename Head>
59ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoclass reverse<cons<Head> > {
60ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaopublic:
61ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef cons<Head> type;
62ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
63ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
64ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<>
65ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoclass reverse<nil> {
66ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaopublic:
67ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef nil type;
68ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
69ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
70ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoint reverse0[is_same<reverse<unsigned_inttypes>::type,
71ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao                     cons<unsigned long,
72ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao                          cons<unsigned int,
73ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao                               cons<unsigned short,
74ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao                                    cons<unsigned char> > > > >::value? 1 : -1];
75ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
76ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// metaprogram that finds a type within a list
77ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
78ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// FIXME: I would prefer that this be a partial specialization, but
79ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// that requires partial ordering of class template partial
80ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// specializations.
81ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename List, typename T>
82ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct find : find<typename List::tail, T> { };
83ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
84ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename Tail, typename T>
85ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct find<cons<T, Tail>, T> {
86ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef cons<T, Tail> type;
87ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
88ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
89ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaotemplate<typename T>
90ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaostruct find<nil, T> {
91ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao  typedef nil type;
92ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao};
93ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
94ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoint find0[is_same<find<unsigned_inttypes, unsigned int>::type,
95ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao                       cons<unsigned int, cons<unsigned long> > >::value?
96ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao             1 : -1];
97ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoint find1[is_same<find<unsigned_inttypes, int>::type, nil>::value? 1 : -1];
98ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao
99