From b5b5e640fc4879308ab32927285677f2faabf2fb Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Mon, 18 Feb 2008 13:32:01 +0000 Subject: [PATCH] [multiple changes] 2008-02-18 Pedro Lamarao * include/std/tuple: Fixes for moveable, non-copyable types. * testsuite/20_util/tuple/moveable2.cc: New. 2008-02-18 Paolo Carlini * include/std/tuple (operator+(tuple<>&&, tuple<>&&): Remove. From-SVN: r132389 --- libstdc++-v3/ChangeLog | 9 ++ libstdc++-v3/include/std/tuple | 89 +++++++++---------- .../testsuite/20_util/tuple/moveable2.cc | 73 +++++++++++++++ 3 files changed, 124 insertions(+), 47 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/tuple/moveable2.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0c54e803f61..68ca46a0397 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2008-02-18 Pedro Lamarao + + * include/std/tuple: Fixes for moveable, non-copyable types. + * testsuite/20_util/tuple/moveable2.cc: New. + +2008-02-18 Paolo Carlini + + * include/std/tuple (operator+(tuple<>&&, tuple<>&&): Remove. + 2008-02-17 Ed Smith-Rowland <3dw4rd@verizon.net> * include/tr1/poly_laguerre.tcc: Doxygen fixes. diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index d64c141878d..b870234c129 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -72,11 +72,12 @@ namespace std _Head_base() : _Head() { } - _Head_base(typename __add_c_ref<_Head>::type __h) + _Head_base(const _Head& __h) : _Head(__h) { } - _Head_base(typename std::remove_reference<_Head>::type&& __h) - : _Head(std::forward<_Head>(__h)) { } + template + _Head_base(_UHead&& __h) + : _Head(std::forward<_UHead>(__h)) { } _Head& _M_head() { return *this; } const _Head& _M_head() const { return *this; } @@ -88,11 +89,12 @@ namespace std _Head_base() : _M_head_impl() { } - _Head_base(typename __add_c_ref<_Head>::type __h) + _Head_base(const _Head& __h) : _M_head_impl(__h) { } - _Head_base(typename std::remove_reference<_Head>::type&& __h) - : _M_head_impl(std::move(__h)) { } + template + _Head_base(_UHead&& __h) + : _M_head_impl(std::forward<_UHead>(__h)) { } _Head& _M_head() { return _M_head_impl; } const _Head& _M_head() const { return _M_head_impl; } @@ -141,23 +143,21 @@ namespace std : _Inherited(), _Base() { } explicit - _Tuple_impl(typename __add_c_ref<_Head>::type __head, - typename __add_c_ref<_Tail>::type... __tail) + _Tuple_impl(const _Head& __head, const _Tail&... __tail) : _Inherited(__tail...), _Base(__head) { } template explicit - _Tuple_impl(typename std::remove_reference<_UHead>::type&& __head, - typename std::remove_reference<_UTail>::type&&... __tail) - : _Inherited(std::forward<_Inherited>(__tail)...), - _Base(std::forward<_Base>(__head)) { } + _Tuple_impl(_UHead&& __head, _UTail&&... __tail) + : _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(_Tuple_impl&& __in) - : _Inherited(std::forward<_Inherited>(__in._M_tail())), - _Base(std::forward<_Base>(__in._M_head())) { } + : _Inherited(std::move<_Inherited&&>(__in._M_tail())), + _Base(std::forward<_Head>(__in._M_head())) { } template _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) @@ -165,8 +165,10 @@ namespace std template _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in) - : _Inherited(std::forward<_Inherited>(__in._M_tail())), - _Base(std::forward<_Base>(__in._M_head())) { } + : _Inherited(std::move:: + _Inherited&&>(__in._M_tail())), + _Base(std::forward:: + _Base>(__in._M_head())) { } _Tuple_impl& operator=(const _Tuple_impl& __in) @@ -219,21 +221,28 @@ namespace std template explicit tuple(_UElements&&... __elements) - : _Inherited(std::forward<_UElements>(__elements)...) { } + : _Inherited(std::forward<_UElements>(__elements)...) { } tuple(const tuple& __in) - : _Inherited(__in) { } + : _Inherited(static_cast(__in)) { } tuple(tuple&& __in) - : _Inherited(std::move(__in)) { } + : _Inherited(std::move<_Inherited>(__in)) { } template tuple(const tuple<_UElements...>& __in) - : _Inherited(__in) { } + : _Inherited(static_cast&>(__in)) + { } template tuple(tuple<_UElements...>&& __in) - : _Inherited(std::move(__in)) { } + : _Inherited(std::move<_Tuple_impl<0, _UElements...> >(__in)) { } + + // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html + template + tuple(tuple<_UElements...>& __in) + : _Inherited(static_cast&>(__in)) + { } tuple& operator=(const tuple& __in) @@ -288,34 +297,26 @@ namespace std : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } tuple(const tuple& __in) - : _Inherited(__in) { } + : _Inherited(static_cast(__in)) { } tuple(tuple&& __in) - : _Inherited(std::move(__in)) { } + : _Inherited(std::move<_Inherited>(__in)) { } template tuple(const tuple<_U1, _U2>& __in) - : _Inherited(__in) { } + : _Inherited(static_cast&>(__in)) { } template tuple(tuple<_U1, _U2>&& __in) - : _Inherited(std::move(__in)) { } + : _Inherited(std::move<_Tuple_impl<0, _U1, _U2> >(__in)) { } template tuple(const pair<_U1, _U2>& __in) - : _Inherited(_Tuple_impl<0, - typename __add_c_ref<_U1>::type, - typename __add_c_ref<_U2>::type>(__in.first, - __in.second)) - { } + : _Inherited(__in.first, __in.second) { } template tuple(pair<_U1, _U2>&& __in) - : _Inherited(_Tuple_impl<0, - typename std::remove_reference<_U1>::type&&, - typename std::remove_reference<_U2>::type&&> - (std::move(__in.first), std::move(__in.second))) - { } + : _Inherited(std::move(__in.first), std::move(__in.second)) { } tuple& operator=(const tuple& __in) @@ -555,8 +556,8 @@ namespace std const __index_holder<_TIdx...>&, const tuple<_UElements...>& __u, const __index_holder<_UIdx...>&) - { return tuple<_TElements..., _UElements...>(std::move(get<_TIdx>(__t))..., - get<_UIdx>(__u)...); } + { return tuple<_TElements..., _UElements...> + (std::move(get<_TIdx>(__t))..., get<_UIdx>(__u)...); } template @@ -565,8 +566,8 @@ namespace std const __index_holder<_TIdx...>&, tuple<_UElements...>&& __u, const __index_holder<_UIdx...>&) - { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)..., - std::move(get<_UIdx>(__u))...); } + { return tuple<_TElements..., _UElements...> + (get<_TIdx>(__t)..., std::move(get<_UIdx>(__u))...); } template @@ -575,8 +576,8 @@ namespace std const __index_holder<_TIdx...>&, tuple<_UElements...>&& __u, const __index_holder<_UIdx...>&) - { return tuple<_TElements..., _UElements...>(std::move(get<_TIdx>(__t))..., - std::move(get<_UIdx>(__u))...); } + { return tuple<_TElements..., _UElements...> + (std::move(get<_TIdx>(__t))..., std::move(get<_UIdx>(__u))...); } template inline tuple<_TElements..., _UElements...> @@ -618,12 +619,6 @@ namespace std __make_index_holder<_UElements...>::type()); } - template - tuple<_TElements..., _UElements...> - operator+(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u) - { return tuple_cat(std::forward(__t), - std::forward(__u)); } - template inline tuple<_Elements&...> tie(_Elements&... __args) diff --git a/libstdc++-v3/testsuite/20_util/tuple/moveable2.cc b/libstdc++-v3/testsuite/20_util/tuple/moveable2.cc new file mode 100644 index 00000000000..ae7a4e2279d --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/moveable2.cc @@ -0,0 +1,73 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include + +struct MoveOnly +{ + MoveOnly () { } + + MoveOnly (MoveOnly&&) { } + + MoveOnly& operator=(MoveOnly&&) + { return *this; } + +private: + MoveOnly(MoveOnly const&); // = delete + MoveOnly& operator=(MoveOnly const&); // = delete +}; + +MoveOnly +make_move_only () +{ return MoveOnly(); } + +// http://gcc.gnu.org/ml/libstdc++/2008-02/msg00046.html +void test01() +{ + typedef std::tuple move_only_tuple; + + move_only_tuple t1(make_move_only()); + move_only_tuple t2(std::move(t1)); + move_only_tuple t3 = std::move(t2); + t1 = std::move(t3); + + typedef std::tuple move_only_tuple2; + + move_only_tuple2 t4(make_move_only(), make_move_only()); + move_only_tuple2 t5(std::move(t4)); + move_only_tuple2 t6 = std::move(t5); + t4 = std::move(t6); +} + +int main() +{ + test01(); + return 0; +}