This patch adds a _Guard_nodes scope guard nested to the _Deque_base, that deallocates the range of nodes, and replaces __try/__catch block with approparietly constructed guard object.
libstdc++-v3/ChangeLog: * include/bits/deque.tcc (_Deque_base<_Tp, _Alloc>::_Guard_nodes): Define. (_Deque_base<_Tp, _Alloc>::_M_create_nodes): Moved defintion from stl_deque.h and replace __try/__catch with _Guard_nodes scope object. (deque<_Tp, _Alloc>::_M_fill_insert, deque<_Tp, _Alloc>::_M_default_append) (deque<_Tp, _Alloc>::_M_push_back_aux, deque<_Tp, _Alloc>::_M_push_front_aux) (deque<_Tp, _Alloc>::_M_range_prepend, deque<_Tp, _Alloc>::_M_range_append) (deque<_Tp, _Alloc>::_M_insert_aux): Replace __try/__catch with _Guard_nodes scope object. (deque<_Tp, _Alloc>::_M_new_elements_at_back) (deque<_Tp, _Alloc>::_M_new_elements_at_back): Use _M_create_nodes. * include/bits/stl_deque.h (_Deque_base<_Tp, _Alloc>::_Guard_nodes): Declare. (_Deque_base<_Tp, _Alloc)::_M_create_nodes): Move defintion to deque.tcc. (deque<_Tp, _Alloc>::_Guard_nodes): Add typedef, so name is found by lookup. --- Testing x86_64-linux, default test configuration passed. OK for trunk? libstdc++-v3/include/bits/deque.tcc | 424 ++++++++++++-------------- libstdc++-v3/include/bits/stl_deque.h | 20 +- 2 files changed, 196 insertions(+), 248 deletions(-) diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index dabb6ec5365..b70eed69294 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -63,6 +63,40 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER + template<typename _Tp, typename _Alloc> + struct + _Deque_base<_Tp, _Alloc>::_Guard_nodes + { + _Guard_nodes(_Deque_base& __self, + _Map_pointer __first, _Map_pointer __last) + : _M_self(__self), _M_first(__first), _M_last(__last) + { } + + ~_Guard_nodes() + { _M_self._M_destroy_nodes(_M_first, _M_last); } + + void _M_disarm() + { _M_first = _M_last; } + + _Deque_base& _M_self; + _Map_pointer _M_first; + _Map_pointer _M_last; + + private: + _Guard_nodes(_Guard_nodes const&); + }; + + template<typename _Tp, typename _Alloc> + void + _Deque_base<_Tp, _Alloc>:: + _M_create_nodes(_Map_pointer __nstart, _Map_pointer __nfinish) + { + _Guard_nodes __guard(*this, __nstart, __nstart); + for (_Map_pointer& __cur = __guard._M_last; __cur < __nfinish; ++__cur) + *__cur = this->_M_allocate_node(); + __guard._M_disarm(); + } + #if __cplusplus >= 201103L template <typename _Tp, typename _Alloc> void @@ -310,35 +344,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (__pos._M_cur == this->_M_impl._M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); - __try - { - std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start, - __x, _M_get_Tp_allocator()); - this->_M_impl._M_start = __new_start; - } - __catch(...) - { - _M_destroy_nodes(__new_start._M_node, - this->_M_impl._M_start._M_node); - __throw_exception_again; - } + _Guard_nodes __guard(*this, __new_start._M_node, + this->_M_impl._M_start._M_node); + + std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start, + __x, _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_start = __new_start; } else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); - __try - { - std::__uninitialized_fill_a(this->_M_impl._M_finish, - __new_finish, __x, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = __new_finish; - } - __catch(...) - { - _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, - __new_finish._M_node + 1); - __throw_exception_again; - } + _Guard_nodes __guard(*this, this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + + std::__uninitialized_fill_a(this->_M_impl._M_finish, + __new_finish, __x, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_finish = __new_finish; } else _M_insert_aux(__pos, __n, __x); @@ -350,23 +374,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER deque<_Tp, _Alloc>:: _M_default_append(size_type __n) { - if (__n) - { - iterator __new_finish = _M_reserve_elements_at_back(__n); - __try - { - std::__uninitialized_default_a(this->_M_impl._M_finish, - __new_finish, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = __new_finish; - } - __catch(...) - { - _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, - __new_finish._M_node + 1); - __throw_exception_again; - } - } + if (!__n) + return; + + iterator __new_finish = _M_reserve_elements_at_back(__n); + _Guard_nodes __guard(*this, this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + + std::__uninitialized_default_a(this->_M_impl._M_finish, + __new_finish, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_finish = __new_finish; } template <typename _Tp, typename _Alloc> @@ -495,24 +514,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_reserve_map_at_back(); *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); - __try - { + _Guard_nodes __guard(*this, this->_M_impl._M_finish._M_node, + this->_M_impl._M_finish._M_node + 1); #if __cplusplus >= 201103L - _Alloc_traits::construct(this->_M_impl, - this->_M_impl._M_finish._M_cur, - std::forward<_Args>(__args)...); + _Alloc_traits::construct(this->_M_impl, + this->_M_impl._M_finish._M_cur, + std::forward<_Args>(__args)...); #else - this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t); + this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t); #endif - this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - + 1); - this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; - } - __catch(...) - { - _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); - __throw_exception_again; - } + __guard._M_disarm(); + this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + 1); + this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; } // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. @@ -534,25 +547,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_reserve_map_at_front(); *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); - __try - { - this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - - 1); - this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; + _Guard_nodes __guard(*this, this->_M_impl._M_start._M_node - 1, + this->_M_impl._M_start._M_node); + + iterator __new_start; + __new_start._M_set_node(this->_M_impl._M_start._M_node - 1); + __new_start._M_cur = __new_start._M_last - 1; #if __cplusplus >= 201103L - _Alloc_traits::construct(this->_M_impl, - this->_M_impl._M_start._M_cur, - std::forward<_Args>(__args)...); + _Alloc_traits::construct(this->_M_impl, + __new_start._M_cur, + std::forward<_Args>(__args)...); #else - this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t); + this->_M_impl.construct(__new_start._M_cur, __t); #endif - } - __catch(...) - { - ++this->_M_impl._M_start; - _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); - __throw_exception_again; - } + __guard._M_disarm(); + this->_M_impl._M_start = __new_start; } // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. @@ -591,18 +600,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER size_type __n) { iterator __new_start = _M_reserve_elements_at_front(__n); - __try - { - std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last, - __new_start, _M_get_Tp_allocator()); - this->_M_impl._M_start = __new_start; - } - __catch(...) - { - _M_destroy_nodes(__new_start._M_node, - this->_M_impl._M_start._M_node); - __throw_exception_again; - } + _Guard_nodes __guard(*this, __new_start._M_node, + this->_M_impl._M_start._M_node); + + std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last, + __new_start, _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_start = __new_start; } template <typename _Tp, typename _Alloc> @@ -613,19 +617,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER size_type __n) { iterator __new_finish = _M_reserve_elements_at_back(__n); - __try - { - std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last, - this->_M_impl._M_finish, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = __new_finish; - } - __catch(...) - { - _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, - __new_finish._M_node + 1); - __throw_exception_again; - } + _Guard_nodes __guard(*this, this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + + std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_finish = __new_finish; } template <typename _Tp, typename _Alloc> @@ -712,35 +711,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER iterator __new_start = _M_reserve_elements_at_front(__n); iterator __old_start = this->_M_impl._M_start; __pos = this->_M_impl._M_start + __elems_before; - __try + + _Guard_nodes __guard(*this, __new_start._M_node, + this->_M_impl._M_start._M_node); + if (__elems_before >= difference_type(__n)) { - if (__elems_before >= difference_type(__n)) - { - iterator __start_n = (this->_M_impl._M_start - + difference_type(__n)); - std::__uninitialized_move_a(this->_M_impl._M_start, - __start_n, __new_start, - _M_get_Tp_allocator()); - this->_M_impl._M_start = __new_start; - _GLIBCXX_MOVE3(__start_n, __pos, __old_start); - std::fill(__pos - difference_type(__n), __pos, __x_copy); - } - else - { - std::__uninitialized_move_fill(this->_M_impl._M_start, - __pos, __new_start, - this->_M_impl._M_start, - __x_copy, - _M_get_Tp_allocator()); - this->_M_impl._M_start = __new_start; - std::fill(__old_start, __pos, __x_copy); - } + iterator __start_n = (this->_M_impl._M_start + + difference_type(__n)); + std::__uninitialized_move_a(this->_M_impl._M_start, + __start_n, __new_start, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_start = __new_start; + _GLIBCXX_MOVE3(__start_n, __pos, __old_start); + std::fill(__pos - difference_type(__n), __pos, __x_copy); } - __catch(...) + else { - _M_destroy_nodes(__new_start._M_node, - this->_M_impl._M_start._M_node); - __throw_exception_again; + std::__uninitialized_move_fill(this->_M_impl._M_start, + __pos, __new_start, + this->_M_impl._M_start, + __x_copy, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_start = __new_start; + std::fill(__old_start, __pos, __x_copy); } } else @@ -750,36 +745,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const difference_type __elems_after = difference_type(__length) - __elems_before; __pos = this->_M_impl._M_finish - __elems_after; - __try + + _Guard_nodes __guard(*this, this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + if (__elems_after > difference_type(__n)) { - if (__elems_after > difference_type(__n)) - { - iterator __finish_n = (this->_M_impl._M_finish - - difference_type(__n)); - std::__uninitialized_move_a(__finish_n, - this->_M_impl._M_finish, - this->_M_impl._M_finish, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = __new_finish; - _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); - std::fill(__pos, __pos + difference_type(__n), __x_copy); - } - else - { - std::__uninitialized_fill_move(this->_M_impl._M_finish, - __pos + difference_type(__n), - __x_copy, __pos, - this->_M_impl._M_finish, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = __new_finish; - std::fill(__pos, __old_finish, __x_copy); - } + iterator __finish_n = (this->_M_impl._M_finish + - difference_type(__n)); + std::__uninitialized_move_a(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_finish = __new_finish; + _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); + std::fill(__pos, __pos + difference_type(__n), __x_copy); } - __catch(...) + else { - _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, - __new_finish._M_node + 1); - __throw_exception_again; + std::__uninitialized_fill_move(this->_M_impl._M_finish, + __pos + difference_type(__n), + __x_copy, __pos, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_finish = __new_finish; + std::fill(__pos, __old_finish, __x_copy); } } } @@ -799,36 +790,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER iterator __new_start = _M_reserve_elements_at_front(__n); iterator __old_start = this->_M_impl._M_start; __pos = this->_M_impl._M_start + __elemsbefore; - __try + + _Guard_nodes __guard(*this, __new_start._M_node, + this->_M_impl._M_start._M_node); + + if (__elemsbefore >= difference_type(__n)) { - if (__elemsbefore >= difference_type(__n)) - { - iterator __start_n = (this->_M_impl._M_start - + difference_type(__n)); - std::__uninitialized_move_a(this->_M_impl._M_start, - __start_n, __new_start, - _M_get_Tp_allocator()); - this->_M_impl._M_start = __new_start; - _GLIBCXX_MOVE3(__start_n, __pos, __old_start); - std::copy(__first, __last, __pos - difference_type(__n)); - } - else - { - _ForwardIterator __mid = __first; - std::advance(__mid, difference_type(__n) - __elemsbefore); - std::__uninitialized_move_copy(this->_M_impl._M_start, - __pos, __first, __mid, - __new_start, - _M_get_Tp_allocator()); - this->_M_impl._M_start = __new_start; - std::copy(__mid, __last, __old_start); - } + iterator __start_n = (this->_M_impl._M_start + + difference_type(__n)); + std::__uninitialized_move_a(this->_M_impl._M_start, + __start_n, __new_start, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_start = __new_start; + _GLIBCXX_MOVE3(__start_n, __pos, __old_start); + std::copy(__first, __last, __pos - difference_type(__n)); } - __catch(...) + else { - _M_destroy_nodes(__new_start._M_node, - this->_M_impl._M_start._M_node); - __throw_exception_again; + _ForwardIterator __mid = __first; + std::advance(__mid, difference_type(__n) - __elemsbefore); + std::__uninitialized_move_copy(this->_M_impl._M_start, + __pos, __first, __mid, + __new_start, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_start = __new_start; + std::copy(__mid, __last, __old_start); } } else @@ -838,37 +826,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const difference_type __elemsafter = difference_type(__length) - __elemsbefore; __pos = this->_M_impl._M_finish - __elemsafter; - __try + + _Guard_nodes __guard(*this, this->_M_impl._M_finish._M_node + 1, + __new_finish._M_node + 1); + if (__elemsafter > difference_type(__n)) { - if (__elemsafter > difference_type(__n)) - { - iterator __finish_n = (this->_M_impl._M_finish - - difference_type(__n)); - std::__uninitialized_move_a(__finish_n, - this->_M_impl._M_finish, - this->_M_impl._M_finish, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = __new_finish; - _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); - std::copy(__first, __last, __pos); - } - else - { - _ForwardIterator __mid = __first; - std::advance(__mid, __elemsafter); - std::__uninitialized_copy_move(__mid, __last, __pos, - this->_M_impl._M_finish, - this->_M_impl._M_finish, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = __new_finish; - std::copy(__first, __mid, __pos); - } + iterator __finish_n = (this->_M_impl._M_finish + - difference_type(__n)); + std::__uninitialized_move_a(__finish_n, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_finish = __new_finish; + _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); + std::copy(__first, __last, __pos); } - __catch(...) + else { - _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, - __new_finish._M_node + 1); - __throw_exception_again; + _ForwardIterator __mid = __first; + std::advance(__mid, __elemsafter); + std::__uninitialized_copy_move(__mid, __last, __pos, + this->_M_impl._M_finish, + this->_M_impl._M_finish, + _M_get_Tp_allocator()); + __guard._M_disarm(); + this->_M_impl._M_finish = __new_finish; + std::copy(__first, __mid, __pos); } } } @@ -1057,18 +1041,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) / _S_buffer_size()); _M_reserve_map_at_front(__new_nodes); - size_type __i; - __try - { - for (__i = 1; __i <= __new_nodes; ++__i) - *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); - } - __catch(...) - { - for (size_type __j = 1; __j < __i; ++__j) - _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); - __throw_exception_again; - } + _M_create_nodes(this->_M_impl._M_start._M_node - __new_nodes, + this->_M_impl._M_start._M_node); } template <typename _Tp, typename _Alloc> @@ -1082,18 +1056,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) / _S_buffer_size()); _M_reserve_map_at_back(__new_nodes); - size_type __i; - __try - { - for (__i = 1; __i <= __new_nodes; ++__i) - *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); - } - __catch(...) - { - for (size_type __j = 1; __j < __i; ++__j) - _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); - __throw_exception_again; - } + _M_create_nodes(_M_impl._M_finish._M_node + 1, + _M_impl._M_finish._M_node + __new_nodes + 1); } template <typename _Tp, typename _Alloc> diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 8d8ee575a26..73e48299938 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -612,6 +612,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void _M_destroy_nodes(_Map_pointer __nstart, _Map_pointer __nfinish) _GLIBCXX_NOEXCEPT; enum { _S_initial_map_size = 8 }; + struct _Guard_nodes; _Deque_impl _M_impl; }; @@ -675,24 +676,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER % __deque_buf_size(sizeof(_Tp))); } - template<typename _Tp, typename _Alloc> - void - _Deque_base<_Tp, _Alloc>:: - _M_create_nodes(_Map_pointer __nstart, _Map_pointer __nfinish) - { - _Map_pointer __cur; - __try - { - for (__cur = __nstart; __cur < __nfinish; ++__cur) - *__cur = this->_M_allocate_node(); - } - __catch(...) - { - _M_destroy_nodes(__nstart, __cur); - __throw_exception_again; - } - } - template<typename _Tp, typename _Alloc> void _Deque_base<_Tp, _Alloc>:: @@ -812,6 +795,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; typedef typename _Base::_Alloc_traits _Alloc_traits; typedef typename _Base::_Map_pointer _Map_pointer; + typedef typename _Base::_Guard_nodes _Guard_nodes; public: typedef _Tp value_type; -- 2.49.0