[v3 PATCH] PR libstdc++/66338
Ville Voutilainen
ville.voutilainen@gmail.com
Tue May 24 17:18:00 GMT 2016
On 24 May 2016 at 17:59, 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.
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.
-------------- next part --------------
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 7522e43..4de36e5 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))
+ && (_TC<true, _Elements...>::
+ template _NotSameTuple<tuple<_UElements...>>()),
_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