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