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