summaryrefslogtreecommitdiff
path: root/test/SemaTemplate/deduction.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-11 23:06:43 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-11 23:06:43 +0000
commitdb0d4b751e83b8841b8f48f913f17e50467f13d4 (patch)
treedacbc00c291d96ddf195da7a3a59f41f5cfaa56b /test/SemaTemplate/deduction.cpp
parent8406aedf4782771e520614ee379594dc0a4f7d5f (diff)
downloadclang-db0d4b751e83b8841b8f48f913f17e50467f13d4.tar.gz
clang-db0d4b751e83b8841b8f48f913f17e50467f13d4.tar.bz2
clang-db0d4b751e83b8841b8f48f913f17e50467f13d4.tar.xz
Template argument deduction for template template parameters. This
permits, among other things, ripping apart and reconstructing templates via partial specialization: template<typename T> struct DeepRemoveConst { typedef T type; }; template<typename T> struct DeepRemoveConst<const T> { typedef typename DeepRemoveConst<T>::type type; }; template<template<typename> class TT, typename T> struct DeepRemoveConst<TT<T> > { typedef TT<typename DeepRemoveConst<T>::type> type; }; Also, fix a longstanding thinko in the code handling partial ordering of class template partial specializations. We were performing the second deduction without clearing out the results of the first deduction. It's amazing we got through so much code with such a horrendous error :( git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86893 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaTemplate/deduction.cpp')
-rw-r--r--test/SemaTemplate/deduction.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp
new file mode 100644
index 0000000000..7b7e18f74a
--- /dev/null
+++ b/test/SemaTemplate/deduction.cpp
@@ -0,0 +1,83 @@
+// RUN: clang-cc -fsyntax-only %s
+
+// Template argument deduction with template template parameters.
+template<typename T, template<T> class A>
+struct X0 {
+ static const unsigned value = 0;
+};
+
+template<template<int> class A>
+struct X0<int, A> {
+ static const unsigned value = 1;
+};
+
+template<int> struct X0i;
+template<long> struct X0l;
+int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
+int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
+
+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;
+};
+
+template<typename T> struct allocator { };
+template<typename T, typename Alloc = allocator<T> > struct vector {};
+
+// Fun with meta-lambdas!
+struct _1 {};
+struct _2 {};
+
+// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
+template<typename T, typename Arg1, typename Arg2>
+struct Replace {
+ typedef T type;
+};
+
+// Replacement of the whole type.
+template<typename Arg1, typename Arg2>
+struct Replace<_1, Arg1, Arg2> {
+ typedef Arg1 type;
+};
+
+template<typename Arg1, typename Arg2>
+struct Replace<_2, Arg1, Arg2> {
+ typedef Arg2 type;
+};
+
+// Replacement through cv-qualifiers
+template<typename T, typename Arg1, typename Arg2>
+struct Replace<const T, Arg1, Arg2> {
+ typedef typename Replace<T, Arg1, Arg2>::type const type;
+};
+
+// Replacement of templates
+template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
+struct Replace<TT<T1>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
+};
+
+template<template<typename, typename> class TT, typename T1, typename T2,
+ typename Arg1, typename Arg2>
+struct Replace<TT<T1, T2>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type,
+ typename Replace<T2, Arg1, Arg2>::type> type;
+};
+
+// Just for kicks...
+template<template<typename, typename> class TT, typename T1,
+ typename Arg1, typename Arg2>
+struct Replace<TT<T1, _2>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
+};
+
+int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
+int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
+int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
+int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
+int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];