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