2019-05-17 François Dumont <fdumont@gcc.gnu.org>
authorFrançois Dumont <fdumont@gcc.gnu.org>
Fri, 17 May 2019 16:27:54 +0000 (16:27 +0000)
committerFrançois Dumont <fdumont@gcc.gnu.org>
Fri, 17 May 2019 16:27:54 +0000 (16:27 +0000)
* include/bits/stl_deque.h
(_Deque_iterator<>::__ptr_to): Remove, use std::__ptr_rebind.
(_Deque_base(_Deque_base&&, const allocator_type&)): New.
(_Deque_base::_Deque_impl_data): New.
(_Deque_base::_Deque_impl): Inherit latter.
(_Deque_base::_Deque_impl::_M_swap_data): Move...
(_Deque_base::_Deque_impl_data::_M_swap_data): ... here.
(_Deque_base::_Deque_impl()): Add noexcept qualification.
(_Deque_base::_Deque_impl(_Deque_impl&&, _Tp_alloc_type&&)): New.
(_Deque_base::_Deque_impl::_M_get_Tp_allocator()): Remove static_cast.
(deque<>::deque()): Default.
(deque<>::deque(deque&&)): Default.
(deque<>::deque(deque&&, const allocator_type&, false_type)): New.
(deque<>::deque(deque&&, const allocator_type&, true_type)): New.
(deque<>::deque(deque&&, const allocator_type&)): Delegate to latters.
(deque<>::deque<_It>(_It, _It, const allocator_type&)): Use
_M_range_initialize.
(deque<>::assign<_It>(_It, _It)): Use _M_assign_aux.
(deque<>::resize(size_type, const value_type&)): Share a single
implementation.
(deque<>::insert<_It>(const_iterator, _It, _It)): Use
_M_range_insert_aux.
[__cplusplus >= 201103L](_M_initialize_dispatch): Remove.
[__cplusplus >= 201103L](_M_assign_dispatch): Remove.
[__cplusplus >= 201103L](_M_insert_dispatch): Remove.
* testsuite/23_containers/deque/allocator/default_init.cc: New.

From-SVN: r271330

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/deque.tcc
libstdc++-v3/include/bits/stl_deque.h
libstdc++-v3/testsuite/23_containers/deque/allocator/default_init.cc [new file with mode: 0644]

index d310cb0..dbf1a88 100644 (file)
@@ -1,3 +1,32 @@
+2019-05-17  François Dumont  <fdumont@gcc.gnu.org>
+
+       * include/bits/stl_deque.h
+       (_Deque_iterator<>::__ptr_to): Remove, use std::__ptr_rebind.
+       (_Deque_base(_Deque_base&&, const allocator_type&)): New.
+       (_Deque_base::_Deque_impl_data): New.
+       (_Deque_base::_Deque_impl): Inherit latter.
+       (_Deque_base::_Deque_impl::_M_swap_data): Move...
+       (_Deque_base::_Deque_impl_data::_M_swap_data): ... here.
+       (_Deque_base::_Deque_impl()): Add noexcept qualification.
+       (_Deque_base::_Deque_impl(_Deque_impl&&, _Tp_alloc_type&&)): New.
+       (_Deque_base::_Deque_impl::_M_get_Tp_allocator()): Remove static_cast.
+       (deque<>::deque()): Default.
+       (deque<>::deque(deque&&)): Default.
+       (deque<>::deque(deque&&, const allocator_type&, false_type)): New.
+       (deque<>::deque(deque&&, const allocator_type&, true_type)): New.
+       (deque<>::deque(deque&&, const allocator_type&)): Delegate to latters.
+       (deque<>::deque<_It>(_It, _It, const allocator_type&)): Use
+       _M_range_initialize.
+       (deque<>::assign<_It>(_It, _It)): Use _M_assign_aux.
+       (deque<>::resize(size_type, const value_type&)): Share a single
+       implementation.
+       (deque<>::insert<_It>(const_iterator, _It, _It)): Use
+       _M_range_insert_aux.
+       [__cplusplus >= 201103L](_M_initialize_dispatch): Remove.
+       [__cplusplus >= 201103L](_M_assign_dispatch): Remove.
+       [__cplusplus >= 201103L](_M_insert_dispatch): Remove.
+       * testsuite/23_containers/deque/allocator/default_init.cc: New.
+
 2019-05-17  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/90246
