[libcxx] r266703 - Make tuples constructors conditionally EXPLICIT. See N4387

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 18 18:19:25 PDT 2016


Author: ericwf
Date: Mon Apr 18 20:19:25 2016
New Revision: 266703

URL: http://llvm.org/viewvc/llvm-project?rev=266703&view=rev
Log:
Make tuples constructors conditionally EXPLICIT. See N4387

Added:
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp
Modified:
    libcxx/trunk/include/tuple
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp
    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=266703&r1=266702&r2=266703&view=diff
==============================================================================
--- libcxx/trunk/include/tuple (original)
+++ libcxx/trunk/include/tuple Mon Apr 18 20:19:25 2016
@@ -449,7 +449,7 @@ struct __tuple_impl<__tuple_indices<_Ind
     template <class _Alloc, class _Tuple,
               class = typename enable_if
                       <
-                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
+                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
                       >::type
              >
         _LIBCPP_INLINE_VISIBILITY
@@ -673,8 +673,17 @@ public:
                     typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
                     __tuple_types<_Tp...>()) {}
 
+    template <bool _Dummy = true,
+              typename enable_if
+                      <
+                         _CheckArgsConstructor<
+                            _Dummy
+                         >::template __enable_implicit<_Tp...>(),
+                         bool
+                      >::type = false
+        >
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
+    tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
         : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
                 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
                 typename __make_tuple_indices<0>::type(),
@@ -682,8 +691,54 @@ public:
                 __t...
                ) {}
 
-    template <class _Alloc>
+    template <bool _Dummy = true,
+              typename enable_if
+                      <
+                         _CheckArgsConstructor<
+                            _Dummy
+                         >::template __enable_explicit<_Tp...>(),
+                         bool
+                      >::type = false
+        >
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
+        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
+                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
+                typename __make_tuple_indices<0>::type(),
+                typename __make_tuple_types<tuple, 0>::type(),
+                __t...
+               ) {}
+
+    template <class _Alloc, bool _Dummy = true,
+              typename enable_if
+                      <
+                         _CheckArgsConstructor<
+                            _Dummy
+                         >::template __enable_implicit<_Tp...>(),
+                         bool
+                      >::type = false
+        >
+      _LIBCPP_INLINE_VISIBILITY
+      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
+        : base_(allocator_arg_t(), __a,
+                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
+                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
+                typename __make_tuple_indices<0>::type(),
+                typename __make_tuple_types<tuple, 0>::type(),
+                __t...
+               ) {}
+
+    template <class _Alloc, bool _Dummy = true,
+              typename enable_if
+                      <
+                         _CheckArgsConstructor<
+                            _Dummy
+                         >::template __enable_explicit<_Tp...>(),
+                         bool
+                      >::type = false
+        >
       _LIBCPP_INLINE_VISIBILITY
+      explicit
       tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
         : base_(allocator_arg_t(), __a,
                 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
@@ -749,15 +804,36 @@ public:
                     _VSTD::forward<_Up>(__u)...) {}
 
     template <class _Alloc, class ..._Up,
-              class = typename enable_if
+              typename enable_if
                       <
                          _CheckArgsConstructor<
                              sizeof...(_Up) == sizeof...(_Tp) &&
                              !_PackExpandsToThisTuple<_Up...>::value
-                         >::template __enable_implicit<_Up...>()
-                      >::type
+                         >::template __enable_implicit<_Up...>(),
+                         bool
+                      >::type = false
+             >
+        _LIBCPP_INLINE_VISIBILITY
+        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
+            : base_(allocator_arg_t(), __a,
+                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
+                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
+                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
+                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
+                    _VSTD::forward<_Up>(__u)...) {}
+
+    template <class _Alloc, class ..._Up,
+              typename enable_if
+                      <
+                         _CheckArgsConstructor<
+                             sizeof...(_Up) == sizeof...(_Tp) &&
+                             !_PackExpandsToThisTuple<_Up...>::value
+                         >::template __enable_explicit<_Up...>(),
+                         bool
+                      >::type = false
              >
         _LIBCPP_INLINE_VISIBILITY
