From cc2ba8e30fa7378e5f0e4a7473287c918d7db663 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Mon, 25 Jul 2011 17:08:48 +0000 Subject: [PATCH] re PR libstdc++/49836 ([C++0x] vector::push_back() should not require T to be (move-)assignable) 2011-07-25 Paolo Carlini Nathan Ridge 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. Co-Authored-By: Nathan Ridge From-SVN: r176761 --- libstdc++-v3/ChangeLog | 25 ++++++++++ libstdc++-v3/include/bits/stl_vector.h | 8 +++ libstdc++-v3/include/bits/vector.tcc | 46 ++++++++++++++++- .../deque/modifiers/push_back/49836.cc | 50 +++++++++++++++++++ .../deque/modifiers/push_front/49836.cc | 50 +++++++++++++++++++ .../vector/modifiers/push_back/49836.cc | 50 +++++++++++++++++++ .../vector/requirements/dr438/assign_neg.cc | 2 +- .../requirements/dr438/constructor_1_neg.cc | 2 +- .../requirements/dr438/constructor_2_neg.cc | 2 +- .../vector/requirements/dr438/insert_neg.cc | 2 +- libstdc++-v3/testsuite/util/testsuite_tr1.h | 18 +++++++ 11 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/deque/modifiers/push_back/49836.cc create mode 100644 libstdc++-v3/testsuite/23_containers/deque/modifiers/push_front/49836.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 91301815bad..79db713ff5b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2011-07-25 Paolo Carlini + Nathan Ridge + + 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. + 2011-07-24 Paolo Carlini * include/bits/hashtable_policy.h (_Prime_rehash_policy::_M_next_bkt, diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 0211033a456..601459b3eaf 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -902,7 +902,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ++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 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template void _M_insert_aux(iterator __position, _Args&&... __args); + + template + void + _M_emplace_back_aux(_Args&&... __args); #endif // Called by the latter. diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 85b514b561b..ba98c7cb07e 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -99,7 +99,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ++this->_M_impl._M_finish; } else - _M_insert_aux(end(), std::forward<_Args>(__args)...); + _M_emplace_back_aux(std::forward<_Args>(__args)...); } #endif @@ -387,6 +387,50 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + template + 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 void vector<_Tp, _Alloc>:: diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_back/49836.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_back/49836.cc new file mode 100644 index 00000000000..290a191c26e --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_back/49836.cc @@ -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 +// . + +#include +#include +#include + +// libstdc++/49836 +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::CopyConsOnlyType; + using __gnu_test::MoveConsOnlyType; + + std::deque d1; + CopyConsOnlyType t1(1); + d1.push_back(t1); + d1.push_back(t1); + d1.push_back(t1); + VERIFY( d1.size() == 3 ); + + std::deque 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; +} diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_front/49836.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_front/49836.cc new file mode 100644 index 00000000000..b481aff3bc8 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/push_front/49836.cc @@ -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 +// . + +#include +#include +#include + +// libstdc++/49836 +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::CopyConsOnlyType; + using __gnu_test::MoveConsOnlyType; + + std::deque d1; + CopyConsOnlyType t1(1); + d1.push_front(t1); + d1.push_front(t1); + d1.push_front(t1); + VERIFY( d1.size() == 3 ); + + std::deque 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; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc new file mode 100644 index 00000000000..0a6426ad540 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc @@ -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 +// . + +#include +#include +#include + +// libstdc++/49836 +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::CopyConsOnlyType; + using __gnu_test::MoveConsOnlyType; + + std::vector v1; + CopyConsOnlyType t1(1); + v1.push_back(t1); + v1.push_back(t1); + v1.push_back(t1); + VERIFY( v1.size() == 3 ); + + std::vector 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; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc index 8ff85455db7..55b9096d768 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1218 } +// { dg-error "no matching" "" { target *-*-* } 1222 } #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc index 344f1a68170..6ea2c6f1145 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1148 } +// { dg-error "no matching" "" { target *-*-* } 1152 } #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc index 7f3c52e8058..75b5bd6d218 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1148 } +// { dg-error "no matching" "" { target *-*-* } 1152 } #include #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc index c2337c82c65..d93de19d486 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1259 } +// { dg-error "no matching" "" { target *-*-* } 1263 } #include diff --git a/libstdc++-v3/testsuite/util/testsuite_tr1.h b/libstdc++-v3/testsuite/util/testsuite_tr1.h index 842d4453897..94207a6e63d 100644 --- a/libstdc++-v3/testsuite/util/testsuite_tr1.h +++ b/libstdc++-v3/testsuite/util/testsuite_tr1.h @@ -696,6 +696,24 @@ namespace __gnu_test 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 -- 2.30.2