diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2011-07-25 17:08:48 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2011-07-25 17:08:48 +0000 |
commit | cc2ba8e30fa7378e5f0e4a7473287c918d7db663 (patch) | |
tree | 8bf7168be80b73a3be6683e8ecbc408f74f347c5 | |
parent | 8175c19c1ba6e51ea44e00ea4bff5a3725ddbddb (diff) | |
download | gcc-cc2ba8e30fa7378e5f0e4a7473287c918d7db663.zip gcc-cc2ba8e30fa7378e5f0e4a7473287c918d7db663.tar.gz gcc-cc2ba8e30fa7378e5f0e4a7473287c918d7db663.tar.bz2 |
re PR libstdc++/49836 ([C++0x] vector<T>::push_back() should not require T to be (move-)assignable)
2011-07-25 Paolo Carlini <paolo.carlini@oracle.com>
Nathan Ridge <zeratul976@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.
Co-Authored-By: Nathan Ridge <zeratul976@hotmail.com>
From-SVN: r176761
11 files changed, 250 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9130181..79db713 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2011-07-25 Paolo Carlini <paolo.carlini@oracle.com> + Nathan Ridge <zeratul976@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. + 2011-07-24 Paolo Carlini <paolo.carlini@oracle.com> * 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 0211033..601459b 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<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. diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 85b514b..ba98c7c 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<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>:: 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 0000000..290a191 --- /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 +// <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; +} 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 0000000..b481aff --- /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 +// <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; +} 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 0000000..0a6426a --- /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 +// <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; +} 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 8ff8545..55b9096 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 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1218 } +// { dg-error "no matching" "" { target *-*-* } 1222 } #include <vector> 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 344f1a6..6ea2c6f 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 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1148 } +// { dg-error "no matching" "" { target *-*-* } 1152 } #include <vector> 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 7f3c52e..75b5bd6 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 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1148 } +// { dg-error "no matching" "" { target *-*-* } 1152 } #include <vector> #include <utility> 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 c2337c8..d93de19 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 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1259 } +// { dg-error "no matching" "" { target *-*-* } 1263 } #include <vector> diff --git a/libstdc++-v3/testsuite/util/testsuite_tr1.h b/libstdc++-v3/testsuite/util/testsuite_tr1.h index 842d445..94207a6 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 |