diff options
Diffstat (limited to 'libcxx')
3 files changed, 117 insertions, 21 deletions
diff --git a/libcxx/include/__tuple b/libcxx/include/__tuple index ee5b916fa52..bffb95cb72c 100644 --- a/libcxx/include/__tuple +++ b/libcxx/include/__tuple @@ -245,19 +245,30 @@ struct __make_tuple_types // __tuple_convertible -template <bool, class _Tp, class _Up> +template <class, class> struct __tuple_convertible_imp : public false_type {}; template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_convertible_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > +struct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > : public integral_constant<bool, is_convertible<_Tp0, _Up0>::value && - __tuple_convertible_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; + __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; template <> -struct __tuple_convertible_imp<true, __tuple_types<>, __tuple_types<> > +struct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > : public true_type {}; +template <bool, class, class> +struct __tuple_convertible_apply : public false_type {}; + +template <class _Tp, class _Up> +struct __tuple_convertible_apply<true, _Tp, _Up> + : public __tuple_convertible_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_convertible @@ -265,26 +276,36 @@ struct __tuple_convertible template <class _Tp, class _Up> struct __tuple_convertible<_Tp, _Up, true, true> - : public __tuple_convertible_imp<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, - typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type> + : public __tuple_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == + tuple_size<_Up>::value, _Tp, _Up> {}; // __tuple_constructible -template <bool, class _Tp, class _Up> +template <class, class> struct __tuple_constructible_imp : public false_type {}; template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_constructible_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > +struct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > : public integral_constant<bool, is_constructible<_Up0, _Tp0>::value && - __tuple_constructible_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; + __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; template <> -struct __tuple_constructible_imp<true, __tuple_types<>, __tuple_types<> > +struct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> > : public true_type {}; +template <bool _SameSize, class, class> +struct __tuple_constructible_apply : public false_type {}; + +template <class _Tp, class _Up> +struct __tuple_constructible_apply<true, _Tp, _Up> + : public __tuple_constructible_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_constructible @@ -292,26 +313,36 @@ struct __tuple_constructible template <class _Tp, class _Up> struct __tuple_constructible<_Tp, _Up, true, true> - : public __tuple_constructible_imp<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, - typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type> + : public __tuple_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == + tuple_size<_Up>::value, _Tp, _Up> {}; // __tuple_assignable -template <bool, class _Tp, class _Up> +template <class, class> struct __tuple_assignable_imp : public false_type {}; template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_assignable_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > +struct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > : public integral_constant<bool, is_assignable<_Up0&, _Tp0>::value && - __tuple_assignable_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; + __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; template <> -struct __tuple_assignable_imp<true, __tuple_types<>, __tuple_types<> > +struct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> > : public true_type {}; +template <bool, class, class> +struct __tuple_assignable_apply : public false_type {}; + +template <class _Tp, class _Up> +struct __tuple_assignable_apply<true, _Tp, _Up> + : __tuple_assignable_imp< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > +{}; + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_assignable @@ -319,9 +350,8 @@ struct __tuple_assignable template <class _Tp, class _Up> struct __tuple_assignable<_Tp, _Up, true, true> - : public __tuple_assignable_imp<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, - typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type> + : public __tuple_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value == + tuple_size<_Up>::value, _Tp, _Up> {}; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp new file mode 100644 index 00000000000..f62d2fed483 --- /dev/null +++ b/libcxx/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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Tuple, __tuple_assignable<Tuple, tuple> > +// 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 <array> +#include <tuple> + +// Use 1256 to try and blow the template instantiation depth for all compilers. +typedef std::array<char, 1256> array_t; +typedef std::tuple<array_t> tuple_t; + +int main() +{ + array_t arr; + tuple_t tup; + tup = arr; +} diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp new file mode 100644 index 00000000000..65a1c701c51 --- /dev/null +++ b/libcxx/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. +// +//===----------------------------------------------------------------------===// + +// <tuple> + +// template <class... Types> class tuple; + +// template <class Tuple, __tuple_convertible<Tuple, tuple> > +// tuple(Tuple &&); +// +// template <class Tuple, __tuple_constructible<Tuple, tuple> > +// tuple(Tuple &&); + +// This test checks that we do not evaluate __make_tuple_types +// on the array. + +#include <array> +#include <tuple> + +// Use 1256 to try and blow the template instantiation depth for all compilers. +typedef std::array<char, 1256> array_t; +typedef std::tuple<array_t> tuple_t; + +int main() +{ + array_t arr; + tuple_t tup(arr); +} |

