[libcxx-commits] [libcxx] r365074 - Fix tuple's conditionally explicit constructors for very weird user

Eric Fiselier via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 3 12:21:40 PDT 2019


Author: ericwf
Date: Wed Jul  3 12:21:40 2019
New Revision: 365074

URL: http://llvm.org/viewvc/llvm-project?rev=365074&view=rev
Log:
Fix tuple's conditionally explicit constructors for very weird user
types.

It seems some people like to write types that can explicitly convert
to anything, but cannot be used to explicitly construct anything.

This patch makes tuple tolerate such types, as is required
by the standard.

Modified:
    libcxx/trunk/include/tuple
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp

Modified: libcxx/trunk/include/tuple
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=365074&r1=365073&r2=365074&view=diff
==============================================================================
--- libcxx/trunk/include/tuple (original)
+++ libcxx/trunk/include/tuple Wed Jul  3 12:21:40 2019
@@ -521,6 +521,13 @@ class _LIBCPP_TEMPLATE_VIS tuple
         template <class ..._Args>
         static constexpr bool __enable_implicit() {
             return
+               __tuple_constructible<
+                    tuple<_Args...>,
+                    typename __make_tuple_types<tuple,
+                             sizeof...(_Args) < sizeof...(_Tp) ?
+                                 sizeof...(_Args) :
+                                 sizeof...(_Tp)>::type
+                >::value &&
                 __tuple_convertible<
                     tuple<_Args...>,
                     typename __make_tuple_types<tuple,
@@ -547,7 +554,8 @@ class _LIBCPP_TEMPLATE_VIS tuple
     {
         template <class _Tuple>
         static constexpr bool __enable_implicit() {
-            return __tuple_convertible<_Tuple, tuple>::value;
+            return __tuple_constructible<_Tuple, tuple>::value
+                && __tuple_convertible<_Tuple, tuple>::value;
         }
 
         template <class _Tuple>
@@ -577,6 +585,7 @@ class _LIBCPP_TEMPLATE_VIS tuple
         template <class _Tuple>
         static constexpr bool __enable_implicit() {
             return _And<
+                __tuple_constructible<_Tuple, tuple>,
                 __tuple_convertible<_Tuple, tuple>,
                 _PreferTupleLikeConstructor<_Tuple>
             >::value;

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp?rev=365074&r1=365073&r2=365074&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_move.pass.cpp Wed Jul  3 12:21:40 2019
@@ -46,6 +46,20 @@ struct D
     explicit D(int i) : B(i) {}
 };
 
+struct BonkersBananas {
+  template <class T>
+  operator T() &&;
+  template <class T, class = void>
+  explicit operator T() && = delete;
+};
+
+void test_bonkers_bananas_conversion() {
+  using ReturnType = std::tuple<int, int>;
+  static_assert(std::is_convertible<BonkersBananas, ReturnType>(), "");
+  static_assert(!std::is_constructible<ReturnType, BonkersBananas>(), "");
+
+}
+
 int main(int, char**)
 {
     {




More information about the libcxx-commits mailing list