[libcxx] r274331 - Flatten tuple_constructible, tuple_convertible and tuple_assignable.

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 30 21:07:39 PDT 2016


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...> {};
 




More information about the cfe-commits mailing list