index 9679ec0..3f77b4f 100644 (file)
@@ -69,22 +69,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     {
       _Map_pointer __cur;
       __try
-        {
-          for (__cur = this->_M_impl._M_start._M_node;
+       {
+         for (__cur = this->_M_impl._M_start._M_node;
               __cur < this->_M_impl._M_finish._M_node;
               ++__cur)
-            std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(),
+           std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(),
                                           _M_get_Tp_allocator());
-          std::__uninitialized_default_a(this->_M_impl._M_finish._M_first,
+         std::__uninitialized_default_a(this->_M_impl._M_finish._M_first,
                                         this->_M_impl._M_finish._M_cur,
                                         _M_get_Tp_allocator());
-        }
+       }
       __catch(...)
-        {
-          std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
+       {
+         std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
                        _M_get_Tp_allocator());
-          __throw_exception_again;
-        }
+         __throw_exception_again;
+       }
     }
 #endif
 
@@ -99,8 +99,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          if (_Alloc_traits::_S_propagate_on_copy_assign())
            {
              if (!_Alloc_traits::_S_always_equal()
-                 && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
-               {
+                 && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
+               {
                  // Replacement allocator cannot free existing storage,
                  // so deallocate everything and take copy of __x's data.
                  _M_replace_map(__x, __x.get_allocator());
@@ -141,8 +141,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
          {
            _Alloc_traits::construct(this->_M_impl,
-                                    this->_M_impl._M_start._M_cur - 1,
-                                    std::forward<_Args>(__args)...);
+                                    this->_M_impl._M_start._M_cur - 1,
+                                    std::forward<_Args>(__args)...);
            --this->_M_impl._M_start._M_cur;
          }
        else
@@ -166,8 +166,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            != this->_M_impl._M_finish._M_last - 1)
          {
            _Alloc_traits::construct(this->_M_impl,
-                                    this->_M_impl._M_finish._M_cur,
-                                    std::forward<_Args>(__args)...);
+                                    this->_M_impl._M_finish._M_cur,
+                                    std::forward<_Args>(__args)...);
            ++this->_M_impl._M_finish._M_cur;
          }
        else
@@ -290,13 +290,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _M_assign_aux(_InputIterator __first, _InputIterator __last,
                    std::input_iterator_tag)
       {
-        iterator __cur = begin();
-        for (; __first != __last && __cur != end(); ++__cur, (void)++__first)
-          *__cur = *__first;
-        if (__first == __last)
-          _M_erase_at_end(__cur);
-        else
-          _M_range_insert_aux(end(), __first, __last,
+       iterator __cur = begin();
+       for (; __first != __last && __cur != end(); ++__cur, (void)++__first)
+         *__cur = *__first;
+       if (__first == __last)
+         _M_erase_at_end(__cur);
+       else
+         _M_range_insert_aux(end(), __first, __last,
                              std::__iterator_category(__first));
       }
 
@@ -339,7 +339,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            }
        }
       else
-        _M_insert_aux(__pos, __n, __x);
+       _M_insert_aux(__pos, __n, __x);
     }
 
 #if __cplusplus >= 201103L
@@ -393,22 +393,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     {
       _Map_pointer __cur;
       __try
-        {
-          for (__cur = this->_M_impl._M_start._M_node;
+       {
+         for (__cur = this->_M_impl._M_start._M_node;
               __cur < this->_M_impl._M_finish._M_node;
               ++__cur)
-            std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
+           std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
                                        __value, _M_get_Tp_allocator());
-          std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
+         std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
                                      this->_M_impl._M_finish._M_cur,
                                      __value, _M_get_Tp_allocator());
-        }
+       }
       __catch(...)
-        {
-          std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
+       {
+         std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
                        _M_get_Tp_allocator());
-          __throw_exception_again;
-        }
+         __throw_exception_again;
+       }
     }
 
   template <typename _Tp, typename _Alloc>
