1// RUN: %clang_cc1 -fsyntax-only -verify %s 2// expected-no-diagnostics 3 4// A simple cons-style typelist 5struct nil { }; 6 7template<typename Head, typename Tail = nil> 8struct cons { 9 typedef Head head; 10 typedef Tail tail; 11}; 12 13// is_same trait, for testing 14template<typename T, typename U> 15struct is_same { 16 static const bool value = false; 17}; 18 19template<typename T> 20struct is_same<T, T> { 21 static const bool value = true; 22}; 23 24// metaprogram that computes the length of a list 25template<typename T> struct length; 26 27template<typename Head, typename Tail> 28struct length<cons<Head, Tail> > { 29 static const unsigned value = length<Tail>::value + 1; 30}; 31 32template<> 33struct length<nil> { 34 static const unsigned value = 0; 35}; 36 37typedef cons<unsigned char, 38 cons<unsigned short, 39 cons<unsigned int, 40 cons<unsigned long> > > > unsigned_inttypes; 41int 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. 48template<typename T> 49class 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 54public: 55 typedef cons<typename reversed_tail::head, 56 typename reverse<cons<typename T::head, most_of_tail> >::type> type; 57}; 58 59template<typename Head> 60class reverse<cons<Head> > { 61public: 62 typedef cons<Head> type; 63}; 64 65template<> 66class reverse<nil> { 67public: 68 typedef nil type; 69}; 70 71int 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. 82template<typename List, typename T> 83struct find : find<typename List::tail, T> { }; 84 85template<typename Tail, typename T> 86struct find<cons<T, Tail>, T> { 87 typedef cons<T, Tail> type; 88}; 89 90template<typename T> 91struct find<nil, T> { 92 typedef nil type; 93}; 94 95int find0[is_same<find<unsigned_inttypes, unsigned int>::type, 96 cons<unsigned int, cons<unsigned long> > >::value? 97 1 : -1]; 98int find1[is_same<find<unsigned_inttypes, int>::type, nil>::value? 1 : -1]; 99 100