re PR libstdc++/66338 (std::forward_as_tuple() issue with single argument)
authorVille Voutilainen <ville.voutilainen@gmail.com>
Fri, 27 May 2016 14:08:37 +0000 (17:08 +0300)
committerVille Voutilainen <ville@gcc.gnu.org>
Fri, 27 May 2016 14:08:37 +0000 (17:08 +0300)
2016-05-24  Ville Voutilainen  <ville.voutilainen@gmail.com>

PR libstdc++/66338
* include/std/tuple (_TMC): Add a check for _NotSameTuple.
* include/std/tuple (tuple(_UElements&&...)): Remove the separate
check for _NotSameTuple.
* include/std/tuple (_TMCT): New.
* include/std/tuple (tuple(const tuple<_UElements...>&)): Use it.
* include/std/tuple (tuple(tuple<_UElements...>&&)): Likewise.
* include/std/tuple (tuple(allocator_arg_t, const _Alloc&,
      const tuple<_UElements...>&)): Likewise.
* include/std/tuple (tuple(allocator_arg_t, const _Alloc&,
      tuple<_UElements...>&&)): Likewise.
* testsuite/20_util/tuple/cons/66338.cc: New.

From-SVN: r236822

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/tuple
libstdc++-v3/testsuite/20_util/tuple/cons/66338.cc [new file with mode: 0644]

index e75d551a800c7e7a36cd597525f5653b57c737ee..16bc239d7d6384fa925fb3ac85db202b1ad576d8 100644 (file)
@@ -1,3 +1,18 @@
+2016-05-27  Ville Voutilainen  <ville.voutilainen@gmail.com>
+
+       PR libstdc++/66338
+       * include/std/tuple (_TMC): Add a check for _NotSameTuple.
+       * include/std/tuple (tuple(_UElements&&...)): Remove the separate
+       check for _NotSameTuple.
+       * include/std/tuple (_TMCT): New.
+       * include/std/tuple (tuple(const tuple<_UElements...>&)): Use it.
+       * include/std/tuple (tuple(tuple<_UElements...>&&)): Likewise.
+       * include/std/tuple (tuple(allocator_arg_t, const _Alloc&,
+             const tuple<_UElements...>&)): Likewise.
+       * include/std/tuple (tuple(allocator_arg_t, const _Alloc&,
+             tuple<_UElements...>&&)): Likewise.
+       * testsuite/20_util/tuple/cons/66338.cc: New.
+
 2016-05-25  Jonathan Wakely  <jwakely@redhat.com>
 
        * acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Fix test for sendfile.
index 7522e435184564c8765f12510f9668e0b4d55ee8..5ef3003b70649e2294fe5fff2eecb8fcb9d2b154 100644 (file)
@@ -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 (file)
index 0000000..f57eae9
--- /dev/null
@@ -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;
+}