aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-06-09 21:22:32 +0000
committerDouglas Gregor <dgregor@apple.com>2009-06-09 21:22:32 +0000
commit6d968e89411406f0fd22ae69c77c79a425e2de6f (patch)
tree6f578c48d6ccf872d359baabb16d4e39d279dd3d
parentd708c72e3e5186662fb0045d2bd666bfd93a013d (diff)
Example metaprogram for reversing and searching in a type list
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73147 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--test/SemaTemplate/example-typelist.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/test/SemaTemplate/example-typelist.cpp b/test/SemaTemplate/example-typelist.cpp
index e130725530..4a2aeb20e7 100644
--- a/test/SemaTemplate/example-typelist.cpp
+++ b/test/SemaTemplate/example-typelist.cpp
@@ -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];
+