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