diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2010-08-10 07:17:44 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2010-08-10 07:17:44 +0000 |
commit | 0a5c2065bd4c06217c2035e1103d2f73a124285e (patch) | |
tree | 4c8b8b103522c21ec6cef88db1439e6b3262be27 /libstdc++-v3 | |
parent | ff61e417cf1adde9a9f4e6a66c8bc708bdef7e6f (diff) | |
download | gcc-0a5c2065bd4c06217c2035e1103d2f73a124285e.zip gcc-0a5c2065bd4c06217c2035e1103d2f73a124285e.tar.gz gcc-0a5c2065bd4c06217c2035e1103d2f73a124285e.tar.bz2 |
re PR libstdc++/45228 ([C++0x] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue)
2010-08-10 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/45228
* include/std/tuple (tuple<typename... _Elements>): Constrain
converting constructors and assignment operators with
sizeof...(_UElements) == sizeof...(_Elements).
(tuple(tuple<_UElements...>&): Remove.
(tuple<typename _T1>): Add.
* testsuite/20_util/tuple/cons/45228.cc: New.
* testsuite/20_util/tuple/cons/converting.cc: Likewise.
* testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust
dg-error line number.
* include/std/tuple (_Tuple_impl<>::_Tuple_impl(const _Tuple_impl&)):
Defaulted.
* include/std/tuple (tuple<typename _T1, typename _T2>
::operator=(pair<_U1, _U2>&&)): Use forward.
From-SVN: r163049
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 19 | ||||
-rw-r--r-- | libstdc++-v3/include/std/tuple | 108 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/tuple/cons/45228.cc | 43 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/tuple/cons/converting.cc | 37 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc | 2 |
5 files changed, 189 insertions, 20 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 11b6637..6015568 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2010-08-10 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/45228 + * include/std/tuple (tuple<typename... _Elements>): Constrain + converting constructors and assignment operators with + sizeof...(_UElements) == sizeof...(_Elements). + (tuple(tuple<_UElements...>&): Remove. + (tuple<typename _T1>): Add. + * testsuite/20_util/tuple/cons/45228.cc: New. + * testsuite/20_util/tuple/cons/converting.cc: Likewise. + * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust + dg-error line number. + + * include/std/tuple (_Tuple_impl<>::_Tuple_impl(const _Tuple_impl&)): + Defaulted. + + * include/std/tuple (tuple<typename _T1, typename _T2> + ::operator=(pair<_U1, _U2>&&)): Use forward. + 2010-08-08 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/44963 diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 2e35241..67a6eb7 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -160,8 +160,7 @@ namespace std : _Inherited(std::forward<_UTail>(__tail)...), _Base(std::forward<_UHead>(__head)) { } - _Tuple_impl(const _Tuple_impl& __in) - : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } + _Tuple_impl(const _Tuple_impl&) = default; _Tuple_impl(_Tuple_impl&& __in) : _Inherited(std::move(__in._M_tail())), @@ -233,7 +232,9 @@ namespace std tuple(const _Elements&... __elements) : _Inherited(__elements...) { } - template<typename... _UElements> + template<typename... _UElements, typename = typename + std::enable_if<sizeof...(_UElements) + == sizeof...(_Elements)>::type> explicit tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } @@ -243,20 +244,18 @@ namespace std tuple(tuple&& __in) : _Inherited(static_cast<_Inherited&&>(__in)) { } - template<typename... _UElements> + template<typename... _UElements, typename = typename + std::enable_if<sizeof...(_UElements) + == sizeof...(_Elements)>::type> tuple(const tuple<_UElements...>& __in) - : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) - { } + : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) + { } - template<typename... _UElements> + template<typename... _UElements, typename = typename + std::enable_if<sizeof...(_UElements) + == sizeof...(_Elements)>::type> tuple(tuple<_UElements...>&& __in) - : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } - - // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html - template<typename... _UElements> - tuple(tuple<_UElements...>& __in) - : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) - { } + : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } tuple& operator=(const tuple& __in) @@ -272,7 +271,9 @@ namespace std return *this; } - template<typename... _UElements> + template<typename... _UElements, typename = typename + std::enable_if<sizeof...(_UElements) + == sizeof...(_Elements)>::type> tuple& operator=(const tuple<_UElements...>& __in) { @@ -280,7 +281,9 @@ namespace std return *this; } - template<typename... _UElements> + template<typename... _UElements, typename = typename + std::enable_if<sizeof...(_UElements) + == sizeof...(_Elements)>::type> tuple& operator=(tuple<_UElements...>&& __in) { @@ -293,7 +296,6 @@ namespace std { _Inherited::_M_swap_impl(__in); } }; - template<> class tuple<> { @@ -385,8 +387,8 @@ namespace std tuple& operator=(pair<_U1, _U2>&& __in) { - this->_M_head() = std::move(__in.first); - this->_M_tail()._M_head() = std::move(__in.second); + this->_M_head() = std::forward<_U1>(__in.first); + this->_M_tail()._M_head() = std::forward<_U2>(__in.second); return *this; } @@ -399,6 +401,74 @@ namespace std } }; + /// tuple (1-element). + template<typename _T1> + class tuple<_T1> : public _Tuple_impl<0, _T1> + { + typedef _Tuple_impl<0, _T1> _Inherited; + + public: + tuple() + : _Inherited() { } + + explicit + tuple(const _T1& __a1) + : _Inherited(__a1) { } + + template<typename _U1, typename = typename + std::enable_if<std::is_convertible<_U1, _T1>::value>::type> + explicit + tuple(_U1&& __a1) + : _Inherited(std::forward<_U1>(__a1)) { } + + tuple(const tuple&) = default; + + tuple(tuple&& __in) + : _Inherited(static_cast<_Inherited&&>(__in)) { } + + template<typename _U1> + tuple(const tuple<_U1>& __in) + : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { } + + template<typename _U1> + tuple(tuple<_U1>&& __in) + : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { } + + tuple& + operator=(const tuple& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + tuple& + operator=(tuple&& __in) + { + static_cast<_Inherited&>(*this) = std::move(__in); + return *this; + } + + template<typename _U1> + tuple& + operator=(const tuple<_U1>& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + template<typename _U1> + tuple& + operator=(tuple<_U1>&& __in) + { + static_cast<_Inherited&>(*this) = std::move(__in); + return *this; + } + + void + swap(tuple& __in) + { _Inherited::_M_swap_impl(__in); } + }; + /// Gives the type of the ith element of a given tuple type. template<std::size_t __i, typename _Tp> diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/45228.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/45228.cc new file mode 100644 index 0000000..863d788 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/45228.cc @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2010 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> + +typedef std::tuple<int> Tuple_1; +typedef std::tuple<int, int> Tuple_2; +typedef std::tuple<int, int, int> Tuple_3; + + Tuple_1 A_1() { return Tuple_1(); } +const Tuple_1 B_1() { return Tuple_1(); } + + Tuple_2 A_2() { return Tuple_2(); } +const Tuple_2 B_2() { return Tuple_2(); } + + Tuple_3 A_3() { return Tuple_3(); } +const Tuple_3 B_3() { return Tuple_3(); } + +Tuple_1 test_A_1(A_1()); +Tuple_1 test_B_1(B_1()); + +Tuple_2 test_A_2(A_2()); +Tuple_2 test_B_2(B_2()); + +Tuple_3 test_A_3(A_3()); +Tuple_3 test_B_3(B_3()); diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/converting.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/converting.cc new file mode 100644 index 0000000..def1b52 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/converting.cc @@ -0,0 +1,37 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2010 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> + +// http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html +std::tuple<int> ts1; +std::tuple<unsigned> tu1(ts1); + +std::tuple<int, int> ts2; +std::tuple<unsigned, unsigned> tu2(ts2); + +std::tuple<int, int, int> ts3; +std::tuple<unsigned, unsigned, unsigned> tu3(ts3); + +std::tuple<int, unsigned> tm2; +std::tuple<unsigned, int> tm2_(tm2); + +std::tuple<int, unsigned, int> tm3; +std::tuple<unsigned, int, unsigned> tm3_(tm3); diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc index f8cf9cd..7942c05 100644 --- a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc @@ -44,7 +44,7 @@ main() // { dg-warning "note" "" { target *-*-* } 324 } // { dg-warning "note" "" { target *-*-* } 423 } // { dg-warning "note" "" { target *-*-* } 862 } -// { dg-warning "note" "" { target *-*-* } 510 } +// { dg-warning "note" "" { target *-*-* } 580 } // { dg-warning "note" "" { target *-*-* } 1027 } // { dg-warning "note" "" { target *-*-* } 340 } // { dg-warning "note" "" { target *-*-* } 290 } |