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