@@ -416,23 +416,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       void
       deque<_Tp, _Alloc>::
       _M_range_initialize(_InputIterator __first, _InputIterator __last,
-                          std::input_iterator_tag)
+                         std::input_iterator_tag)
       {
-        this->_M_initialize_map(0);
-        __try
-          {
-            for (; __first != __last; ++__first)
+       this->_M_initialize_map(0);
+       __try
+         {
+           for (; __first != __last; ++__first)
 #if __cplusplus >= 201103L
              emplace_back(*__first);
 #else
-              push_back(*__first);
+             push_back(*__first);
 #endif
-          }
-        __catch(...)
-          {
-            clear();
-            __throw_exception_again;
-          }
+         }
+       __catch(...)
+         {
+           clear();
+           __throw_exception_again;
+         }
       }
 
   template <typename _Tp, typename _Alloc>
@@ -440,17 +440,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       void
       deque<_Tp, _Alloc>::
       _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
-                          std::forward_iterator_tag)
+                         std::forward_iterator_tag)
       {
-        const size_type __n = std::distance(__first, __last);
-        this->_M_initialize_map(_S_check_init_len(__n, _M_get_Tp_allocator()));
-
-        _Map_pointer __cur_node;
-        __try
-          {
-            for (__cur_node = this->_M_impl._M_start._M_node;
-                 __cur_node < this->_M_impl._M_finish._M_node;
-                 ++__cur_node)
+       const size_type __n = std::distance(__first, __last);
+       this->_M_initialize_map(_S_check_init_len(__n, _M_get_Tp_allocator()));
+
+       _Map_pointer __cur_node;
+       __try
+         {
+           for (__cur_node = this->_M_impl._M_start._M_node;
+                __cur_node < this->_M_impl._M_finish._M_node;
+                ++__cur_node)
              {
                _ForwardIterator __mid = __first;
                std::advance(__mid, _S_buffer_size());
@@ -458,17 +458,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                                            _M_get_Tp_allocator());
                __first = __mid;
              }
-            std::__uninitialized_copy_a(__first, __last,
+           std::__uninitialized_copy_a(__first, __last,
                                        this->_M_impl._M_finish._M_first,
                                        _M_get_Tp_allocator());
-          }
-        __catch(...)
-          {
-            std::_Destroy(this->_M_impl._M_start,
+         }
+       __catch(...)
+         {
+           std::_Destroy(this->_M_impl._M_start,
                          iterator(*__cur_node, __cur_node),
                          _M_get_Tp_allocator());
-            __throw_exception_again;
-          }
+           __throw_exception_again;
+         }
       }
 
   // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1.
@@ -494,8 +494,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          {
 #if __cplusplus >= 201103L
            _Alloc_traits::construct(this->_M_impl,
-                                    this->_M_impl._M_finish._M_cur,
-                                    std::forward<_Args>(__args)...);
+                                    this->_M_impl._M_finish._M_cur,
+                                    std::forward<_Args>(__args)...);
 #else
            this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t);
 #endif
@@ -536,8 +536,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
 #if __cplusplus >= 201103L
            _Alloc_traits::construct(this->_M_impl,
-                                    this->_M_impl._M_start._M_cur,
-                                    std::forward<_Args>(__args)...);
+                                    this->_M_impl._M_start._M_cur,
+                                    std::forward<_Args>(__args)...);
 #else
            this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t);
 #endif
@@ -583,8 +583,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       void
       deque<_Tp, _Alloc>::
       _M_range_insert_aux(iterator __pos,
-                          _InputIterator __first, _InputIterator __last,
-                          std::input_iterator_tag)
+                         _InputIterator __first, _InputIterator __last,
+                         std::input_iterator_tag)
       { std::copy(__first, __last, std::inserter(*this, __pos)); }
 
   template <typename _Tp, typename _Alloc>
@@ -592,11 +592,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       void
       deque<_Tp, _Alloc>::
       _M_range_insert_aux(iterator __pos,
-                          _ForwardIterator __first, _ForwardIterator __last,
-                          std::forward_iterator_tag)
+                         _ForwardIterator __first, _ForwardIterator __last,
+                         std::forward_iterator_tag)
       {
-        const size_type __n = std::distance(__first, __last);
-        if (__pos._M_cur == this->_M_impl._M_start._M_cur)
+       const size_type __n = std::distance(__first, __last);
+       if (__pos._M_cur == this->_M_impl._M_start._M_cur)
          {
            iterator __new_start = _M_reserve_elements_at_front(__n);
            __try
@@ -612,7 +612,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                __throw_exception_again;
              }
          }
