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