]> granicus.if.org Git - clang/commitdiff
Example metaprogram for reversing and searching in a type list
authorDouglas Gregor <dgregor@apple.com>
Tue, 9 Jun 2009 21:22:32 +0000 (21:22 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 9 Jun 2009 21:22:32 +0000 (21:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73147 91177308-0d34-0410-b5e6-96231b3b80d8

test/SemaTemplate/example-typelist.cpp

index e130725530ed26b6114c7a02fa162b19c2a2f3b7..4a2aeb20e7302e6daa374bfc4bf49e1dc93dcacb 100644 (file)
@@ -1,5 +1,6 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
+// A simple cons-style typelist
 struct nil { };
 
 template<typename Head, typename Tail = nil>
@@ -8,6 +9,17 @@ struct cons {
   typedef Tail tail;
 };
 
+// is_same trait, for testing
+template<typename T, typename U>
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+
 // metaprogram that computes the length of a list
 template<typename T> struct length;
 
@@ -26,3 +38,61 @@ typedef cons<unsigned char,
                   cons<unsigned int,
                        cons<unsigned long> > > > unsigned_inttypes;
 int length0[length<unsigned_inttypes>::value == 4? 1 : -1];
+
+// metaprogram that reverses a list
+
+// FIXME: I would prefer that this be a partial specialization, but
+// that requires partial ordering of class template partial
+// specializations.
+template<typename T> 
+class reverse {
+  typedef typename reverse<typename T::tail>::type reversed_tail;
+
+  typedef typename reverse<typename reversed_tail::tail>::type most_of_tail;
+
+public:
+  typedef cons<typename reversed_tail::head,
+               typename reverse<cons<typename T::head, most_of_tail> >::type> type;
+};
+
+template<typename Head>
+class reverse<cons<Head> > {
+public:
+  typedef cons<Head> type;
+};
+
+template<>
+class reverse<nil> {
+public:
+  typedef nil type;
+};
+
+int reverse0[is_same<reverse<unsigned_inttypes>::type,
+                     cons<unsigned long, 
+                          cons<unsigned int, 
+                               cons<unsigned short,
+                                    cons<unsigned char> > > > >::value? 1 : -1];
+
+// metaprogram that finds a type within a list
+
+// FIXME: I would prefer that this be a partial specialization, but
+// that requires partial ordering of class template partial
+// specializations.
+template<typename List, typename T>
+struct find : find<typename List::tail, T> { };
+
+template<typename Tail, typename T>
+struct find<cons<T, Tail>, T> {
+  typedef cons<T, Tail> type;
+};
+
+template<typename T>
+struct find<nil, T> {
+  typedef nil type;
+};
+
+int find0[is_same<find<unsigned_inttypes, unsigned int>::type,
+                       cons<unsigned int, cons<unsigned long> > >::value?
+             1 : -1];
+int find1[is_same<find<unsigned_inttypes, int>::type, nil>::value? 1 : -1];
+