+        explicit
         tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
             : base_(allocator_arg_t(), __a,
                     typename __make_tuple_indices<sizeof...(_Up)>::type(),
@@ -796,17 +872,32 @@ public:
             : base_(_VSTD::forward<_Tuple>(__t)) {}
 
     template <class _Alloc, class _Tuple,
-              class = typename enable_if
+              typename enable_if
                       <
                          _CheckTupleLikeConstructor<
                              __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
-                         >::template __enable_implicit<_Tuple>()
-                      >::type
+                         >::template __enable_implicit<_Tuple>(),
+                         bool
+                      >::type = false
              >
         _LIBCPP_INLINE_VISIBILITY
         tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
             : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
 
+    template <class _Alloc, class _Tuple,
+              typename enable_if
+                      <
+                         _CheckTupleLikeConstructor<
+                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
+                         >::template __enable_explicit<_Tuple>(),
+                         bool
+                      >::type = false
+             >
+        _LIBCPP_INLINE_VISIBILITY
+        explicit
+        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
+            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
+
     template <class _Tuple,
               class = typename enable_if
                       <

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp?rev=266703&r1=266702&r2=266703&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp Mon Apr 18 20:19:25 2016
@@ -73,9 +73,18 @@ void test_uses_allocator_sfinae_evaluati
     }
 }
 
