On Thu, May 8, 2025 at 7:46 PM Jonathan Wakely <jwak...@redhat.com> wrote:

> On Fri, 18 Apr 2025 at 10:03, Tomasz Kamiński <tkami...@redhat.com> wrote:
> >
> > 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.
>
> "appropriately"
>
> >
> > libstdc++-v3/ChangeLog:
> >
> >         * include/bits/deque.tcc (_Deque_base<_Tp,
> _Alloc>::_Guard_nodes): Define.
>
> There's no need for the template argument list here, just
> "_Deque_base" is unambiguous (there's no partial or explicit
> specialization that could be disambiguated with template argument
> lists). And just "deque" below.
>
> >         (_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
>
> No new line here, just "struct _Deque_base...".
>
> > +    _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));
>
> This deallocates _M_node+1 but the guard object guards
> [_M_node,_M_node+1). I think there's an off-by-one error here.
>
Yes, indeed. I will also add a test that will detect this.

>
> > -           __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
> >
>
>

Reply via email to