Hi, tested x86_64-linux, committed to mainline (see audit trail for details)
Thanks, Paolo. ////////////////////////
2011-07-25 Paolo Carlini <paolo.carl...@oracle.com> Nathan Ridge <zeratul...@hotmail.com> PR libstdc++/49836 * include/bits/stl_vector.h (vector<>::_M_emplace_back_aux): Declare. (vector<>::push_back(const value_type&)): Use it. * include/bits/vector.tcc: Define. (vector<>::emplace_back(_Args&&...)): Use it. * testsuite/util/testsuite_tr1.h (CopyConsOnlyType, MoveConsOnlyType): Add. * testsuite/23_containers/vector/modifiers/push_back/49836.cc: New. * testsuite/23_containers/deque/modifiers/push_back/49836.cc: Likewise. * testsuite/23_containers/deque/modifiers/push_front/49836.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: Adjust dg-error line number. * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/ constructor_1_neg.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/ constructor_2_neg.cc: Likewise.
Index: include/bits/stl_vector.h =================================================================== --- include/bits/stl_vector.h (revision 176718) +++ include/bits/stl_vector.h (working copy) @@ -902,7 +902,11 @@ ++this->_M_impl._M_finish; } else +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + _M_emplace_back_aux(__x); +#else _M_insert_aux(end(), __x); +#endif } #ifdef __GXX_EXPERIMENTAL_CXX0X__ @@ -1303,6 +1307,10 @@ template<typename... _Args> void _M_insert_aux(iterator __position, _Args&&... __args); + + template<typename... _Args> + void + _M_emplace_back_aux(_Args&&... __args); #endif // Called by the latter. Index: include/bits/vector.tcc =================================================================== --- include/bits/vector.tcc (revision 176718) +++ include/bits/vector.tcc (working copy) @@ -99,7 +99,7 @@ ++this->_M_impl._M_finish; } else - _M_insert_aux(end(), std::forward<_Args>(__args)...); + _M_emplace_back_aux(std::forward<_Args>(__args)...); } #endif @@ -387,7 +387,51 @@ } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ template<typename _Tp, typename _Alloc> + template<typename... _Args> + void + vector<_Tp, _Alloc>:: + _M_emplace_back_aux(_Args&&... __args) + { + const size_type __len = + _M_check_len(size_type(1), "vector::_M_emplace_back_aux"); + pointer __new_start(this->_M_allocate(__len)); + pointer __new_finish(__new_start); + __try + { + _Alloc_traits::construct(this->_M_impl, __new_start + size(), + std::forward<_Args>(__args)...); + __new_finish = 0; + + __new_finish + = std::__uninitialized_move_if_noexcept_a + (this->_M_impl._M_start, this->_M_impl._M_finish, + __new_start, _M_get_Tp_allocator()); + + ++__new_finish; + } + __catch(...) + { + if (!__new_finish) + _Alloc_traits::destroy(this->_M_impl, __new_start + size()); + else + std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); + _M_deallocate(__new_start, __len); + __throw_exception_again; + } + std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, + _M_get_Tp_allocator()); + _M_deallocate(this->_M_impl._M_start, + this->_M_impl._M_end_of_storage + - this->_M_impl._M_start); + this->_M_impl._M_start = __new_start; + this->_M_impl._M_finish = __new_finish; + this->_M_impl._M_end_of_storage = __new_start + __len; + } +#endif + + template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>:: _M_fill_insert(iterator __position, size_type __n, const value_type& __x) Index: testsuite/23_containers/vector/modifiers/push_back/49836.cc =================================================================== --- testsuite/23_containers/vector/modifiers/push_back/49836.cc (revision 0) +++ testsuite/23_containers/vector/modifiers/push_back/49836.cc (revision 0) @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 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 <vector> +#include <testsuite_hooks.h> +#include <testsuite_tr1.h> + +// libstdc++/49836 +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::CopyConsOnlyType; + using __gnu_test::MoveConsOnlyType; + + std::vector<CopyConsOnlyType> v1; + CopyConsOnlyType t1(1); + v1.push_back(t1); + v1.push_back(t1); + v1.push_back(t1); + VERIFY( v1.size() == 3 ); + + std::vector<MoveConsOnlyType> v2; + MoveConsOnlyType t2(1); + v2.push_back(std::move(t2)); + v2.push_back(std::move(t2)); + v2.push_back(std::move(t2)); + VERIFY( v2.size() == 3 ); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/vector/requirements/dr438/assign_neg.cc =================================================================== --- testsuite/23_containers/vector/requirements/dr438/assign_neg.cc (revision 176718) +++ testsuite/23_containers/vector/requirements/dr438/assign_neg.cc (working copy) @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1218 } +// { dg-error "no matching" "" { target *-*-* } 1222 } #include <vector> Index: testsuite/23_containers/vector/requirements/dr438/insert_neg.cc =================================================================== --- testsuite/23_containers/vector/requirements/dr438/insert_neg.cc (revision 176718) +++ testsuite/23_containers/vector/requirements/dr438/insert_neg.cc (working copy) @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1259 } +// { dg-error "no matching" "" { target *-*-* } 1263 } #include <vector> Index: testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc =================================================================== --- testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc (revision 176718) +++ testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc (working copy) @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1148 } +// { dg-error "no matching" "" { target *-*-* } 1152 } #include <vector> Index: testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc =================================================================== --- testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc (revision 176718) +++ testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc (working copy) @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1148 } +// { dg-error "no matching" "" { target *-*-* } 1152 } #include <vector> #include <utility> Index: testsuite/23_containers/deque/modifiers/push_back/49836.cc =================================================================== --- testsuite/23_containers/deque/modifiers/push_back/49836.cc (revision 0) +++ testsuite/23_containers/deque/modifiers/push_back/49836.cc (revision 0) @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 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 <deque> +#include <testsuite_hooks.h> +#include <testsuite_tr1.h> + +// libstdc++/49836 +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::CopyConsOnlyType; + using __gnu_test::MoveConsOnlyType; + + std::deque<CopyConsOnlyType> d1; + CopyConsOnlyType t1(1); + d1.push_back(t1); + d1.push_back(t1); + d1.push_back(t1); + VERIFY( d1.size() == 3 ); + + std::deque<MoveConsOnlyType> d2; + MoveConsOnlyType t2(1); + d2.push_back(std::move(t2)); + d2.push_back(std::move(t2)); + d2.push_back(std::move(t2)); + VERIFY( d2.size() == 3 ); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/deque/modifiers/push_front/49836.cc =================================================================== --- testsuite/23_containers/deque/modifiers/push_front/49836.cc (revision 0) +++ testsuite/23_containers/deque/modifiers/push_front/49836.cc (revision 0) @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 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 <deque> +#include <testsuite_hooks.h> +#include <testsuite_tr1.h> + +// libstdc++/49836 +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::CopyConsOnlyType; + using __gnu_test::MoveConsOnlyType; + + std::deque<CopyConsOnlyType> d1; + CopyConsOnlyType t1(1); + d1.push_front(t1); + d1.push_front(t1); + d1.push_front(t1); + VERIFY( d1.size() == 3 ); + + std::deque<MoveConsOnlyType> d2; + MoveConsOnlyType t2(1); + d2.push_front(std::move(t2)); + d2.push_front(std::move(t2)); + d2.push_front(std::move(t2)); + VERIFY( d2.size() == 3 ); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/util/testsuite_tr1.h =================================================================== --- testsuite/util/testsuite_tr1.h (revision 176718) +++ testsuite/util/testsuite_tr1.h (working copy) @@ -696,6 +696,24 @@ MO& operator=(MO&&) = default; }; } + + struct CopyConsOnlyType + { + CopyConsOnlyType(int) { } + CopyConsOnlyType(CopyConsOnlyType&&) = delete; + CopyConsOnlyType(const CopyConsOnlyType&) = default; + CopyConsOnlyType& operator=(const CopyConsOnlyType&) = delete; + CopyConsOnlyType& operator=(CopyConsOnlyType&&) = delete; + }; + + struct MoveConsOnlyType + { + MoveConsOnlyType(int) { } + MoveConsOnlyType(const MoveConsOnlyType&) = delete; + MoveConsOnlyType(MoveConsOnlyType&&) = default; + MoveConsOnlyType& operator=(const MoveConsOnlyType&) = delete; + MoveConsOnlyType& operator=(MoveConsOnlyType&&) = delete; + }; #endif } // namespace __gnu_test