+struct Explicit {
+  int value;
+  explicit Explicit(int x) : value(x) {}
+};
+
 int main()
 {
     {
+        std::tuple<Explicit> t{std::allocator_arg, std::allocator<void>{}, 42};
+        assert(std::get<0>(t).value == 42);
+    }
+    {
         std::tuple<MoveOnly> t(std::allocator_arg, A1<int>(), MoveOnly(0));
         assert(std::get<0>(t) == 0);
     }

Added: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp?rev=266703&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp (added)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.fail.cpp Mon Apr 18 20:19:25 2016
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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 Alloc>
+//   EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <tuple>
+#include <memory>
+#include <cassert>
+
+struct ExplicitCopy {
+  explicit ExplicitCopy(ExplicitCopy const&) {}
+  explicit ExplicitCopy(int) {}
+};
+
+std::tuple<ExplicitCopy> const_explicit_copy_test() {
+    const ExplicitCopy e(42);
+    return {std::allocator_arg, std::allocator<void>{}, e};
+    // expected-error at -1 {{chosen constructor is explicit in copy-initialization}}
+}
+
+std::tuple<ExplicitCopy> non_const_explicity_copy_test() {
+    ExplicitCopy e(42);
+    return {std::allocator_arg, std::allocator<void>{}, e};
+    // expected-error at -1 {{chosen constructor is explicit in copy-initialization}}
+}
+int main()
+{
+    const_explicit_copy_test();
+    non_const_explicity_copy_test();
+}

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp?rev=266703&r1=266702&r2=266703&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_const_Types.pass.cpp Mon Apr 18 20:19:25 2016
@@ -17,15 +17,37 @@
 // UNSUPPORTED: c++98, c++03
 
 #include <tuple>
+#include <memory>
 #include <cassert>
 
 #include "allocators.h"
 #include "../alloc_first.h"
 #include "../alloc_last.h"
 
+struct ImplicitCopy {
+  explicit ImplicitCopy(int) {}
+  ImplicitCopy(ImplicitCopy const&) {}
+};
+
+// Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit
+// copy conversions in return value expressions.
+std::tuple<ImplicitCopy> testImplicitCopy1() {
+    ImplicitCopy i(42);
+    return {std::allocator_arg, std::allocator<void>{}, i};
+}
+
+std::tuple<ImplicitCopy> testImplicitCopy2() {
+    const ImplicitCopy i(42);
+    return {std::allocator_arg, std::allocator<void>{}, i};
+}
+
 int main()
 {
     {
+        // check that the literal '0' can implicitly initialize a stored pointer.
+        std::tuple<int*> t = {std::allocator_arg, std::allocator<void>{}, 0};
+    }
+    {
         std::tuple<int> t(std::allocator_arg, A1<int>(), 3);
         assert(std::get<0>(t) == 3);
     }

Added: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp?rev=266703&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp (added)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.fail.cpp Mon Apr 18 20:19:25 2016
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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 Alloc, class ...UTypes>
+//   tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...> const&);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <tuple>
+#include <memory>
+
+struct ExplicitCopy {
+  explicit ExplicitCopy(int) {}
+  explicit ExplicitCopy(ExplicitCopy const&) {}
+
+};
+
+std::tuple<ExplicitCopy> const_explicit_copy_test() {
+    const std::tuple<int> t1(42);
+    return {std::allocator_arg, std::allocator<void>{}, t1};
+    // expected-error at -1 {{chosen constructor is explicit in copy-initialization}}
+}
+
+std::tuple<ExplicitCopy> non_const_explicit_copy_test() {
+    std::tuple<int> t1(42);
+    return {std::allocator_arg, std::allocator<void>{}, t1};
+    // expected-error at -1 {{chosen constructor is explicit in copy-initialization}}
+}
+
+int main()
+{
+
+}

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp?rev=266703&r1=266702&r2=266703&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_copy.pass.cpp Mon Apr 18 20:19:25 2016
@@ -17,12 +17,23 @@
 // UNSUPPORTED: c++98, c++03
 
 #include <tuple>
+#include <memory>
 #include <cassert>
 
 #include "allocators.h"
 #include "../alloc_first.h"
 #include "../alloc_last.h"
 
+struct Explicit {
+  int value;
+  explicit Explicit(int x) : value(x) {}
+};
+
+struct Implicit {
+  int value;
+  Implicit(int x) : value(x) {}
+};
+
 int main()
 {
     {
@@ -66,4 +77,14 @@ int main()
         assert(std::get<1>(t1) == 2);
         assert(std::get<2>(t1) == 3);
     }
+    {
+        const std::tuple<int> t1(42);
+        std::tuple<Explicit> t2{std::allocator_arg, std::allocator<void>{},  t1};
+        assert(std::get<0>(t2).value == 42);
+    }
+    {
+        const std::tuple<int> t1(42);
+        std::tuple<Implicit> t2 = {std::allocator_arg, std::allocator<void>{}, t1};
+        assert(std::get<0>(t2).value == 42);
+    }
 }

Added: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp?rev=266703&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp (added)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.fail.cpp Mon Apr 18 20:19:25 2016
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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 Alloc, class ...UTypes>
+//   tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
+
+// UNSUPPORTED: c++98, c++03
+
+#include <tuple>
+#include <memory>
+
+struct ExplicitCopy {
+  explicit ExplicitCopy(int) {}
+  explicit ExplicitCopy(ExplicitCopy const&) {}
+};
+
+std::tuple<ExplicitCopy> explicit_move_test() {
+    std::tuple<int> t1(42);
+    return {std::allocator_arg, std::allocator<void>{}, std::move(t1)};
+    // expected-error at -1 {{chosen constructor is explicit in copy-initialization}}
+}
+
+int main()
+{
+
+}

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp?rev=266703&r1=266702&r2=266703&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_convert_move.pass.cpp Mon Apr 18 20:19:25 2016
@@ -40,6 +40,16 @@ struct D
     explicit D(int i) : B(i) {}
 };
 
+struct Explicit {
+  int value;
+  explicit Explicit(int x) : value(x) {}
+};
+
+struct Implicit {
+  int value;
+  Implicit(int x) : value(x) {}
+};
+
 int main()
 {
     {
@@ -81,4 +91,14 @@ int main()
         assert(std::get<1>(t1) == 2);
         assert(std::get<2>(t1)->id_ == 3);
     }
+    {
+        std::tuple<int> t1(42);
+        std::tuple<Explicit> t2{std::allocator_arg, std::allocator<void>{}, std::move(t1)};
+        assert(std::get<0>(t2).value == 42);
+    }
+    {
+        std::tuple<int> t1(42);
+        std::tuple<Implicit> t2 = {std::allocator_arg, std::allocator<void>{}, std::move(t1)};
+        assert(std::get<0>(t2).value == 42);
+    }
 }

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp?rev=266703&r1=266702&r2=266703&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.fail.cpp Mon Apr 18 20:19:25 2016
@@ -19,9 +19,30 @@
 #include <string>
 #include <cassert>
 
+struct ExplicitCopy {
+  ExplicitCopy(int) {}
+  explicit ExplicitCopy(ExplicitCopy const&) {}
+};
+
+std::tuple<ExplicitCopy> const_explicit_copy() {
+    const ExplicitCopy e(42);
+    return {e};
+    // expected-error at -1 {{chosen constructor is explicit in copy-initialization}}
+}
+
+
+std::tuple<ExplicitCopy> non_const_explicit_copy() {
+    ExplicitCopy e(42);
+    return {e};
+    // expected-error at -1 {{chosen constructor is explicit in copy-initialization}}
+}
+
+std::tuple<ExplicitCopy> const_explicit_copy_no_brace() {
+    const ExplicitCopy e(42);
+    return e;
+    // expected-error at -1 {{no viable conversion}}
+}
+
 int main()
 {
-    {
-        std::tuple<int*> t = 0;
-    }
 }

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp?rev=266703&r1=266702&r2=266703&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/const_Types.pass.cpp Mon Apr 18 20:19:25 2016
@@ -53,9 +53,36 @@ struct NoValueCtorEmpty
     { static_assert(never<T>::value, "This should not be instantiated"); }
 };
 
