12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RUN: %clang_cc1 -fsyntax-only -verify %s 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// expected-no-diagnostics 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A simple cons-style typelist 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct nil { }; 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitemplate<typename Head, typename Tail = nil> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct cons { 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) typedef Head head; 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef Tail tail; 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}; 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// is_same trait, for testing 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)template<typename T, typename U> 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)struct is_same { 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const bool value = false; 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T> 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct is_same<T, T> { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const bool value = true; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// metaprogram that computes the length of a list 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T> struct length; 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)template<typename Head, typename Tail> 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct length<cons<Head, Tail> > { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned value = length<Tail>::value + 1; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<> 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct length<nil> { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const unsigned value = 0; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef cons<unsigned char, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cons<unsigned short, 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cons<unsigned int, 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cons<unsigned long> > > > unsigned_inttypes; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int length0[length<unsigned_inttypes>::value == 4? 1 : -1]; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// metaprogram that reverses a list 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// FIXME: I would prefer that this be a partial specialization, but 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that requires partial ordering of class template partial 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// specializations. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T> 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class reverse { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef typename reverse<typename T::tail>::type reversed_tail; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef typename reverse<typename reversed_tail::tail>::type most_of_tail; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef cons<typename reversed_tail::head, 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typename reverse<cons<typename T::head, most_of_tail> >::type> type; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename Head> 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class reverse<cons<Head> > { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef cons<Head> type; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<> 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class reverse<nil> { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef nil type; 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int reverse0[is_same<reverse<unsigned_inttypes>::type, 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cons<unsigned long, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cons<unsigned int, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cons<unsigned short, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cons<unsigned char> > > > >::value? 1 : -1]; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// metaprogram that finds a type within a list 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// FIXME: I would prefer that this be a partial specialization, but 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that requires partial ordering of class template partial 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// specializations. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename List, typename T> 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct find : find<typename List::tail, T> { }; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename Tail, typename T> 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct find<cons<T, Tail>, T> { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef cons<T, Tail> type; 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T> 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct find<nil, T> { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef nil type; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int find0[is_same<find<unsigned_inttypes, unsigned int>::type, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cons<unsigned int, cons<unsigned long> > >::value? 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1 : -1]; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int find1[is_same<find<unsigned_inttypes, int>::type, nil>::value? 1 : -1]; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)