Index: include/__tuple =================================================================== --- include/__tuple +++ include/__tuple @@ -245,19 +245,30 @@ // __tuple_convertible -template +template struct __tuple_convertible_imp : public false_type {}; template -struct __tuple_convertible_imp, __tuple_types<_Up0, _Up...> > +struct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > : public integral_constant::value && - __tuple_convertible_imp, __tuple_types<_Up...> >::value> {}; + __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; template <> -struct __tuple_convertible_imp, __tuple_types<> > +struct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > : public true_type {}; +template +struct __tuple_convertible_apply : public false_type {}; + +template +struct __tuple_convertible_apply + : public __tuple_convertible_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + template ::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_convertible @@ -265,26 +276,36 @@ template struct __tuple_convertible<_Tp, _Up, true, true> - : public __tuple_convertible_imp::type>::value == - tuple_size<_Up>::value, - typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type> + : public __tuple_convertible_apply::type>::value == + tuple_size<_Up>::value, _Tp, _Up> {}; // __tuple_constructible -template +template struct __tuple_constructible_imp : public false_type {}; template -struct __tuple_constructible_imp, __tuple_types<_Up0, _Up...> > +struct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > : public integral_constant::value && - __tuple_constructible_imp, __tuple_types<_Up...> >::value> {}; + __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; template <> -struct __tuple_constructible_imp, __tuple_types<> > +struct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> > : public true_type {}; +template +struct __tuple_constructible_apply : public false_type {}; + +template +struct __tuple_constructible_apply + : public __tuple_constructible_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + template ::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_constructible @@ -292,26 +313,36 @@ template struct __tuple_constructible<_Tp, _Up, true, true> - : public __tuple_constructible_imp::type>::value == - tuple_size<_Up>::value, - typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type> + : public __tuple_constructible_apply::type>::value == + tuple_size<_Up>::value, _Tp, _Up> {}; // __tuple_assignable -template +template struct __tuple_assignable_imp : public false_type {}; template -struct __tuple_assignable_imp, __tuple_types<_Up0, _Up...> > +struct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > : public integral_constant::value && - __tuple_assignable_imp, __tuple_types<_Up...> >::value> {}; + __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; template <> -struct __tuple_assignable_imp, __tuple_types<> > +struct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> > : public true_type {}; +template +struct __tuple_assignable_apply : public false_type {}; + +template +struct __tuple_assignable_apply + : __tuple_assignable_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + template ::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_assignable @@ -319,9 +350,8 @@ template struct __tuple_assignable<_Tp, _Up, true, true> - : public __tuple_assignable_imp::type>::value == - tuple_size<_Up>::value, - typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type> + : public __tuple_assignable_apply::type>::value == + tuple_size<_Up>::value, _Tp, _Up> {}; _LIBCPP_END_NAMESPACE_STD Index: test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp =================================================================== --- /dev/null +++ test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class tuple; + +// template > +// tuple & operator=(Tuple &&); + +// This test checks that we do not evaluate __make_tuple_types +// on the array when it doesn't match the size of the tuple. + +#include +#include + +// Use 1256 to try and blow the template instantiation depth for all compilers. +typedef std::array array_t; +typedef std::tuple tuple_t; + +int main() +{ + array_t arr; + tuple_t tup; + tup = arr; +} Index: test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp =================================================================== --- /dev/null +++ test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template class tuple; + +// template > +// tuple(Tuple &&); +// +// template > +// tuple(Tuple &&); + +// This test checks that we do not evaluate __make_tuple_types +// on the array. + +#include +#include + +// Use 1256 to try and blow the template instantiation depth for all compilers. +typedef std::array array_t; +typedef std::tuple tuple_t; + +int main() +{ + array_t arr; + tuple_t tup(arr); +}