[libcxx-commits] [PATCH] D61293: Fix make_from_tuple when given a tuple containing rvalues

Zoe Carver via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Apr 29 19:57:32 PDT 2019


zoecarver created this revision.
zoecarver added reviewers: EricWF, mclow.lists.
Herald added subscribers: libcxx-commits, ldionne.

This patch attempts to fix 41643 <https://bugs.llvm.org/show_bug.cgi?id=41643> by providing two `__make_from_tuple_impl` overloads. I am not sure if this is the best way to implement this (and I especially don't love `__is_rvalue_tuple`) so I am waiting to update `tuple_cat` (and possibly others) until this patch gets a green-light.


Repository:
  rCXX libc++

https://reviews.llvm.org/D61293

Files:
  include/tuple
  test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp


Index: test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
===================================================================
--- test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
+++ test/std/utilities/tuple/tuple.tuple/tuple.apply/make_from_tuple.pass.cpp
@@ -156,6 +156,13 @@
         assert((do_forwarding_test<int&&, int&&, int&&>(std::move(tup))));
         assert((do_forwarding_test<int const&&, int const&&, int const&&>(std::move(ctup))));
     }
+    // test with pair<T&&, T&&>
+    {
+        using Tup = std::tuple<int&&, int&&>;
+        int x = 42;
+        Tup tup(std::move(x), std::move(x));
+        assert((do_forwarding_test<int&&, int&&>(tup)));
+    }
 }
 
 void test_noexcept() {
@@ -211,5 +218,5 @@
     test_perfect_forwarding();
     test_noexcept();
 
-  return 0;
+    return 0;
 }
Index: include/tuple
===================================================================
--- include/tuple
+++ include/tuple
@@ -1370,9 +1370,33 @@
         typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
 )
 
+template<class>
+struct __is_rvalue_tuple : false_type { };
+
+template<class..._Ts>
+struct __is_rvalue_tuple<tuple<_Ts&&...>> : true_type { };
+
+template<class..._Ts>
+struct __is_rvalue_tuple<tuple<_Ts&&...> &> : true_type { };
+
+template<class..._Ts>
+struct __is_rvalue_tuple<const tuple<_Ts&&...>> : true_type { };
+
+template<class..._Ts>
+struct __is_rvalue_tuple<const tuple<_Ts&&...> &> : true_type { };
+
 template <class _Tp, class _Tuple, size_t... _Idx>
-inline _LIBCPP_INLINE_VISIBILITY
-constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
+inline _LIBCPP_INLINE_VISIBILITY constexpr
+typename enable_if<__is_rvalue_tuple<_Tuple>::value, _Tp>::type
+__make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
+_LIBCPP_NOEXCEPT_RETURN(
+    _Tp(_VSTD::move(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t)))...)
+)
+
+template <class _Tp, class _Tuple, size_t... _Idx>
+inline _LIBCPP_INLINE_VISIBILITY constexpr
+typename enable_if<!__is_rvalue_tuple<_Tuple>::value, _Tp>::type
+__make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
 _LIBCPP_NOEXCEPT_RETURN(
     _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
 )
@@ -1381,7 +1405,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 constexpr _Tp make_from_tuple(_Tuple&& __t)
 _LIBCPP_NOEXCEPT_RETURN(
-    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
+    __make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
         typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
 )
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61293.197249.patch
Type: text/x-patch
Size: 2628 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20190430/6a65539f/attachment.bin>


More information about the libcxx-commits mailing list