Author: ericwf Date: Thu Jun 30 23:07:39 2016 New Revision: 274331 URL: http://llvm.org/viewvc/llvm-project?rev=274331&view=rev Log: Flatten tuple_constructible, tuple_convertible and tuple_assignable.
This patch is the last in a series that replaces recursive meta-programming in std::tuple with non-recursive implementations. Previously std::tuple could only be instantiated with 126 elements before it blew the max template instantiation depth. Now the size of std::tuple is essentially unbounded (I've tested with over 5000 elements). One unfortunate side-effect of this change is that tuple_constructible and similar no longer short circuit after the first failure. Instead they evaluate the conditions for all elements. This could be potentially breaking. I plan to look into this further. Modified: libcxx/trunk/include/__tuple libcxx/trunk/include/tuple Modified: libcxx/trunk/include/__tuple URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__tuple?rev=274331&r1=274330&r2=274331&view=diff ============================================================================== --- libcxx/trunk/include/__tuple (original) +++ libcxx/trunk/include/__tuple Thu Jun 30 23:07:39 2016 @@ -255,7 +255,6 @@ using __type_pack_element = typename dec typename __make_tuple_indices<sizeof...(_Types)>::type >{}) )::type; - #endif template <size_t _Ip, class ..._Types> @@ -266,6 +265,7 @@ public: typedef __type_pack_element<_Ip, _Types...> type; }; + template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> @@ -364,31 +364,36 @@ struct __make_tuple_types<__tuple_types< typedef __tuple_types<_Types...> type; }; -// __tuple_convertible - -template <class, class> -struct __tuple_convertible_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._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<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; +template <bool ..._Preds> +struct __all_dummy; -template <> -struct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > - : public true_type {}; +template <bool ..._Pred> +using __all = is_same<__all_dummy<_Pred...>, __all_dummy<(_Pred, true)...>>; -template <bool, class, class> -struct __tuple_convertible_apply : public false_type {}; +struct __tuple_sfinae_base { + template <class ..._FromArgs, class ..._ToArgs> + static auto __test_constructible(__tuple_types<_FromArgs...>, __tuple_types<_ToArgs...>) + -> __all<is_constructible<_ToArgs, _FromArgs>::value...>; + static auto __test_constructible(...) -> false_type; + template <class _Types1, class _Types2> + using __constructible = decltype(__test_constructible(_Types1{}, _Types2{})); + + template <class ..._FromArgs, class ..._ToArgs> + static auto __test_convertible(__tuple_types<_FromArgs...>, __tuple_types<_ToArgs...>) + -> __all<is_convertible<_FromArgs, _ToArgs>::value...>; + static auto __test_convertible(...) -> false_type; + template <class _Types1, class _Types2> + using __convertible = decltype(__test_convertible(_Types1{}, _Types2{})); + + template <class ..._FromArgs, class ..._ToArgs> + static auto __test_assignable(__tuple_types<_FromArgs...>, __tuple_types<_ToArgs...>) + -> __all<is_assignable<_ToArgs&, _FromArgs>::value...>; + static auto __test_assignable(...) -> false_type; + template <class _Types1, class _Types2> + using __assignable = decltype(__test_assignable(_Types1{}, _Types2{})); +}; -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 - > -{}; +// __tuple_convertible template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> @@ -397,36 +402,14 @@ struct __tuple_convertible template <class _Tp, class _Up> struct __tuple_convertible<_Tp, _Up, true, true> - : public __tuple_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> -{}; - -// __tuple_constructible - -template <class, class> -struct __tuple_constructible_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._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<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; - -template <> -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< + : public __tuple_sfinae_base::__convertible< typename __make_tuple_types<_Tp>::type , typename __make_tuple_types<_Up>::type > {}; +// __tuple_constructible + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_constructible @@ -434,36 +417,14 @@ struct __tuple_constructible template <class _Tp, class _Up> struct __tuple_constructible<_Tp, _Up, true, true> - : public __tuple_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> -{}; - -// __tuple_assignable - -template <class, class> -struct __tuple_assignable_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._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<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; - -template <> -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< + : public __tuple_sfinae_base::__constructible< typename __make_tuple_types<_Tp>::type , typename __make_tuple_types<_Up>::type > {}; +// __tuple_assignable + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_assignable @@ -471,8 +432,10 @@ struct __tuple_assignable template <class _Tp, class _Up> struct __tuple_assignable<_Tp, _Up, true, true> - : public __tuple_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> + : public __tuple_sfinae_base::__assignable< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up>::type + > {}; #endif // _LIBCPP_HAS_NO_VARIADICS Modified: libcxx/trunk/include/tuple URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=274331&r1=274330&r2=274331&view=diff ============================================================================== --- libcxx/trunk/include/tuple (original) +++ libcxx/trunk/include/tuple Thu Jun 30 23:07:39 2016 @@ -379,11 +379,6 @@ template <class ..._Tp> _LIBCPP_INLINE_VISIBILITY void __swallow(_Tp&&...) _NOEXCEPT {} -template <bool ..._Pred> -struct __all - : is_same<__all<_Pred...>, __all<(_Pred, true)...>> -{ }; - template <class ..._Tp> struct __lazy_all : __all<_Tp::value...> {}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits