diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2016-05-09 14:03:36 +0300 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2016-05-09 14:03:36 +0300 |
commit | fb334765e2ab959fcf3630e3c4a31ba1cc01a0f2 (patch) | |
tree | 9e1995589052979ed36437c6c15615ab0ee511d2 | |
parent | fc48633e86abf4dacc6ee7281a3be14d97328980 (diff) | |
download | gcc-fb334765e2ab959fcf3630e3c4a31ba1cc01a0f2.zip gcc-fb334765e2ab959fcf3630e3c4a31ba1cc01a0f2.tar.gz gcc-fb334765e2ab959fcf3630e3c4a31ba1cc01a0f2.tar.bz2 |
Avoid endless run-time recursion for copying single-element tuples where the...
Avoid endless run-time recursion for copying single-element
tuples where the element type is by-value constructible
from any type.
* include/std/tuple (_NotSameTuple): New.
* include/std/tuple (tuple(_UElements&&...): Use it.
* testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc: New.
From-SVN: r236025
-rw-r--r-- | libstdc++-v3/ChangeLog | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/std/tuple | 23 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc | 30 |
3 files changed, 60 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index cda02f4..6f4ae5f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2016-05-09 Ville Voutilainen <ville.voutilainen@gmail.com> + + Avoid endless run-time recursion for copying single-element + tuples where the element type is by-value constructible + from any type. + * include/std/tuple (_NotSameTuple): New. + * include/std/tuple (tuple(_UElements&&...): Use it. + * testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc: New. + 2016-05-09 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/71004 diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 53f3184..7522e43 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -500,6 +500,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __not_<is_constructible<_Elements..., _SrcTuple>> >::value; } + template<typename... _UElements> + static constexpr bool _NotSameTuple() + { + return __not_<is_same<tuple<_Elements...>, + typename remove_const< + typename remove_reference<_UElements...>::type + >::type>>::value; + } }; template<typename... _Elements> @@ -534,6 +542,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return true; } + template<typename... _UElements> + static constexpr bool _NotSameTuple() + { + return true; + } }; /// Primary class template, tuple @@ -611,7 +624,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Elements...>; template<typename... _UElements, typename - enable_if<_TMC<_UElements...>::template + enable_if< + _TC<sizeof...(_UElements) == 1, _Elements...>::template + _NotSameTuple<_UElements...>() + && _TMC<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() @@ -621,7 +637,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _Inherited(std::forward<_UElements>(__elements)...) { } template<typename... _UElements, typename - enable_if<_TMC<_UElements...>::template + enable_if< + _TC<sizeof...(_UElements) == 1, _Elements...>::template + _NotSameTuple<_UElements...>() + && _TMC<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && !_TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc new file mode 100644 index 0000000..fe9bea6 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc @@ -0,0 +1,30 @@ +// 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> +using namespace std; + +struct Something { + Something() { } + template <typename T> Something(T) { } +}; + +int main() { + tuple<Something> t1; + tuple<Something> t2 = t1; +} + |