-        else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
+       else if (__pos._M_cur == this->_M_impl._M_finish._M_cur)
          {
            iterator __new_finish = _M_reserve_elements_at_back(__n);
            __try
@@ -629,8 +629,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                __throw_exception_again;
              }
          }
-        else
-          _M_insert_aux(__pos, __first, __last, __n);
+       else
+         _M_insert_aux(__pos, __first, __last, __n);
       }
 
   template<typename _Tp, typename _Alloc>
@@ -765,12 +765,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       void
       deque<_Tp, _Alloc>::
       _M_insert_aux(iterator __pos,
-                    _ForwardIterator __first, _ForwardIterator __last,
-                    size_type __n)
+                   _ForwardIterator __first, _ForwardIterator __last,
+                   size_type __n)
       {
-        const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
-        const size_type __length = size();
-        if (static_cast<size_type>(__elemsbefore) < __length / 2)
+       const difference_type __elemsbefore = __pos - this->_M_impl._M_start;
+       const size_type __length = size();
+       if (static_cast<size_type>(__elemsbefore) < __length / 2)
          {
            iterator __new_start = _M_reserve_elements_at_front(__n);
            iterator __old_start = this->_M_impl._M_start;
@@ -807,16 +807,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                __throw_exception_again;
              }
          }
-        else
-        {
-          iterator __new_finish = _M_reserve_elements_at_back(__n);
-          iterator __old_finish = this->_M_impl._M_finish;
-          const difference_type __elemsafter =
-            difference_type(__length) - __elemsbefore;
-          __pos = this->_M_impl._M_finish - __elemsafter;
-          __try
-            {
-              if (__elemsafter > difference_type(__n))
+       else
+       {
+         iterator __new_finish = _M_reserve_elements_at_back(__n);
+         iterator __old_finish = this->_M_impl._M_finish;
+         const difference_type __elemsafter =
+           difference_type(__length) - __elemsbefore;
+         __pos = this->_M_impl._M_finish - __elemsafter;
+         __try
+           {
+             if (__elemsafter > difference_type(__n))
                {
                  iterator __finish_n = (this->_M_impl._M_finish
                                         - difference_type(__n));
@@ -828,7 +828,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                  _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish);
                  std::copy(__first, __last, __pos);
                }
-              else
+             else
                {
                  _ForwardIterator __mid = __first;
                  std::advance(__mid, __elemsafter);
@@ -839,14 +839,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                  this->_M_impl._M_finish = __new_finish;
                  std::copy(__first, __mid, __pos);
                }
-            }
-          __catch(...)
-            {
-              _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
+           }
+         __catch(...)
+           {
+             _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1,
                               __new_finish._M_node + 1);
-              __throw_exception_again;
-            }
-        }
+             __throw_exception_again;
+           }
+       }
       }
 
    template<typename _Tp, typename _Alloc>
@@ -884,16 +884,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _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();
-        }
+       {
+         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;
-        }
+       {
+         for (size_type __j = 1; __j < __i; ++__j)
+           _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j));
+         __throw_exception_again;
+       }
     }
 
   template <typename _Tp, typename _Alloc>
@@ -909,16 +909,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _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();
-        }
+       {
+         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;
-        }
+       {
+         for (size_type __j = 1; __j < __i; ++__j)
+           _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j));
+         __throw_exception_again;
+       }
     }
 
   template <typename _Tp, typename _Alloc>
@@ -935,7 +935,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        {
          __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size
                                         - __new_num_nodes) / 2
