[v3 PATCH] PR libstdc++/66338

Ville Voutilainen ville.voutilainen@gmail.com
Tue May 24 17:31:00 GMT 2016


On 24 May 2016 at 19:35, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
> Slight tweak. The avoidance of _NotSameTuple wasn't quite correct for
> the templates that
> take const tuple<_UElements...>& or  tuple<_UElements...>&& instead of
> const _UElements&...
> or _UElements&&...
>
> This patch introduces a new helper alias to cover those cases and
> takes it into use where appropriate.
> All tests pass, but I don't have any sane tests to verify this tweak.


..and I don't need to be quite so round-about in the new helper, it
can just check !is_same
instead of doing a nested _TC call. Changelog the same as in the previous one.
-------------- next part --------------
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 7522e43..ea88793 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -620,14 +620,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Shortcut for the cases where constructors taking _UElements...
       // need to be constrained.
       template<typename... _UElements> using _TMC =
-                  _TC<(sizeof...(_Elements) == sizeof...(_UElements)),
+                  _TC<(sizeof...(_Elements) == sizeof...(_UElements))
+		      && (_TC<(sizeof...(_UElements)==1), _Elements...>::
+			  template _NotSameTuple<_UElements...>()),
+                      _Elements...>;
+
+      // Shortcut for the cases where constructors taking tuple<_UElements...>
+      // need to be constrained.
+      template<typename... _UElements> using _TMCT =
+                  _TC<(sizeof...(_Elements) == sizeof...(_UElements))
+		      && !is_same<tuple<_Elements...>,
+				  tuple<_UElements...>>::value,
                       _Elements...>;
 
       template<typename... _UElements, typename
 	       enable_if<
-		  _TC<sizeof...(_UElements) == 1, _Elements...>::template
-		    _NotSameTuple<_UElements...>()
-		  && _TMC<_UElements...>::template
+		  _TMC<_UElements...>::template
                     _MoveConstructibleTuple<_UElements...>()
                   && _TMC<_UElements...>::template
                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
@@ -638,9 +646,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       template<typename... _UElements, typename
         enable_if<
-		  _TC<sizeof...(_UElements) == 1, _Elements...>::template
-		    _NotSameTuple<_UElements...>()
-		  && _TMC<_UElements...>::template
+		  _TMC<_UElements...>::template
                     _MoveConstructibleTuple<_UElements...>()
                   && !_TMC<_UElements...>::template
                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
@@ -660,9 +666,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
             _Elements...>;
 
       template<typename... _UElements, typename _Dummy = void, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<_TMCT<_UElements...>::template
                     _ConstructibleTuple<_UElements...>()
-                  && _TMC<_UElements...>::template
+                  && _TMCT<_UElements...>::template
                     _ImplicitlyConvertibleTuple<_UElements...>()
                   && _TNTC<_Dummy>::template
                     _NonNestedTuple<const tuple<_UElements...>&>(),
@@ -672,9 +678,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         { }
 
       template<typename... _UElements, typename _Dummy = void, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<_TMCT<_UElements...>::template
                     _ConstructibleTuple<_UElements...>()
-                  && !_TMC<_UElements...>::template
+                  && !_TMCT<_UElements...>::template
                     _ImplicitlyConvertibleTuple<_UElements...>()
                   && _TNTC<_Dummy>::template
                     _NonNestedTuple<const tuple<_UElements...>&>(),
@@ -684,9 +690,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         { }
 
       template<typename... _UElements, typename _Dummy = void, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<_TMCT<_UElements...>::template
                     _MoveConstructibleTuple<_UElements...>()
-                  && _TMC<_UElements...>::template
+                  && _TMCT<_UElements...>::template
                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
                   && _TNTC<_Dummy>::template
                     _NonNestedTuple<tuple<_UElements...>&&>(),
@@ -695,9 +701,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
 
       template<typename... _UElements, typename _Dummy = void, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<_TMCT<_UElements...>::template
                     _MoveConstructibleTuple<_UElements...>()
-                  && !_TMC<_UElements...>::template
+                  && !_TMCT<_UElements...>::template
                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
                   && _TNTC<_Dummy>::template
                     _NonNestedTuple<tuple<_UElements...>&&>(),
@@ -764,9 +770,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
 
       template<typename _Alloc, typename... _UElements, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<_TMCT<_UElements...>::template
                     _ConstructibleTuple<_UElements...>()
-                  && _TMC<_UElements...>::template
+                  && _TMCT<_UElements...>::template
                     _ImplicitlyConvertibleTuple<_UElements...>(),
         bool>::type=true>
 	tuple(allocator_arg_t __tag, const _Alloc& __a,
@@ -776,9 +782,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ }
 
       template<typename _Alloc, typename... _UElements, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<_TMCT<_UElements...>::template
                     _ConstructibleTuple<_UElements...>()
-                  && !_TMC<_UElements...>::template
+                  && !_TMCT<_UElements...>::template
                     _ImplicitlyConvertibleTuple<_UElements...>(),
         bool>::type=false>
 	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
@@ -788,9 +794,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ }
 
       template<typename _Alloc, typename... _UElements, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<_TMCT<_UElements...>::template
                     _MoveConstructibleTuple<_UElements...>()
-                  && _TMC<_UElements...>::template
+                  && _TMCT<_UElements...>::template
                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
         bool>::type=true>
 	tuple(allocator_arg_t __tag, const _Alloc& __a,
@@ -800,9 +806,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ }
 
       template<typename _Alloc, typename... _UElements, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<_TMCT<_UElements...>::template
                     _MoveConstructibleTuple<_UElements...>()
-                  && !_TMC<_UElements...>::template
+                  && !_TMCT<_UElements...>::template
                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
         bool>::type=false>
 	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/66338.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/66338.cc
new file mode 100644
index 0000000..f57eae9
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/66338.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <tuple>
+
+struct S {
+  int i_;
+
+  template<typename T>
+  S(T&& i)
+    noexcept(noexcept(i_ = i))
+  { i_ = i; }
+
+  S() noexcept : i_{0} {};
+};
+
+int main()
+{
+  std::tuple<S&&>(std::forward_as_tuple(S{}));
+  return 0;
+}


More information about the Gcc-patches mailing list