+
+struct ImplicitCopy {
+  explicit ImplicitCopy(int) {}
+  ImplicitCopy(ImplicitCopy const&) {}
+};
+
+// Test that tuple(std::allocator_arg, Alloc, Types const&...) allows implicit
+// copy conversions in return value expressions.
+std::tuple<ImplicitCopy> testImplicitCopy1() {
+    ImplicitCopy i(42);
+    return {i};
+}
+
+std::tuple<ImplicitCopy> testImplicitCopy2() {
+    const ImplicitCopy i(42);
+    return {i};
+}
+
+std::tuple<ImplicitCopy> testImplicitCopy3() {
+    const ImplicitCopy i(42);
+    return i;
+}
+
 int main()
 {
     {
+        // check that the literal '0' can implicitly initialize a stored pointer.
+        std::tuple<int*> t = 0;
+    }
+    {
         std::tuple<int> t(2);
         assert(std::get<0>(t) == 2);
     }

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp?rev=266703&r1=266702&r2=266703&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp Mon Apr 18 20:19:25 2016
@@ -20,6 +20,16 @@
 #include <string>
 #include <cassert>
 
+struct Explicit {
+  int value;
+  explicit Explicit(int x) : value(x) {}
+};
+
+struct Implicit {
+  int value;
+  Implicit(int x) : value(x) {}
+};
+
 struct B
 {
     int id_;
@@ -115,4 +125,14 @@ int main()
         assert(std::get<1>(t1) == int('a'));
         assert(std::get<2>(t1).id_ == 3);
     }
+    {
+        const std::tuple<int> t1(42);
+        std::tuple<Explicit> t2(t1);
+        assert(std::get<0>(t2).value == 42);
+    }
+    {
+        const std::tuple<int> t1(42);
+        std::tuple<Implicit> t2 = t1;
+        assert(std::get<0>(t2).value == 42);
+    }
 }

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=266703&r1=266702&r2=266703&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 Mon Apr 18 20:19:25 2016
@@ -20,6 +20,16 @@
 #include <memory>
 #include <cassert>
 
+struct Explicit {
+  int value;
+  explicit Explicit(int x) : value(x) {}
+};
+
+struct Implicit {
+  int value;
+  Implicit(int x) : value(x) {}
+};
+
 struct B
 {
     int id_;
@@ -81,4 +91,14 @@ int main()
         assert(std::get<1>(t1) == int('a'));
         assert(std::get<2>(t1)->id_ == 3);
     }
+    {
+        std::tuple<int> t1(42);
+        std::tuple<Explicit> t2(std::move(t1));
+        assert(std::get<0>(t2).value == 42);
+    }
+    {
+        std::tuple<int> t1(42);
+        std::tuple<Implicit> t2 = std::move(t1);
+        assert(std::get<0>(t2).value == 42);
+    }
 }




More information about the cfe-commits mailing list