diff options
Diffstat (limited to 'test/SemaTemplate/deduction.cpp')
-rw-r--r-- | test/SemaTemplate/deduction.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp new file mode 100644 index 0000000..7b7e18f --- /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]; |