[libcxx] r290624 - Fix PR31481 - 3+ parameter common_type isn't SFINAE friendly

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 27 11:59:50 PST 2016


Author: ericwf
Date: Tue Dec 27 13:59:50 2016
New Revision: 290624

URL: http://llvm.org/viewvc/llvm-project?rev=290624&view=rev
Log:
Fix PR31481 - 3+ parameter common_type isn't SFINAE friendly

Modified:
    libcxx/trunk/include/type_traits
    libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp

Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=290624&r1=290623&r2=290624&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Tue Dec 27 13:59:50 2016
@@ -2020,13 +2020,21 @@ template <class ...Tp> struct __common_t
 template <class, class = void>
 struct __common_type_impl {};
 
+template <class _Tp, class _Up>
+struct __common_type_impl<
+    __common_types<_Tp, _Up>,
+    typename __void_t<typename common_type<_Tp, _Up>::type>::type>
+{
+  typedef typename common_type<_Tp, _Up>::type type;
+};
+
 template <class _Tp, class _Up, class ..._Vp>
 struct __common_type_impl<__common_types<_Tp, _Up, _Vp...>,
     typename __void_t<typename common_type<_Tp, _Up>::type>::type>
+  : __common_type_impl<
+      __common_types<typename common_type<_Tp, _Up>::type, _Vp...> >
 {
-    typedef typename common_type<
-        typename common_type<_Tp, _Up>::type, _Vp...
-    >::type type;
+
 };
 
 template <class _Tp, class _Up, class ..._Vp>

Modified: libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp?rev=290624&r1=290623&r2=290624&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp Tue Dec 27 13:59:50 2016
@@ -33,12 +33,21 @@ namespace std
 }
 
 #if TEST_STD_VER >= 11
-template <class T, class U, class = void>
-struct no_common_type : std::true_type {};
+template <class Tp>
+struct always_bool_imp { using type = bool; };
+template <class Tp> using always_bool = typename always_bool_imp<Tp>::type;
+
+template <class ...Args>
+constexpr auto no_common_type_imp(int)
+  -> always_bool<typename std::common_type<Args...>::type>
+  { return false; }
+
+template <class ...Args>
+constexpr bool no_common_type_imp(long) { return true; }
+
+template <class ...Args>
+using no_common_type = std::integral_constant<bool, no_common_type_imp<Args...>(0)>;
 
-template <class T, class U>
-struct no_common_type<T, U, typename std::conditional<false,
-    typename std::common_type<T, U>::type, void>::type> : std::false_type {};
 #endif // TEST_STD_VER >= 11
 
 int main()
@@ -93,6 +102,9 @@ int main()
     static_assert((no_common_type<void, int>::value), "");
     static_assert((no_common_type<int, void>::value), "");
     static_assert((no_common_type<int, E>::value), "");
+    static_assert((no_common_type<int, int, E>::value), "");
+    static_assert((no_common_type<int, int, E, int>::value), "");
+    static_assert((no_common_type<int, int, int, E>::value), "");
     static_assert((no_common_type<int, X<int> >::value), "");
 #endif // TEST_STD_VER >= 11
 




More information about the cfe-commits mailing list