-                        + (__add_at_front ? __nodes_to_add : 0);
+                        + (__add_at_front ? __nodes_to_add : 0);
          if (__new_nstart < this->_M_impl._M_start._M_node)
            std::copy(this->_M_impl._M_start._M_node,
                      this->_M_impl._M_finish._M_node + 1,
@@ -948,12 +948,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       else
        {
          size_type __new_map_size = this->_M_impl._M_map_size
-                                    + std::max(this->_M_impl._M_map_size,
+                                    + std::max(this->_M_impl._M_map_size,
                                                __nodes_to_add) + 2;
 
          _Map_pointer __new_map = this->_M_allocate_map(__new_map_size);
          __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
-                        + (__add_at_front ? __nodes_to_add : 0);
+                        + (__add_at_front ? __nodes_to_add : 0);
          std::copy(this->_M_impl._M_start._M_node,
                    this->_M_impl._M_finish._M_node + 1,
                    __new_nstart);
index d0b46c6..7dcb538 100644 (file)
@@ -110,21 +110,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     struct _Deque_iterator
     {
 #if __cplusplus < 201103L
-      typedef _Deque_iterator<_Tp, _Tp&, _Tp*>      iterator;
+      typedef _Deque_iterator<_Tp, _Tp&, _Tp*>            iterator;
       typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
-      typedef _Tp*                                      _Elt_pointer;
-      typedef _Tp**                                    _Map_pointer;
+      typedef _Tp*                                        _Elt_pointer;
+      typedef _Tp**                                       _Map_pointer;
 #else
     private:
-      template<typename _Up>
-       using __ptr_to = typename pointer_traits<_Ptr>::template rebind<_Up>;
       template<typename _CvTp>
-       using __iter = _Deque_iterator<_Tp, _CvTp&, __ptr_to<_CvTp>>;
+       using __iter = _Deque_iterator<_Tp, _CvTp&, __ptr_rebind<_Ptr, _CvTp>>;
     public:
-      typedef __iter<_Tp>              iterator;
-      typedef __iter<const _Tp>                const_iterator;
-      typedef __ptr_to<_Tp>            _Elt_pointer;
-      typedef __ptr_to<_Elt_pointer>   _Map_pointer;
+      typedef __iter<_Tp>                                 iterator;
+      typedef __iter<const _Tp>                                   const_iterator;
+      typedef __ptr_rebind<_Ptr, _Tp>                     _Elt_pointer;
+      typedef __ptr_rebind<_Ptr, _Elt_pointer>            _Map_pointer;
 #endif
 
       static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT
@@ -158,11 +156,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #else
       // Conversion from iterator to const_iterator.
       template<typename _Iter,
-              typename = _Require<is_same<_Self, const_iterator>,
-                                  is_same<_Iter, iterator>>>
+             typename = _Require<is_same<_Self, const_iterator>,
+                                 is_same<_Iter, iterator>>>
        _Deque_iterator(const _Iter& __x) noexcept
        : _M_cur(__x._M_cur), _M_first(__x._M_first),
-         _M_last(__x._M_last), _M_node(__x._M_node) { }
+        _M_last(__x._M_last), _M_node(__x._M_node) { }
 
       _Deque_iterator(const _Deque_iterator&) = default;
       _Deque_iterator& operator=(const _Deque_iterator&) = default;
@@ -473,7 +471,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        _Map_alloc_type;
       typedef __gnu_cxx::__alloc_traits<_Map_alloc_type> _Map_alloc_traits;
 
-    public:
       typedef _Alloc             allocator_type;
 
       allocator_type
@@ -508,6 +505,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          this->_M_impl._M_swap_data(__x._M_impl);
       }
 
+      _Deque_base(_Deque_base&& __x, const allocator_type& __a)
+      : _M_impl(std::move(__x._M_impl), _Tp_alloc_type(__a))
+      { __x._M_initialize_map(0); }
+
       _Deque_base(_Deque_base&& __x, const allocator_type& __a, size_t __n)
       : _M_impl(__a)
       {
@@ -528,56 +529,73 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       ~_Deque_base() _GLIBCXX_NOEXCEPT;
 
-    protected:
       typedef typename iterator::_Map_pointer _Map_pointer;
 
-      //This struct encapsulates the implementation of the std::deque
-      //standard container and at the same time makes use of the EBO
-      //for empty allocators.
-      struct _Deque_impl
-      : public _Tp_alloc_type
+      struct _Deque_impl_data
       {
        _Map_pointer _M_map;
        size_t _M_map_size;
        iterator _M_start;
        iterator _M_finish;
 
-       _Deque_impl()
-       : _Tp_alloc_type(), _M_map(), _M_map_size(0),
-         _M_start(), _M_finish()
+       _Deque_impl_data() _GLIBCXX_NOEXCEPT
+       : _M_map(), _M_map_size(), _M_start(), _M_finish()
+       { }
+
+#if __cplusplus >= 201103L
+       _Deque_impl_data(const _Deque_impl_data&) = default;
+       _Deque_impl_data&
+       operator=(const _Deque_impl_data&) = default;
+
+       _Deque_impl_data(_Deque_impl_data&& __x) noexcept
+       : _Deque_impl_data(__x)
+       { __x = _Deque_impl_data(); }
+#endif
+
+       void
+       _M_swap_data(_Deque_impl_data& __x) _GLIBCXX_NOEXCEPT
+       {
+         // Do not use std::swap(_M_start, __x._M_start), etc as it loses
+         // information used by TBAA.
+         std::swap(*this, __x);
+       }
+      };
+
+      // This struct encapsulates the implementation of the std::deque
+      // standard container and at the same time makes use of the EBO
+      // for empty allocators.
+      struct _Deque_impl
+      : public _Tp_alloc_type, public _Deque_impl_data
+      {
+       _Deque_impl() _GLIBCXX_NOEXCEPT_IF(
+         is_nothrow_default_constructible<_Tp_alloc_type>::value)
+       : _Tp_alloc_type()
        { }
 
        _Deque_impl(const _Tp_alloc_type& __a) _GLIBCXX_NOEXCEPT
-       : _Tp_alloc_type(__a), _M_map(), _M_map_size(0),
-         _M_start(), _M_finish()
+       : _Tp_alloc_type(__a)
        { }
 
 #if __cplusplus >= 201103L
        _Deque_impl(_Deque_impl&&) = default;
 
        _Deque_impl(_Tp_alloc_type&& __a) noexcept
-       : _Tp_alloc_type(std::move(__a)), _M_map(), _M_map_size(0),
-         _M_start(), _M_finish()
+       : _Tp_alloc_type(std::move(__a))
        { }
-#endif
 
-       void _M_swap_data(_Deque_impl& __x) _GLIBCXX_NOEXCEPT
-       {
-         using std::swap;
-         swap(this->_M_start, __x._M_start);
-         swap(this->_M_finish, __x._M_finish);
-         swap(this->_M_map, __x._M_map);
-         swap(this->_M_map_size, __x._M_map_size);
-       }
+       _Deque_impl(_Deque_impl&& __d, _Tp_alloc_type&& __a)
+       : _Tp_alloc_type(std::move(__a)), _Deque_impl_data(std::move(__d))
+       { }
+#endif
       };
 
       _Tp_alloc_type&
       _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT
-      { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); }
+      { return this->_M_impl; }
 
       const _Tp_alloc_type&
       _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT
-      { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); }
+      { return this->_M_impl; }
 
       _Map_alloc_type
       _M_get_map_allocator() const _GLIBCXX_NOEXCEPT
@@ -611,7 +629,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        _Map_alloc_traits::deallocate(__map_alloc, __p, __n);
       }
 
-    protected:
       void _M_initialize_map(size_t);
       void _M_create_nodes(_Map_pointer __nstart, _Map_pointer __nfinish);
       void _M_destroy_nodes(_Map_pointer __nstart,
@@ -646,7 +663,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     _Deque_base<_Tp, _Alloc>::
     _M_initialize_map(size_t __num_elements)
     {
-      const size_t __num_nodes = (__num_elements/ __deque_buf_size(sizeof(_Tp))
+      const size_t __num_nodes = (__num_elements / __deque_buf_size(sizeof(_Tp))
                                  + 1);
 
       this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size,
@@ -832,7 +849,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       typedef ptrdiff_t                                        difference_type;
       typedef _Alloc                                   allocator_type;
 
-    protected:
+    private:
       static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT
       { return __deque_buf_size(sizeof(_Tp)); }
 
@@ -859,7 +876,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /**
        *  @brief  Creates a %deque with no elements.
        */
-      deque() : _Base() { }
+#if __cplusplus >= 201103L
+      deque() = default;
+#else
+      deque() { }
+#endif
 
       /**
        *  @brief  Creates a %deque with no elements.
@@ -928,13 +949,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #if __cplusplus >= 201103L
       /**
        *  @brief  %Deque move constructor.
-       *  @param  __x  A %deque of identical element and allocator types.
        *
-       *  The newly-created %deque contains the exact contents of @a __x.
-       *  The contents of @a __x are a valid, but unspecified %deque.
+       *  The newly-created %deque contains the exact contents of the
+       *  moved instance.
+       *  The contents of the moved instance are a valid, but unspecified
+       *  %deque.
        */
-      deque(deque&& __x)
-      : _Base(std::move(__x)) { }
+      deque(deque&&) = default;
 
       /// Copy constructor with alternative allocator
       deque(const deque& __x, const allocator_type& __a)
@@ -945,9 +966,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       /// Move constructor with alternative allocator
       deque(deque&& __x, const allocator_type& __a)
+      : deque(std::move(__x), __a, typename _Alloc_traits::is_always_equal{})
+      { }
+
+    private:
+      deque(deque&& __x, const allocator_type& __a, true_type)
+      : _Base(std::move(__x), __a)
+      { }
+
+      deque(deque&& __x, const allocator_type& __a, false_type)
       : _Base(std::move(__x), __a, __x.size())
       {
-       if (__x.get_allocator() != __a)
+       if (__x.get_allocator() != __a && !__x.empty())
          {
            std::__uninitialized_move_a(__x.begin(), __x.end(),
                                        this->_M_impl._M_start,
@@ -956,6 +986,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          }
       }
 
+    public:
       /**
        *  @brief  Builds a %deque from an initializer list.
        *  @param  __l  An initializer_list.
@@ -997,7 +1028,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        deque(_InputIterator __first, _InputIterator __last,
              const allocator_type& __a = allocator_type())
        : _Base(__a)
-       { _M_initialize_dispatch(__first, __last, __false_type()); }
+       {
+         _M_range_initialize(__first, __last,
+                             std::__iterator_category(__first));
+       }
 #else
       template<typename _InputIterator>
        deque(_InputIterator __first, _InputIterator __last,
@@ -1098,7 +1132,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
               typename = std::_RequireInputIter<_InputIterator>>
        void
        assign(_InputIterator __first, _InputIterator __last)
-       { _M_assign_dispatch(__first, __last, __false_type()); }
+       { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
 #else
       template<typename _InputIterator>
        void
@@ -1284,14 +1318,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       void
       resize(size_type __new_size, const value_type& __x)
-      {
-       const size_type __len = size();
-       if (__new_size > __len)
-         _M_fill_insert(this->_M_impl._M_finish, __new_size - __len, __x);
-       else if (__new_size < __len)
-         _M_erase_at_end(this->_M_impl._M_start
-                         + difference_type(__new_size));
-      }
 #else
       /**
        *  @brief  Resizes the %deque to the specified number of elements.
@@ -1306,6 +1332,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       void
       resize(size_type __new_size, value_type __x = value_type())
+#endif
       {
        const size_type __len = size();
        if (__new_size > __len)
@@ -1314,7 +1341,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          _M_erase_at_end(this->_M_impl._M_start
                          + difference_type(__new_size));
       }
-#endif
 
 #if __cplusplus >= 201103L
       /**  A non-binding request to reduce memory use.  */
@@ -1555,7 +1581,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        if (this->_M_impl._M_start._M_cur
            != this->_M_impl._M_start._M_last - 1)
          {
-           _Alloc_traits::destroy(this->_M_impl,
+           _Alloc_traits::destroy(_M_get_Tp_allocator(),
                                   this->_M_impl._M_start._M_cur);
            ++this->_M_impl._M_start._M_cur;
          }
@@ -1579,7 +1605,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            != this->_M_impl._M_finish._M_first)
          {
            --this->_M_impl._M_finish._M_cur;
-           _Alloc_traits::destroy(this->_M_impl,
+           _Alloc_traits::destroy(_M_get_Tp_allocator(),
                                   this->_M_impl._M_finish._M_cur);
          }
        else
@@ -1643,6 +1669,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  @brief  Inserts an initializer list into the %deque.
        *  @param  __p  An iterator into the %deque.
        *  @param  __l  An initializer_list.
+       *  @return  An iterator that points to the inserted data.
        *
        *  This function will insert copies of the data in the
        *  initializer_list @a __l into the %deque before the location
@@ -1656,9 +1683,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                            std::random_access_iterator_tag());
        return begin() + __offset;
       }
-#endif
 
-#if __cplusplus >= 201103L
       /**
        *  @brief  Inserts a number of copies of given data into the %deque.
        *  @param  __position  A const_iterator into the %deque.
@@ -1710,8 +1735,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
               _InputIterator __last)
        {
          difference_type __offset = __position - cbegin();
-         _M_insert_dispatch(__position._M_const_cast(),
-                            __first, __last, __false_type());
+         _M_range_insert_aux(__position._M_const_cast(), __first, __last,
+                             std::__iterator_category(__first));
          return begin() + __offset;
        }
 #else
@@ -1817,6 +1842,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     protected:
       // Internal constructor functions follow.
 
+#if __cplusplus < 201103L
       // called by the range constructor to implement [23.1.1]/9
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -1830,6 +1856,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          _M_fill_initialize(__x);
        }
 
+      // called by the range constructor to implement [23.1.1]/9
+      template<typename _InputIterator>
+       void
+       _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+                              __false_type)
+       {
+         _M_range_initialize(__first, __last,
+                             std::__iterator_category(__first));
+       }
+#endif
+
       static size_t
       _S_check_init_len(size_t __n, const allocator_type& __a)
       {
@@ -1847,16 +1884,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        return (std::min)(__diffmax, __allocmax);
       }
 
-      // called by the range constructor to implement [23.1.1]/9
-      template<typename _InputIterator>
-       void
-       _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
-                              __false_type)
-       {
-         _M_range_initialize(__first, __last,
-                             std::__iterator_category(__first));
-       }
-
       // called by the second initialize_dispatch above
       //@{
       /**
@@ -1903,6 +1930,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       // Internal assign functions follow.  The *_aux functions do the actual
       // assignment work for the range versions.
 
+#if __cplusplus < 201103L
       // called by the range assign to implement [23.1.1]/9
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -1918,6 +1946,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
                           __false_type)
        { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
+#endif
 
       // called by the second assign_dispatch above
       template<typename _InputIterator>
@@ -1983,6 +2012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       // Internal insert functions follow.  The *_aux functions do the actual
       // insertion work when all shortcuts fail.
 
+#if __cplusplus < 201103L
       // called by the range insert to implement [23.1.1]/9
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -2003,6 +2033,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          _M_range_insert_aux(__pos, __first, __last,
                              std::__iterator_category(__first));
        }
+#endif
 
       // called by the second insert_dispatch above
       template<typename _InputIterator>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/allocator/default_init.cc b/libstdc++-v3/testsuite/23_containers/deque/allocator/default_init.cc
new file mode 100644 (file)
index 0000000..f6cc61e
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (C) 2019 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/>.
+
+// { dg-do run { target c++11 } }
+// { dg-options "-O0" }
+// { dg-xfail-run-if "PR c++/65816" { *-*-* } }
+
+#include <deque>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+#include <ext/aligned_buffer.h>
+
+using T = int;
+
+using __gnu_test::default_init_allocator;
+
+void test01()
+{
+  typedef default_init_allocator<T> alloc_type;
+  typedef std::deque<T, alloc_type> test_type;
+
+  __gnu_cxx::__aligned_buffer<test_type> buf;
+  __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+
+  test_type *tmp = ::new(buf._M_addr()) test_type;
+
+  VERIFY( tmp->get_allocator().state == 0 );
+
+  tmp->~test_type();
+}
+
+void test02()
+{
+  typedef default_init_allocator<T> alloc_type;
+  typedef std::deque<T, alloc_type> test_type;
+
+  __gnu_cxx::__aligned_buffer<test_type> buf;
+  __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+
+  test_type *tmp = ::new(buf._M_addr()) test_type();
+
+  VERIFY( tmp->get_allocator().state == 0 );
+
+  tmp->~test_type();
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}