diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2011-06-07 16:11:36 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2011-06-07 16:11:36 +0000 |
commit | 74a2a1b4f60cb499962d67c43e7d0b3b783b1373 (patch) | |
tree | 44f8b32ca92b13801daecdae7376732bd875fb7c | |
parent | 06bc3ec79056f8c53d4e59f45afe78a547c23546 (diff) | |
download | gcc-74a2a1b4f60cb499962d67c43e7d0b3b783b1373.zip gcc-74a2a1b4f60cb499962d67c43e7d0b3b783b1373.tar.gz gcc-74a2a1b4f60cb499962d67c43e7d0b3b783b1373.tar.bz2 |
move.h (struct __move_if_noexcept_cond): Add.
2011-06-07 Paolo Carlini <paolo.carlini@oracle.com>
* include/bits/move.h (struct __move_if_noexcept_cond): Add.
(move_if_noexcept): Use the latter.
* include/bits/stl_iterator.h (__make_move_if_noexcept_iterator,
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR): Add.
* include/bits/stl_uninitialized.h
(__uninitialized_move_if_noexcept_a): Add.
* include/bits/vector.tcc (vector<>::reserve): Use
_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR.
(vector<>::_M_insert_aux, _M_fill_insert, _M_default_append,
_M_range_insert): Use __uninitialized_move_if_noexcept_a.
* testsuite/23_containers/vector/modifiers/moveable2.cc: New.
* testsuite/23_containers/vector/capacity/resize/moveable2.cc:
Likewise.
* testsuite/23_containers/vector/capacity/reserve/moveable2.cc:
Likewise.
From-SVN: r174756
-rw-r--r-- | libstdc++-v3/ChangeLog | 18 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/move.h | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_iterator.h | 11 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_uninitialized.h | 13 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/vector.tcc | 76 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/vector/capacity/reserve/moveable2.cc | 45 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/vector/capacity/resize/moveable2.cc | 57 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable2.cc | 77 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/util/testsuite_rvalref.h | 14 |
9 files changed, 276 insertions, 45 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0e3d551..2f3707b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,23 @@ 2011-06-07 Paolo Carlini <paolo.carlini@oracle.com> + * include/bits/move.h (struct __move_if_noexcept_cond): Add. + (move_if_noexcept): Use the latter. + * include/bits/stl_iterator.h (__make_move_if_noexcept_iterator, + _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR): Add. + * include/bits/stl_uninitialized.h + (__uninitialized_move_if_noexcept_a): Add. + * include/bits/vector.tcc (vector<>::reserve): Use + _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR. + (vector<>::_M_insert_aux, _M_fill_insert, _M_default_append, + _M_range_insert): Use __uninitialized_move_if_noexcept_a. + * testsuite/23_containers/vector/modifiers/moveable2.cc: New. + * testsuite/23_containers/vector/capacity/resize/moveable2.cc: + Likewise. + * testsuite/23_containers/vector/capacity/reserve/moveable2.cc: + Likewise. + +2011-06-07 Paolo Carlini <paolo.carlini@oracle.com> + PR libstdc++/49293 * testsuite/22_locale/time_get/get_weekday/char/38081-1.cc: Tweak for glibc 2.14. diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index 6f3b420..d791d69 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -82,6 +82,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION move(_Tp&& __t) noexcept { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); } + + template<typename _Tp> + struct __move_if_noexcept_cond + : public __and_<__not_<is_nothrow_move_constructible<_Tp>>, + is_copy_constructible<_Tp>>::type { }; + /** * @brief Move unless it could throw and the type is copyable. * @ingroup utilities @@ -90,9 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _Tp> inline typename - conditional<__and_<__not_<is_nothrow_move_constructible<_Tp>>, - is_copy_constructible<_Tp>>::value, - const _Tp&, _Tp&&>::type + conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type move_if_noexcept(_Tp& __x) noexcept { return std::move(__x); } diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index b23107d..c2a1689 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1118,14 +1118,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION make_move_iterator(const _Iterator& __i) { return move_iterator<_Iterator>(__i); } + template<typename _Iterator, typename _ReturnType + = typename conditional<__move_if_noexcept_cond + <typename iterator_traits<_Iterator>::value_type>::value, + _Iterator, move_iterator<_Iterator>>::type> + inline _ReturnType + __make_move_if_noexcept_iterator(_Iterator __i) + { return _ReturnType(__i); } + // @} group iterators _GLIBCXX_END_NAMESPACE_VERSION } // namespace #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter) +#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) \ + std::__make_move_if_noexcept_iterator(_Iter) #else #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter) +#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter) #endif // __GXX_EXPERIMENTAL_CXX0X__ #endif diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index f15be3a..246d5c3 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -269,6 +269,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __result, __alloc); } + template<typename _InputIterator, typename _ForwardIterator, + typename _Allocator> + inline _ForwardIterator + __uninitialized_move_if_noexcept_a(_InputIterator __first, + _InputIterator __last, + _ForwardIterator __result, + _Allocator& __alloc) + { + return std::__uninitialized_copy_a + (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), + _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); + } + template<typename _ForwardIterator, typename _Tp, typename _Allocator> void __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 3aaee39..5b6a8d7 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -72,8 +72,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { const size_type __old_size = size(); pointer __tmp = _M_allocate_and_copy(__n, - _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_start), - _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_finish)); + _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start), + _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish)); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -337,17 +337,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif __new_finish = 0; - __new_finish = - std::__uninitialized_move_a(this->_M_impl._M_start, - __position.base(), __new_start, - _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_move_if_noexcept_a + (this->_M_impl._M_start, __position.base(), + __new_start, _M_get_Tp_allocator()); + ++__new_finish; - __new_finish = - std::__uninitialized_move_a(__position.base(), - this->_M_impl._M_finish, - __new_finish, - _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_move_if_noexcept_a + (__position.base(), this->_M_impl._M_finish, + __new_finish, _M_get_Tp_allocator()); } __catch(...) { @@ -423,18 +423,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_get_Tp_allocator()); __new_finish = 0; - __new_finish = - std::__uninitialized_move_a(this->_M_impl._M_start, - __position.base(), - __new_start, - _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_move_if_noexcept_a + (this->_M_impl._M_start, __position.base(), + __new_start, _M_get_Tp_allocator()); + __new_finish += __n; - __new_finish = - std::__uninitialized_move_a(__position.base(), - this->_M_impl._M_finish, - __new_finish, - _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_move_if_noexcept_a + (__position.base(), this->_M_impl._M_finish, + __new_finish, _M_get_Tp_allocator()); } __catch(...) { @@ -484,11 +483,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer __new_finish(__new_start); __try { - __new_finish = - std::__uninitialized_move_a(this->_M_impl._M_start, - this->_M_impl._M_finish, - __new_start, - _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_move_if_noexcept_a + (this->_M_impl._M_start, this->_M_impl._M_finish, + __new_start, _M_get_Tp_allocator()); std::__uninitialized_default_n_a(__new_finish, __n, _M_get_Tp_allocator()); __new_finish += __n; @@ -577,20 +575,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer __new_finish(__new_start); __try { - __new_finish = - std::__uninitialized_move_a(this->_M_impl._M_start, - __position.base(), - __new_start, - _M_get_Tp_allocator()); - __new_finish = - std::__uninitialized_copy_a(__first, __last, - __new_finish, - _M_get_Tp_allocator()); - __new_finish = - std::__uninitialized_move_a(__position.base(), - this->_M_impl._M_finish, - __new_finish, - _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_move_if_noexcept_a + (this->_M_impl._M_start, __position.base(), + __new_start, _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_copy_a(__first, __last, + __new_finish, + _M_get_Tp_allocator()); + __new_finish + = std::__uninitialized_move_if_noexcept_a + (__position.base(), this->_M_impl._M_finish, + __new_finish, _M_get_Tp_allocator()); } __catch(...) { diff --git a/libstdc++-v3/testsuite/23_containers/vector/capacity/reserve/moveable2.cc b/libstdc++-v3/testsuite/23_containers/vector/capacity/reserve/moveable2.cc new file mode 100644 index 0000000..3a6c313 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/reserve/moveable2.cc @@ -0,0 +1,45 @@ +// { dg-options "-std=gnu++0x" } + +// 2011-06-07 Paolo Carlini <paolo.carlini@oracle.com> + +// 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_rvalref.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + using namespace __gnu_test; + + std::vector<throwing_move_constructor> v(5); + + v.reserve(50); + VERIFY( v.capacity() >= 50 ); + + v.reserve(500); + VERIFY( v.capacity() >= 500 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/capacity/resize/moveable2.cc b/libstdc++-v3/testsuite/23_containers/vector/capacity/resize/moveable2.cc new file mode 100644 index 0000000..5bdb981 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/resize/moveable2.cc @@ -0,0 +1,57 @@ +// { dg-options "-std=gnu++0x" } + +// 2011-06-07 Paolo Carlini <paolo.carlini@oracle.com> + +// 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_rvalref.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + using namespace __gnu_test; + + std::vector<throwing_move_constructor> v(5); + + v.resize(50); + VERIFY( v.size() == 50 ); + + v.reserve(200); + VERIFY( v.capacity() >= 200 ); + + v.resize(100); + VERIFY( v.size() == 100 ); + + v.resize(500, throwing_move_constructor()); + VERIFY( v.size() == 500 ); + + v.reserve(2000); + VERIFY( v.capacity() >= 2000 ); + + v.resize(1000, throwing_move_constructor()); + VERIFY( v.size() == 1000 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable2.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable2.cc new file mode 100644 index 0000000..000db2c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable2.cc @@ -0,0 +1,77 @@ +// { dg-options "-std=gnu++0x" } + +// 2011-06-07 Paolo Carlini <paolo.carlini@oracle.com> + +// 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_rvalref.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + using namespace __gnu_test; + + std::vector<throwing_move_constructor> v1; + + throwing_move_constructor tmc; + + v1.push_back(tmc); + VERIFY( v1.size() == 1 ); + + v1.push_back(tmc); + VERIFY( v1.size() == 2 ); + + v1.insert(v1.end(), tmc); + VERIFY( v1.size() == 3 ); + + v1.insert(v1.end(), 100, tmc); + VERIFY( v1.size() == 103 ); + + v1.insert(v1.end(), 10, tmc); + VERIFY( v1.size() == 113 ); + + v1.insert(v1.end(), 1, tmc); + VERIFY( v1.size() == 114 ); + + std::vector<throwing_move_constructor> v2; + + throwing_move_constructor tmca[] + = { throwing_move_constructor(), throwing_move_constructor(), + throwing_move_constructor(), throwing_move_constructor() }; + + v2.insert(v2.end(), tmca, tmca + 1); + VERIFY( v2.size() == 1 ); + + v2.insert(v2.end(), tmca, tmca + 4); + VERIFY( v2.size() == 5 ); + + v2.insert(v2.end(), tmca, tmca + 2); + VERIFY( v2.size() == 7 ); + + v2.insert(v2.end(), tmca, tmca + 1); + VERIFY( v2.size() == 8 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/util/testsuite_rvalref.h b/libstdc++-v3/testsuite/util/testsuite_rvalref.h index 8e37bbd..3159915 100644 --- a/libstdc++-v3/testsuite/util/testsuite_rvalref.h +++ b/libstdc++-v3/testsuite/util/testsuite_rvalref.h @@ -117,7 +117,7 @@ namespace __gnu_test ++copycount; } - copycounter(copycounter&& in) + copycounter(copycounter&& in) noexcept { bool test __attribute__((unused)) = true; VERIFY( in.valid == true ); @@ -156,7 +156,7 @@ namespace __gnu_test return *this; } - ~copycounter() + ~copycounter() noexcept { valid = false; } }; @@ -246,6 +246,16 @@ namespace __gnu_test return lh.val < rh.val; } + struct throwing_move_constructor + { + throwing_move_constructor() = default; + + throwing_move_constructor(throwing_move_constructor&&) + { throw 1; } + + throwing_move_constructor(const throwing_move_constructor&) = default; + }; + } // namespace __gnu_test namespace std |