Tested on Linux-PPC64. 2016-05-08 Ville Voutilainen <ville.voutilai...@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 (_TC<>::_NotSameTuple): New. * include/std/tuple (tuple(_UElements&&...): Use it. * testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc: New.
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; +} +