Home | History | Annotate | Download | only in SemaTemplate
      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