stl_bvector.h (__fill_bvector(_Bit_type*, unsigned int, unsigned int, bool)): Change...
authorFrançois Dumont <fdumont@gcc.gnu.org>
Fri, 16 Jun 2017 05:28:06 +0000 (05:28 +0000)
committerFrançois Dumont <fdumont@gcc.gnu.org>
Fri, 16 Jun 2017 05:28:06 +0000 (05:28 +0000)
2017-06-16  François Dumont  <fdumont@gcc.gnu.org>

* include/bits/stl_bvector.h
(__fill_bvector(_Bit_type*, unsigned int, unsigned int, bool)):
Change signature.
(std::fill(_Bit_iterator, _Bit_iterator, bool)): Adapt.
(_Bvector_impl_data): New.
(_Bvector_impl): Inherits from latter.
(_Bvector_impl(_Bit_alloc_type&&)): Delete.
(_Bvector_impl(_Bvector_impl&&)): New, default.
(_Bvector_base()): Default.
(_Bvector_base(_Bvector_base&&)): Default.
(_Bvector_base::_M_move_data(_Bvector_base&&)): New.
(vector(vector&&, const allocator_type&)): Use latter.
(vector<bool>::operator=(vector&&)): Likewise.
(vector<bool>::vector()): Default.
(vector<bool>::vector(vector&&)): Default.
(vector<bool>::assign(_InputIterator, _InputIterator)): Use
_M_assign_aux.
(vector<bool>::assign(initializer_list<bool>)): Likewise.
(vector<bool>::_M_initialize_value(bool)): New.
(vector<bool>(size_type, const bool&, const allocator_type&)): Use
latter.
(vector<bool>::_M_initialize_dispatch(_Integer, _Integer, __true_type)):
Likewise.
(vector<bool>::_M_fill_assign(size_t, bool)): Likewise.

From-SVN: r249235

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

index ceb4811ff35d8baf0ce228ca583f19c4a631f734..26b3075143d224929f8b0ed4669fd16e96eba88e 100644 (file)
@@ -1,3 +1,30 @@
+2017-06-16  François Dumont  <fdumont@gcc.gnu.org>
+
+       * include/bits/stl_bvector.h
+       (__fill_bvector(_Bit_type*, unsigned int, unsigned int, bool)):
+       Change signature.
+       (std::fill(_Bit_iterator, _Bit_iterator, bool)): Adapt.
+       (_Bvector_impl_data): New.
+       (_Bvector_impl): Inherits from latter.
+       (_Bvector_impl(_Bit_alloc_type&&)): Delete.
+       (_Bvector_impl(_Bvector_impl&&)): New, default.
+       (_Bvector_base()): Default.
+       (_Bvector_base(_Bvector_base&&)): Default.
+       (_Bvector_base::_M_move_data(_Bvector_base&&)): New.
+       (vector(vector&&, const allocator_type&)): Use latter.
+       (vector<bool>::operator=(vector&&)): Likewise.
+       (vector<bool>::vector()): Default.
+       (vector<bool>::vector(vector&&)): Default.
+       (vector<bool>::assign(_InputIterator, _InputIterator)): Use
+       _M_assign_aux.
+       (vector<bool>::assign(initializer_list<bool>)): Likewise.
+       (vector<bool>::_M_initialize_value(bool)): New.
+       (vector<bool>(size_type, const bool&, const allocator_type&)): Use
+       latter.
+       (vector<bool>::_M_initialize_dispatch(_Integer, _Integer, __true_type)):
+       Likewise.
+       (vector<bool>::_M_fill_assign(size_t, bool)): Likewise.
+
 2017-06-15  François Dumont  <fdumont@gcc.gnu.org>
 
        * src/c++98/tree.cc  [!_GLIBCXX_INLINE_VERSION]
index 78195c1295deccf7e96d9a318ecb996fee3619a3..c9433d4f80f25159c1635ea14816a989f6865a0a 100644 (file)
@@ -184,7 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     operator<(const _Bit_iterator_base& __i) const
     {
       return _M_p < __i._M_p
-            || (_M_p == __i._M_p && _M_offset < __i._M_offset);
+           || (_M_p == __i._M_p && _M_offset < __i._M_offset);
     }
 
     bool
@@ -388,10 +388,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   { return __x + __n; }
 
   inline void
-  __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x)
+  __fill_bvector(_Bit_type * __v,
+                unsigned int __first, unsigned int __last, bool __x)
   {
-    for (; __first != __last; ++__first)
-      *__first = __x;
+    const _Bit_type __fmask = ~0ul << __first;
+    const _Bit_type __lmask = ~0ul >> (_S_word_bit - __last);
+    const _Bit_type __mask = __fmask & __lmask;
+
+    if (__x)
+      *__v |= __mask;
+    else
+      *__v &= ~__mask;
   }
 
   inline void
@@ -399,12 +406,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   {
     if (__first._M_p != __last._M_p)
       {
-       std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0);
-       __fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x);
-       __fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x);
+       _Bit_type *__first_p = __first._M_p;
+       if (__first._M_offset != 0)
+         __fill_bvector(__first_p++, __first._M_offset, _S_word_bit, __x);
+
+       __builtin_memset(__first_p, __x ? ~0 : 0,
+                        (__last._M_p - __first_p) * sizeof(_Bit_type));
+
+       if (__last._M_offset != 0)
+         __fill_bvector(__last._M_p, 0, __last._M_offset, __x);
       }
     else
-      __fill_bvector(__first, __last, __x);
+      __fill_bvector(__first._M_p, __first._M_offset, __last._M_offset, __x);
   }
 
   template<typename _Alloc>
@@ -416,33 +429,62 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        _Bit_alloc_traits;
       typedef typename _Bit_alloc_traits::pointer _Bit_pointer;
 
-      struct _Bvector_impl
-      : public _Bit_alloc_type
+      struct _Bvector_impl_data
       {
        _Bit_iterator   _M_start;
        _Bit_iterator   _M_finish;
        _Bit_pointer    _M_end_of_storage;
 
-       _Bvector_impl()
-       : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage()
-       { }
-       _Bvector_impl(const _Bit_alloc_type& __a)
-       : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage()
+       _Bvector_impl_data() _GLIBCXX_NOEXCEPT
+       : _M_start(), _M_finish(), _M_end_of_storage()
        { }
 
 #if __cplusplus >= 201103L
-       _Bvector_impl(_Bit_alloc_type&& __a)
-       : _Bit_alloc_type(std::move(__a)), _M_start(), _M_finish(),
-         _M_end_of_storage()
-       { }
+       _Bvector_impl_data(_Bvector_impl_data&& __x) noexcept
+       : _M_start(__x._M_start), _M_finish(__x._M_finish)
+       , _M_end_of_storage(__x._M_end_of_storage)
+       { __x._M_reset(); }
+
+       void
+       _M_move_data(_Bvector_impl_data&& __x) noexcept
+       {
+         this->_M_start = __x._M_start;
+         this->_M_finish = __x._M_finish;
+         this->_M_end_of_storage = __x._M_end_of_storage;
+         __x._M_reset();
+       }
+#endif
+
+       void
+       _M_reset() _GLIBCXX_NOEXCEPT
+       {
+         _M_start = _M_finish = _Bit_iterator();
+         _M_end_of_storage = _Bit_pointer();
+       }
+      };
+
+      struct _Bvector_impl
+       : public _Bit_alloc_type, public _Bvector_impl_data
+       {
+       public:
+         _Bvector_impl()
+           _GLIBCXX_NOEXCEPT_IF( noexcept(_Bit_alloc_type()) )
+         : _Bit_alloc_type()
+         { }
+
+         _Bvector_impl(const _Bit_alloc_type& __a) _GLIBCXX_NOEXCEPT
+         : _Bit_alloc_type(__a)
+         { }
+
+#if __cplusplus >= 201103L
+       _Bvector_impl(_Bvector_impl&&) = default;
 #endif
 
        _Bit_type*
        _M_end_addr() const _GLIBCXX_NOEXCEPT
        {
-         if (_M_end_of_storage)
-           return std::__addressof(_M_end_of_storage[-1]) + 1;
+         if (this->_M_end_of_storage)
+           return std::__addressof(this->_M_end_of_storage[-1]) + 1;
          return 0;
        }
       };
@@ -452,33 +494,27 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       _Bit_alloc_type&
       _M_get_Bit_allocator() _GLIBCXX_NOEXCEPT
-      { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); }
+      { return this->_M_impl; }
 
       const _Bit_alloc_type&
       _M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT
-      { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); }
+      { return this->_M_impl; }
 
       allocator_type
       get_allocator() const _GLIBCXX_NOEXCEPT
       { return allocator_type(_M_get_Bit_allocator()); }
 
-      _Bvector_base()
-      : _M_impl() { }
+#if __cplusplus >= 201103L
+      _Bvector_base() = default;
+#else
+      _Bvector_base() { }
+#endif
       
       _Bvector_base(const allocator_type& __a)
       : _M_impl(__a) { }
 
 #if __cplusplus >= 201103L
-      _Bvector_base(_Bvector_base&& __x) noexcept
-      : _M_impl(std::move(__x._M_get_Bit_allocator()))
-      {
-       this->_M_impl._M_start = __x._M_impl._M_start;
-       this->_M_impl._M_finish = __x._M_impl._M_finish;
-       this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage;
-       __x._M_impl._M_start = _Bit_iterator();
-       __x._M_impl._M_finish = _Bit_iterator();
-       __x._M_impl._M_end_of_storage = nullptr;
-      }
+      _Bvector_base(_Bvector_base&&) = default;
 #endif
 
       ~_Bvector_base()
@@ -500,11 +536,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            _Bit_alloc_traits::deallocate(_M_impl,
                                          _M_impl._M_end_of_storage - __n,
                                          __n);
-           _M_impl._M_start = _M_impl._M_finish = _Bit_iterator();
-           _M_impl._M_end_of_storage = _Bit_pointer();
+           _M_impl._M_reset();
          }
       }
 
+#if __cplusplus >= 201103L
+      void
+      _M_move_data(_Bvector_base&& __x) noexcept
+      { _M_impl._M_move_data(std::move(__x._M_impl)); }
+#endif
+
       static size_t
       _S_nword(size_t __n)
       { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); }
@@ -539,738 +580,727 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
    *  memory and size allocation.  Subscripting ( @c [] ) access is
    *  also provided as with C-style arrays.
   */
-template<typename _Alloc>
-  class vector<bool, _Alloc> : protected _Bvector_base<_Alloc>
-  {
-    typedef _Bvector_base<_Alloc>                       _Base;
-    typedef typename _Base::_Bit_pointer                _Bit_pointer;
-    typedef typename _Base::_Bit_alloc_traits           _Bit_alloc_traits;
+  template<typename _Alloc>
+    class vector<bool, _Alloc> : protected _Bvector_base<_Alloc>
+    {
+      typedef _Bvector_base<_Alloc>                    _Base;
+      typedef typename _Base::_Bit_pointer             _Bit_pointer;
+      typedef typename _Base::_Bit_alloc_traits                _Bit_alloc_traits;
 
 #if __cplusplus >= 201103L
-    template<typename> friend struct hash;
+      template<typename> friend struct hash;
 #endif
 
-  public:
-    typedef bool                                         value_type;
-    typedef size_t                                       size_type;
-    typedef ptrdiff_t                                    difference_type;
-    typedef _Bit_reference                               reference;
-    typedef bool                                         const_reference;
-    typedef _Bit_reference*                              pointer;
-    typedef const bool*                                  const_pointer;
-    typedef _Bit_iterator                                iterator;
-    typedef _Bit_const_iterator                          const_iterator;
-    typedef std::reverse_iterator<const_iterator>        const_reverse_iterator;
-    typedef std::reverse_iterator<iterator>              reverse_iterator;
-    typedef _Alloc                                      allocator_type;
-
-    allocator_type get_allocator() const
-    { return _Base::get_allocator(); }
-
-  protected:
-    using _Base::_M_allocate;
-    using _Base::_M_deallocate;
-    using _Base::_S_nword;
-    using _Base::_M_get_Bit_allocator;
-
-  public:
-    vector()
-#if __cplusplus >= 201103L
-      noexcept(is_nothrow_default_constructible<allocator_type>::value)
-#endif
-    : _Base() { }
+    public:
+      typedef bool                                     value_type;
+      typedef size_t                                   size_type;
+      typedef ptrdiff_t                                        difference_type;
+      typedef _Bit_reference                           reference;
+      typedef bool                                     const_reference;
+      typedef _Bit_reference*                          pointer;
+      typedef const bool*                              const_pointer;
+      typedef _Bit_iterator                            iterator;
+      typedef _Bit_const_iterator                      const_iterator;
+      typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+      typedef std::reverse_iterator<iterator>          reverse_iterator;
+      typedef _Alloc                                   allocator_type;
 
-    explicit
-    vector(const allocator_type& __a)
-    : _Base(__a) { }
+      allocator_type
+      get_allocator() const
+      { return _Base::get_allocator(); }
+
+    protected:
+      using _Base::_M_allocate;
+      using _Base::_M_deallocate;
+      using _Base::_S_nword;
+      using _Base::_M_get_Bit_allocator;
 
+    public:
 #if __cplusplus >= 201103L
-    explicit
-    vector(size_type __n, const allocator_type& __a = allocator_type())
-    : vector(__n, false, __a)
-    { }
-
-    vector(size_type __n, const bool& __value, 
-          const allocator_type& __a = allocator_type())
-    : _Base(__a)
-    {
-      _M_initialize(__n);
-      std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_addr(),
-               __value ? ~0 : 0);
-    }
+      vector() = default;
 #else
-    explicit
-    vector(size_type __n, const bool& __value = bool(), 
-          const allocator_type& __a = allocator_type())
-    : _Base(__a)
-    {
-      _M_initialize(__n);
-      std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_addr(),
-               __value ? ~0 : 0);
-    }
+      vector() { }
 #endif
 
-    vector(const vector& __x)
-    : _Base(_Bit_alloc_traits::_S_select_on_copy(__x._M_get_Bit_allocator()))
-    {
-      _M_initialize(__x.size());
-      _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
-    }
+      explicit
+      vector(const allocator_type& __a)
+      : _Base(__a) { }
 
 #if __cplusplus >= 201103L
-    vector(vector&& __x) noexcept
-    : _Base(std::move(__x)) { }
-
-    vector(vector&& __x, const allocator_type& __a)
-    noexcept(_Bit_alloc_traits::_S_always_equal())
-    : _Base(__a)
-    {
-      if (__x.get_allocator() == __a)
-       {
-         this->_M_impl._M_start = __x._M_impl._M_start;
-         this->_M_impl._M_finish = __x._M_impl._M_finish;
-         this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage;
-         __x._M_impl._M_start = _Bit_iterator();
-         __x._M_impl._M_finish = _Bit_iterator();
-         __x._M_impl._M_end_of_storage = nullptr;
-       }
-      else
-       {
-         _M_initialize(__x.size());
-         _M_copy_aligned(__x.begin(), __x.end(), begin());
-         __x.clear();
-       }
-    }
-
-    vector(const vector& __x, const allocator_type& __a)
-    : _Base(__a)
-    {
-      _M_initialize(__x.size());
-      _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
-    }
+      explicit
+      vector(size_type __n, const allocator_type& __a = allocator_type())
+      : vector(__n, false, __a)
+      { }
 
-    vector(initializer_list<bool> __l,
-          const allocator_type& __a = allocator_type())
-    : _Base(__a)
-    {
-      _M_initialize_range(__l.begin(), __l.end(),
-                         random_access_iterator_tag());
-    }
+      vector(size_type __n, const bool& __value, 
+            const allocator_type& __a = allocator_type())
+#else
+      explicit
+      vector(size_type __n, const bool& __value = bool(), 
+            const allocator_type& __a = allocator_type())
 #endif
+      : _Base(__a)
+      {
+       _M_initialize(__n);
+       _M_initialize_value(__value);
+      }
+
+      vector(const vector& __x)
+      : _Base(_Bit_alloc_traits::_S_select_on_copy(__x._M_get_Bit_allocator()))
+      {
+       _M_initialize(__x.size());
+       _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
+      }
 
 #if __cplusplus >= 201103L
-    template<typename _InputIterator,
-            typename = std::_RequireInputIter<_InputIterator>>
-      vector(_InputIterator __first, _InputIterator __last,
-            const allocator_type& __a = allocator_type())
+      vector(vector&&) = default;
+
+      vector(vector&& __x, const allocator_type& __a)
+      noexcept(_Bit_alloc_traits::_S_always_equal())
       : _Base(__a)
-      { _M_initialize_dispatch(__first, __last, __false_type()); }
-#else
-    template<typename _InputIterator>
-      vector(_InputIterator __first, _InputIterator __last,
+      {
+       if (__x.get_allocator() == __a)
+         this->_M_move_data(std::move(__x));
+       else
+         {
+           _M_initialize(__x.size());
+           _M_copy_aligned(__x.begin(), __x.end(), begin());
+           __x.clear();
+         }
+      }
+
+      vector(const vector& __x, const allocator_type& __a)
+      : _Base(__a)
+      {
+       _M_initialize(__x.size());
+       _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
+      }
+
+      vector(initializer_list<bool> __l,
             const allocator_type& __a = allocator_type())
       : _Base(__a)
       {
-       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
-       _M_initialize_dispatch(__first, __last, _Integral());
+       _M_initialize_range(__l.begin(), __l.end(),
+                           random_access_iterator_tag());
       }
 #endif
 
-    ~vector() _GLIBCXX_NOEXCEPT { }
-
-    vector&
-    operator=(const vector& __x)
-    {
-      if (&__x == this)
-       return *this;
 #if __cplusplus >= 201103L
-      if (_Bit_alloc_traits::_S_propagate_on_copy_assign())
+      template<typename _InputIterator,
+              typename = std::_RequireInputIter<_InputIterator>>
+       vector(_InputIterator __first, _InputIterator __last,
+              const allocator_type& __a = allocator_type())
+       : _Base(__a)
+       { _M_initialize_dispatch(__first, __last, __false_type()); }
+#else
+      template<typename _InputIterator>
+       vector(_InputIterator __first, _InputIterator __last,
+              const allocator_type& __a = allocator_type())
+       : _Base(__a)
        {
-         if (this->_M_get_Bit_allocator() != __x._M_get_Bit_allocator())
-           {
-             this->_M_deallocate();
+         typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+         _M_initialize_dispatch(__first, __last, _Integral());
+       }
+#endif
+
+      ~vector() _GLIBCXX_NOEXCEPT { }
+
+      vector&
+      operator=(const vector& __x)
+      {
+       if (&__x == this)
+         return *this;
+#if __cplusplus >= 201103L
+       if (_Bit_alloc_traits::_S_propagate_on_copy_assign())
+         {
+           if (this->_M_get_Bit_allocator() != __x._M_get_Bit_allocator())
+             {
+               this->_M_deallocate();
+               std::__alloc_on_copy(_M_get_Bit_allocator(),
+                                    __x._M_get_Bit_allocator());
+               _M_initialize(__x.size());
+             }
+           else
              std::__alloc_on_copy(_M_get_Bit_allocator(),
                                   __x._M_get_Bit_allocator());
-             _M_initialize(__x.size());
-           }
-         else
-           std::__alloc_on_copy(_M_get_Bit_allocator(),
-                                __x._M_get_Bit_allocator());
-       }
+         }
 #endif
-      if (__x.size() > capacity())
-       {
-         this->_M_deallocate();
-         _M_initialize(__x.size());
-       }
-      this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
-                                               begin());
-      return *this;
-    }
+       if (__x.size() > capacity())
+         {
+           this->_M_deallocate();
+           _M_initialize(__x.size());
+         }
+       this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
+                                                 begin());
+       return *this;
+      }
 
 #if __cplusplus >= 201103L
-    vector&
-    operator=(vector&& __x) noexcept(_Bit_alloc_traits::_S_nothrow_move())
-    {
-      if (_Bit_alloc_traits::_S_propagate_on_move_assign()
-         || this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator())
-       {
-         this->_M_deallocate();
-         this->_M_impl._M_start = __x._M_impl._M_start;
-         this->_M_impl._M_finish = __x._M_impl._M_finish;
-         this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage;
-         __x._M_impl._M_start = _Bit_iterator();
-         __x._M_impl._M_finish = _Bit_iterator();
-         __x._M_impl._M_end_of_storage = nullptr;
-         std::__alloc_on_move(_M_get_Bit_allocator(),
-                              __x._M_get_Bit_allocator());
-       }
-      else
-       {
-         if (__x.size() > capacity())
-           {
-             this->_M_deallocate();
-             _M_initialize(__x.size());
-           }
-         this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
-                                                   begin());
-         __x.clear();
-       }
-      return *this;
-    }
+      vector&
+      operator=(vector&& __x) noexcept(_Bit_alloc_traits::_S_nothrow_move())
+      {
+       if (_Bit_alloc_traits::_S_propagate_on_move_assign()
+           || this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator())
+         {
+           this->_M_deallocate();
+           this->_M_move_data(std::move(__x));
+           std::__alloc_on_move(_M_get_Bit_allocator(),
+                                __x._M_get_Bit_allocator());
+         }
+       else
+         {
+           if (__x.size() > capacity())
+             {
+               this->_M_deallocate();
+               _M_initialize(__x.size());
+             }
+           this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
+                                                     begin());
+           __x.clear();
+         }
+       return *this;
+      }
 
-    vector&
-    operator=(initializer_list<bool> __l)
-    {
-      this->assign (__l.begin(), __l.end());
-      return *this;
-    }
+      vector&
+      operator=(initializer_list<bool> __l)
+      {
+       this->assign (__l.begin(), __l.end());
+       return *this;
+      }
 #endif
 
-    // assign(), a generalized assignment member function.  Two
-    // versions: one that takes a count, and one that takes a range.
-    // The range version is a member template, so we dispatch on whether
-    // or not the type is an integer.
-    void
-    assign(size_type __n, const bool& __x)
-    { _M_fill_assign(__n, __x); }
+      // assign(), a generalized assignment member function.  Two
+      // versions: one that takes a count, and one that takes a range.
+      // The range version is a member template, so we dispatch on whether
+      // or not the type is an integer.
+      void
+      assign(size_type __n, const bool& __x)
+      { _M_fill_assign(__n, __x); }
 
 #if __cplusplus >= 201103L
-    template<typename _InputIterator,
-            typename = std::_RequireInputIter<_InputIterator>>
-      void
-      assign(_InputIterator __first, _InputIterator __last)
-      { _M_assign_dispatch(__first, __last, __false_type()); }
+      template<typename _InputIterator,
+              typename = std::_RequireInputIter<_InputIterator>>
+       void
+       assign(_InputIterator __first, _InputIterator __last)
+       { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
 #else
-    template<typename _InputIterator>
-      void
-      assign(_InputIterator __first, _InputIterator __last)
-      {
-       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
-       _M_assign_dispatch(__first, __last, _Integral());
-      }
+      template<typename _InputIterator>
+       void
+       assign(_InputIterator __first, _InputIterator __last)
+       {
+         typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+         _M_assign_dispatch(__first, __last, _Integral());
+       }
 #endif
 
 #if __cplusplus >= 201103L
-    void
-    assign(initializer_list<bool> __l)
-    { this->assign(__l.begin(), __l.end()); }
+      void
+      assign(initializer_list<bool> __l)
+      { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); }
 #endif
 
-    iterator
-    begin() _GLIBCXX_NOEXCEPT
-    { return this->_M_impl._M_start; }
+      iterator
+      begin() _GLIBCXX_NOEXCEPT
+      { return this->_M_impl._M_start; }
 
-    const_iterator
-    begin() const _GLIBCXX_NOEXCEPT
-    { return this->_M_impl._M_start; }
+      const_iterator
+      begin() const _GLIBCXX_NOEXCEPT
+      { return this->_M_impl._M_start; }
 
-    iterator
-    end() _GLIBCXX_NOEXCEPT
-    { return this->_M_impl._M_finish; }
+      iterator
+      end() _GLIBCXX_NOEXCEPT
+      { return this->_M_impl._M_finish; }
 
-    const_iterator
-    end() const _GLIBCXX_NOEXCEPT
-    { return this->_M_impl._M_finish; }
+      const_iterator
+      end() const _GLIBCXX_NOEXCEPT
+      { return this->_M_impl._M_finish; }
 
-    reverse_iterator
-    rbegin() _GLIBCXX_NOEXCEPT
-    { return reverse_iterator(end()); }
+      reverse_iterator
+      rbegin() _GLIBCXX_NOEXCEPT
+      { return reverse_iterator(end()); }
 
-    const_reverse_iterator
-    rbegin() const _GLIBCXX_NOEXCEPT
-    { return const_reverse_iterator(end()); }
+      const_reverse_iterator
+      rbegin() const _GLIBCXX_NOEXCEPT
+      { return const_reverse_iterator(end()); }
 
-    reverse_iterator
-    rend() _GLIBCXX_NOEXCEPT
-    { return reverse_iterator(begin()); }
+      reverse_iterator
+      rend() _GLIBCXX_NOEXCEPT
+      { return reverse_iterator(begin()); }
 
-    const_reverse_iterator
-    rend() const _GLIBCXX_NOEXCEPT
-    { return const_reverse_iterator(begin()); }
+      const_reverse_iterator
+      rend() const _GLIBCXX_NOEXCEPT
+      { return const_reverse_iterator(begin()); }
 
 #if __cplusplus >= 201103L
-    const_iterator
-    cbegin() const noexcept
-    { return this->_M_impl._M_start; }
+      const_iterator
+      cbegin() const noexcept
+      { return this->_M_impl._M_start; }
 
-    const_iterator
-    cend() const noexcept
-    { return this->_M_impl._M_finish; }
+      const_iterator
+      cend() const noexcept
+      { return this->_M_impl._M_finish; }
 
-    const_reverse_iterator
-    crbegin() const noexcept
-    { return const_reverse_iterator(end()); }
+      const_reverse_iterator
+      crbegin() const noexcept
+      { return const_reverse_iterator(end()); }
 
-    const_reverse_iterator
-    crend() const noexcept
-    { return const_reverse_iterator(begin()); }
+      const_reverse_iterator
+      crend() const noexcept
+      { return const_reverse_iterator(begin()); }
 #endif
 
-    size_type
-    size() const _GLIBCXX_NOEXCEPT
-    { return size_type(end() - begin()); }
+      size_type
+      size() const _GLIBCXX_NOEXCEPT
+      { return size_type(end() - begin()); }
 
-    size_type
-    max_size() const _GLIBCXX_NOEXCEPT
-    {
-      const size_type __isize =
-       __gnu_cxx::__numeric_traits<difference_type>::__max
-       - int(_S_word_bit) + 1;
-      const size_type __asize
-       = _Bit_alloc_traits::max_size(_M_get_Bit_allocator());
-      return (__asize <= __isize / int(_S_word_bit)
-             ? __asize * int(_S_word_bit) : __isize);
-    }
+      size_type
+      max_size() const _GLIBCXX_NOEXCEPT
+      {
+       const size_type __isize =
+         __gnu_cxx::__numeric_traits<difference_type>::__max
+         - int(_S_word_bit) + 1;
+       const size_type __asize
+         = _Bit_alloc_traits::max_size(_M_get_Bit_allocator());
+       return (__asize <= __isize / int(_S_word_bit)
+               ? __asize * int(_S_word_bit) : __isize);
+      }
 
-    size_type
-    capacity() const _GLIBCXX_NOEXCEPT
-    { return size_type(const_iterator(this->_M_impl._M_end_addr(), 0)
-                      - begin()); }
+      size_type
+      capacity() const _GLIBCXX_NOEXCEPT
+      { return size_type(const_iterator(this->_M_impl._M_end_addr(), 0)
+                        - begin()); }
 
-    bool
-    empty() const _GLIBCXX_NOEXCEPT
-    { return begin() == end(); }
+      bool
+      empty() const _GLIBCXX_NOEXCEPT
+      { return begin() == end(); }
 
-    reference
-    operator[](size_type __n)
-    {
-      return *iterator(this->_M_impl._M_start._M_p
-                      + __n / int(_S_word_bit), __n % int(_S_word_bit));
-    }
+      reference
+      operator[](size_type __n)
+      {
+       return *iterator(this->_M_impl._M_start._M_p
+                        + __n / int(_S_word_bit), __n % int(_S_word_bit));
+      }
 
-    const_reference
-    operator[](size_type __n) const
-    {
-      return *const_iterator(this->_M_impl._M_start._M_p
+      const_reference
+      operator[](size_type __n) const
+      {
+       return *const_iterator(this->_M_impl._M_start._M_p
                             + __n / int(_S_word_bit), __n % int(_S_word_bit));
-    }
+      }
 
-  protected:
-    void
-    _M_range_check(size_type __n) const
-    {
-      if (__n >= this->size())
-       __throw_out_of_range_fmt(__N("vector<bool>::_M_range_check: __n "
-                                    "(which is %zu) >= this->size() "
-                                    "(which is %zu)"),
-                                __n, this->size());
-    }
+    protected:
+      void
+      _M_range_check(size_type __n) const
+      {
+       if (__n >= this->size())
+         __throw_out_of_range_fmt(__N("vector<bool>::_M_range_check: __n "
+                                      "(which is %zu) >= this->size() "
+                                      "(which is %zu)"),
+                                  __n, this->size());
+      }
 
-  public:
-    reference
-    at(size_type __n)
-    { _M_range_check(__n); return (*this)[__n]; }
+    public:
+      reference
+      at(size_type __n)
+      { _M_range_check(__n); return (*this)[__n]; }
 
-    const_reference
-    at(size_type __n) const
-    { _M_range_check(__n); return (*this)[__n]; }
+      const_reference
+      at(size_type __n) const
+      { _M_range_check(__n); return (*this)[__n]; }
 
-    void
-    reserve(size_type __n)
-    {
-      if (__n > max_size())
-       __throw_length_error(__N("vector::reserve"));
-      if (capacity() < __n)
-       _M_reallocate(__n);
-    }
+      void
+      reserve(size_type __n)
+      {
+       if (__n > max_size())
+         __throw_length_error(__N("vector::reserve"));
+       if (capacity() < __n)
+         _M_reallocate(__n);
+      }
 
-    reference
-    front()
-    { return *begin(); }
+      reference
+      front()
+      { return *begin(); }
 
-    const_reference
-    front() const
-    { return *begin(); }
+      const_reference
+      front() const
+      { return *begin(); }
 
-    reference
-    back()
-    { return *(end() - 1); }
+      reference
+      back()
+      { return *(end() - 1); }
+
+      const_reference
+      back() const
+      { return *(end() - 1); }
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 464. Suggestion for new member functions in standard containers.
+      // N.B. DR 464 says nothing about vector<bool> but we need something
+      // here due to the way we are implementing DR 464 in the debug-mode
+      // vector class.
+      void
+      data() _GLIBCXX_NOEXCEPT { }
 
-    const_reference
-    back() const
-    { return *(end() - 1); }
-
-    // _GLIBCXX_RESOLVE_LIB_DEFECTS
-    // DR 464. Suggestion for new member functions in standard containers.
-    // N.B. DR 464 says nothing about vector<bool> but we need something
-    // here due to the way we are implementing DR 464 in the debug-mode
-    // vector class.
-    void
-    data() _GLIBCXX_NOEXCEPT { }
+      void
+      push_back(bool __x)
+      {
+       if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr())
+         *this->_M_impl._M_finish++ = __x;
+       else
+         _M_insert_aux(end(), __x);
+      }
 
-    void
-    push_back(bool __x)
-    {
-      if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr())
-        *this->_M_impl._M_finish++ = __x;
-      else
-        _M_insert_aux(end(), __x);
-    }
+      void
+      swap(vector& __x) _GLIBCXX_NOEXCEPT
+      {
+       std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
+       std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
+       std::swap(this->_M_impl._M_end_of_storage, 
+                 __x._M_impl._M_end_of_storage);
+       _Bit_alloc_traits::_S_on_swap(_M_get_Bit_allocator(),
+                                     __x._M_get_Bit_allocator());
+      }
 
-    void
-    swap(vector& __x) _GLIBCXX_NOEXCEPT
-    {
-      std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
-      std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
-      std::swap(this->_M_impl._M_end_of_storage, 
-               __x._M_impl._M_end_of_storage);
-      _Bit_alloc_traits::_S_on_swap(_M_get_Bit_allocator(),
-                                   __x._M_get_Bit_allocator());
-    }
+      // [23.2.5]/1, third-to-last entry in synopsis listing
+      static void
+      swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT
+      {
+       bool __tmp = __x;
+       __x = __y;
+       __y = __tmp;
+      }
 
-    // [23.2.5]/1, third-to-last entry in synopsis listing
-    static void
-    swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT
-    {
-      bool __tmp = __x;
-      __x = __y;
-      __y = __tmp;
-    }
+      iterator
+#if __cplusplus >= 201103L
+      insert(const_iterator __position, const bool& __x = bool())
+#else
+      insert(iterator __position, const bool& __x = bool())
+#endif
+      {
+       const difference_type __n = __position - begin();
+       if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()
+           && __position == end())
+         *this->_M_impl._M_finish++ = __x;
+       else
+         _M_insert_aux(__position._M_const_cast(), __x);
+       return begin() + __n;
+      }
 
-    iterator
 #if __cplusplus >= 201103L
-    insert(const_iterator __position, const bool& __x = bool())
+      template<typename _InputIterator,
+              typename = std::_RequireInputIter<_InputIterator>>
+       iterator
+       insert(const_iterator __position,
+              _InputIterator __first, _InputIterator __last)
+       {
+         difference_type __offset = __position - cbegin();
+         _M_insert_dispatch(__position._M_const_cast(),
+                            __first, __last, __false_type());
+         return begin() + __offset;
+       }
 #else
-    insert(iterator __position, const bool& __x = bool())
+      template<typename _InputIterator>
+       void
+       insert(iterator __position,
+              _InputIterator __first, _InputIterator __last)
+       {
+         typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+         _M_insert_dispatch(__position, __first, __last, _Integral());
+       }
 #endif
-    {
-      const difference_type __n = __position - begin();
-      if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()
-         && __position == end())
-        *this->_M_impl._M_finish++ = __x;
-      else
-        _M_insert_aux(__position._M_const_cast(), __x);
-      return begin() + __n;
-    }
 
 #if __cplusplus >= 201103L
-    template<typename _InputIterator,
-            typename = std::_RequireInputIter<_InputIterator>>
       iterator
-      insert(const_iterator __position,
-            _InputIterator __first, _InputIterator __last)
+      insert(const_iterator __position, size_type __n, const bool& __x)
       {
        difference_type __offset = __position - cbegin();
-       _M_insert_dispatch(__position._M_const_cast(),
-                          __first, __last, __false_type());
+       _M_fill_insert(__position._M_const_cast(), __n, __x);
        return begin() + __offset;
       }
 #else
-    template<typename _InputIterator>
       void
-      insert(iterator __position,
-            _InputIterator __first, _InputIterator __last)
-      {
-       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
-       _M_insert_dispatch(__position, __first, __last, _Integral());
-      }
-#endif
-
-#if __cplusplus >= 201103L
-    iterator
-    insert(const_iterator __position, size_type __n, const bool& __x)
-    {
-      difference_type __offset = __position - cbegin();
-      _M_fill_insert(__position._M_const_cast(), __n, __x);
-      return begin() + __offset;
-    }
-#else
-    void
-    insert(iterator __position, size_type __n, const bool& __x)
-    { _M_fill_insert(__position, __n, __x); }
+      insert(iterator __position, size_type __n, const bool& __x)
+      { _M_fill_insert(__position, __n, __x); }
 #endif
 
 #if __cplusplus >= 201103L
-    iterator
-    insert(const_iterator __p, initializer_list<bool> __l)
-    { return this->insert(__p, __l.begin(), __l.end()); }
+      iterator
+      insert(const_iterator __p, initializer_list<bool> __l)
+      { return this->insert(__p, __l.begin(), __l.end()); }
 #endif
 
-    void
-    pop_back()
-    { --this->_M_impl._M_finish; }
+      void
+      pop_back()
+      { --this->_M_impl._M_finish; }
 
-    iterator
+      iterator
 #if __cplusplus >= 201103L
-    erase(const_iterator __position)
+      erase(const_iterator __position)
 #else
-    erase(iterator __position)
+      erase(iterator __position)
 #endif
-    { return _M_erase(__position._M_const_cast()); }
+      { return _M_erase(__position._M_const_cast()); }
 
-    iterator
+      iterator
 #if __cplusplus >= 201103L
-    erase(const_iterator __first, const_iterator __last)
+      erase(const_iterator __first, const_iterator __last)
 #else
-    erase(iterator __first, iterator __last)
+      erase(iterator __first, iterator __last)
 #endif
-    { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); }
+      { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); }
 
-    void
-    resize(size_type __new_size, bool __x = bool())
-    {
-      if (__new_size < size())
-        _M_erase_at_end(begin() + difference_type(__new_size));
-      else
-        insert(end(), __new_size - size(), __x);
-    }
+      void
+      resize(size_type __new_size, bool __x = bool())
+      {
+       if (__new_size < size())
+         _M_erase_at_end(begin() + difference_type(__new_size));
+       else
+         insert(end(), __new_size - size(), __x);
+      }
 
 #if __cplusplus >= 201103L
-    void
-    shrink_to_fit()
-    { _M_shrink_to_fit(); }
+      void
+      shrink_to_fit()
+      { _M_shrink_to_fit(); }
 #endif
 
-    void
-    flip() _GLIBCXX_NOEXCEPT
-    {
-      _Bit_type * const __end = this->_M_impl._M_end_addr();
-      for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != __end; ++__p)
-        *__p = ~*__p;
-    }
+      void
+      flip() _GLIBCXX_NOEXCEPT
+      {
+       _Bit_type * const __end = this->_M_impl._M_end_addr();
+       for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != __end; ++__p)
+         *__p = ~*__p;
+      }
 
-    void
-    clear() _GLIBCXX_NOEXCEPT
-    { _M_erase_at_end(begin()); }
+      void
+      clear() _GLIBCXX_NOEXCEPT
+      { _M_erase_at_end(begin()); }
 
 #if __cplusplus >= 201103L
-    template<typename... _Args>
+      template<typename... _Args>
 #if __cplusplus > 201402L
-      reference
+       reference
 #else
-      void
+       void
 #endif
-      emplace_back(_Args&&... __args)
-      {
-       push_back(bool(__args...));
+       emplace_back(_Args&&... __args)
+       {
+         push_back(bool(__args...));
 #if __cplusplus > 201402L
-       return back();
-#endif
-      }
-
-    template<typename... _Args>
-      iterator
-      emplace(const_iterator __pos, _Args&&... __args)
-      { return insert(__pos, bool(__args...)); }
+         return back();
 #endif
-
-  protected:
-    // Precondition: __first._M_offset == 0 && __result._M_offset == 0.
-    iterator
-    _M_copy_aligned(const_iterator __first, const_iterator __last,
-                   iterator __result)
-    {
-      _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p);
-      return std::copy(const_iterator(__last._M_p, 0), __last,
-                      iterator(__q, 0));
-    }
-
-    void
-    _M_initialize(size_type __n)
-    {
-      if (__n)
-       {
-         _Bit_pointer __q = this->_M_allocate(__n);
-         this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
-         this->_M_impl._M_start = iterator(std::__addressof(*__q), 0);
-       }
-      else
-       {
-         this->_M_impl._M_end_of_storage = _Bit_pointer();
-         this->_M_impl._M_start = iterator(0, 0);
        }
-      this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
-    }
 
-    void
-    _M_reallocate(size_type __n);
-
-#if __cplusplus >= 201103L
-    bool
-    _M_shrink_to_fit();
+      template<typename... _Args>
+       iterator
+       emplace(const_iterator __pos, _Args&&... __args)
+       { return insert(__pos, bool(__args...)); }
 #endif
 
-    // Check whether it's an integral type.  If so, it's not an iterator.
-
-    // _GLIBCXX_RESOLVE_LIB_DEFECTS
-    // 438. Ambiguity in the "do the right thing" clause
-    template<typename _Integer>
-      void
-      _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
+    protected:
+      // Precondition: __first._M_offset == 0 && __result._M_offset == 0.
+      iterator
+      _M_copy_aligned(const_iterator __first, const_iterator __last,
+                     iterator __result)
       {
-       _M_initialize(static_cast<size_type>(__n));
-       std::fill(this->_M_impl._M_start._M_p, 
-                 this->_M_impl._M_end_addr(), __x ? ~0 : 0);
+       _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p);
+       return std::copy(const_iterator(__last._M_p, 0), __last,
+                        iterator(__q, 0));
       }
 
-    template<typename _InputIterator>
-      void 
-      _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
-                            __false_type)
-      { _M_initialize_range(__first, __last, 
-                           std::__iterator_category(__first)); }
-
-    template<typename _InputIterator>
       void
-      _M_initialize_range(_InputIterator __first, _InputIterator __last,
-                         std::input_iterator_tag)
+      _M_initialize(size_type __n)
       {
-       for (; __first != __last; ++__first)
-         push_back(*__first);
+       if (__n)
+         {
+           _Bit_pointer __q = this->_M_allocate(__n);
+           this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
+           this->_M_impl._M_start = iterator(std::__addressof(*__q), 0);
+         }
+       else
+         {
+           this->_M_impl._M_end_of_storage = _Bit_pointer();
+           this->_M_impl._M_start = iterator(0, 0);
+         }
+       this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
+
       }
 
-    template<typename _ForwardIterator>
       void
-      _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last,
-                         std::forward_iterator_tag)
+      _M_initialize_value(bool __x)
       {
-       const size_type __n = std::distance(__first, __last);
-       _M_initialize(__n);
-       std::copy(__first, __last, this->_M_impl._M_start);
+       __builtin_memset(this->_M_impl._M_start._M_p, __x ? ~0 : 0,
+               (this->_M_impl._M_end_addr() - this->_M_impl._M_start._M_p)
+               * sizeof(_Bit_type));
       }
 
-    // _GLIBCXX_RESOLVE_LIB_DEFECTS
-    // 438. Ambiguity in the "do the right thing" clause
-    template<typename _Integer>
       void
-      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
-      { _M_fill_assign(__n, __val); }
+      _M_reallocate(size_type __n);
 
-    template<class _InputIterator>
-      void
-      _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
-                        __false_type)
-      { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
+#if __cplusplus >= 201103L
+      bool
+      _M_shrink_to_fit();
+#endif
 
-    void
-    _M_fill_assign(size_t __n, bool __x)
-    {
-      if (__n > size())
+      // Check whether it's an integral type.  If so, it's not an iterator.
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 438. Ambiguity in the "do the right thing" clause
+      template<typename _Integer>
+       void
+       _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
        {
-         std::fill(this->_M_impl._M_start._M_p, 
-                   this->_M_impl._M_end_addr(), __x ? ~0 : 0);
-         insert(end(), __n - size(), __x);
+         _M_initialize(static_cast<size_type>(__n));
+         _M_initialize_value(__x);
        }
-      else
+
+      template<typename _InputIterator>
+       void 
+       _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+                              __false_type)
+       { _M_initialize_range(__first, __last, 
+                             std::__iterator_category(__first)); }
+
+      template<typename _InputIterator>
+       void
+       _M_initialize_range(_InputIterator __first, _InputIterator __last,
+                           std::input_iterator_tag)
        {
-         _M_erase_at_end(begin() + __n);
-         std::fill(this->_M_impl._M_start._M_p, 
-                   this->_M_impl._M_end_addr(), __x ? ~0 : 0);
+         for (; __first != __last; ++__first)
+           push_back(*__first);
        }
-    }
 
-    template<typename _InputIterator>
-      void
-      _M_assign_aux(_InputIterator __first, _InputIterator __last,
-                   std::input_iterator_tag)
-      {
-       iterator __cur = begin();
-       for (; __first != __last && __cur != end(); ++__cur, ++__first)
-         *__cur = *__first;
-       if (__first == __last)
-         _M_erase_at_end(__cur);
-       else
-         insert(end(), __first, __last);
-      }
-    
-    template<typename _ForwardIterator>
+      template<typename _ForwardIterator>
+       void
+       _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last,
+                           std::forward_iterator_tag)
+       {
+         const size_type __n = std::distance(__first, __last);
+         _M_initialize(__n);
+         std::copy(__first, __last, this->_M_impl._M_start);
+       }
+
+#if __cplusplus < 201103L
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 438. Ambiguity in the "do the right thing" clause
+      template<typename _Integer>
+       void
+       _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+       { _M_fill_assign(__n, __val); }
+
+      template<class _InputIterator>
+       void
+       _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
+                          __false_type)
+       { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
+#endif
+
       void
-      _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
-                   std::forward_iterator_tag)
+      _M_fill_assign(size_t __n, bool __x)
       {
-       const size_type __len = std::distance(__first, __last);
-       if (__len < size())
-         _M_erase_at_end(std::copy(__first, __last, begin()));
+       if (__n > size())
+         {
+           _M_initialize_value(__x);
+           insert(end(), __n - size(), __x);
+         }
        else
          {
-           _ForwardIterator __mid = __first;
-           std::advance(__mid, size());
-           std::copy(__first, __mid, begin());
-           insert(end(), __mid, __last);
+           _M_erase_at_end(begin() + __n);
+           _M_initialize_value(__x);
          }
       }
 
-    // Check whether it's an integral type.  If so, it's not an iterator.
+      template<typename _InputIterator>
+       void
+       _M_assign_aux(_InputIterator __first, _InputIterator __last,
+                     std::input_iterator_tag)
+       {
+         iterator __cur = begin();
+         for (; __first != __last && __cur != end(); ++__cur, ++__first)
+           *__cur = *__first;
+         if (__first == __last)
+           _M_erase_at_end(__cur);
+         else
+           insert(end(), __first, __last);
+       }
+    
+      template<typename _ForwardIterator>
+       void
+       _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
+                     std::forward_iterator_tag)
+       {
+         const size_type __len = std::distance(__first, __last);
+         if (__len < size())
+           _M_erase_at_end(std::copy(__first, __last, begin()));
+         else
+           {
+             _ForwardIterator __mid = __first;
+             std::advance(__mid, size());
+             std::copy(__first, __mid, begin());
+             insert(end(), __mid, __last);
+           }
+       }
 
-    // _GLIBCXX_RESOLVE_LIB_DEFECTS
-    // 438. Ambiguity in the "do the right thing" clause
-    template<typename _Integer>
-      void
-      _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
-                        __true_type)
-      { _M_fill_insert(__pos, __n, __x); }
+      // Check whether it's an integral type.  If so, it's not an iterator.
 
-    template<typename _InputIterator>
-      void
-      _M_insert_dispatch(iterator __pos,
-                        _InputIterator __first, _InputIterator __last,
-                        __false_type)
-      { _M_insert_range(__pos, __first, __last,
-                       std::__iterator_category(__first)); }
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 438. Ambiguity in the "do the right thing" clause
+      template<typename _Integer>
+       void
+       _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
+                          __true_type)
+       { _M_fill_insert(__pos, __n, __x); }
 
-    void
-    _M_fill_insert(iterator __position, size_type __n, bool __x);
+      template<typename _InputIterator>
+       void
+       _M_insert_dispatch(iterator __pos,
+                          _InputIterator __first, _InputIterator __last,
+                          __false_type)
+       { _M_insert_range(__pos, __first, __last,
+                         std::__iterator_category(__first)); }
 
-    template<typename _InputIterator>
       void
-      _M_insert_range(iterator __pos, _InputIterator __first, 
-                     _InputIterator __last, std::input_iterator_tag)
-      {
-       for (; __first != __last; ++__first)
-         {
-           __pos = insert(__pos, *__first);
-           ++__pos;
-         }
-      }
+      _M_fill_insert(iterator __position, size_type __n, bool __x);
 
-    template<typename _ForwardIterator>
-      void
-      _M_insert_range(iterator __position, _ForwardIterator __first, 
-                     _ForwardIterator __last, std::forward_iterator_tag);
+      template<typename _InputIterator>
+       void
+       _M_insert_range(iterator __pos, _InputIterator __first, 
+                       _InputIterator __last, std::input_iterator_tag)
+       {
+         for (; __first != __last; ++__first)
+           {
+             __pos = insert(__pos, *__first);
+             ++__pos;
+           }
+       }
 
-    void
-    _M_insert_aux(iterator __position, bool __x);
+      template<typename _ForwardIterator>
+       void
+       _M_insert_range(iterator __position, _ForwardIterator __first, 
+                       _ForwardIterator __last, std::forward_iterator_tag);
 
-    size_type
-    _M_check_len(size_type __n, const char* __s) const
-    {
-      if (max_size() - size() < __n)
-       __throw_length_error(__N(__s));
+      void
+      _M_insert_aux(iterator __position, bool __x);
 
-      const size_type __len = size() + std::max(size(), __n);
-      return (__len < size() || __len > max_size()) ? max_size() : __len;
-    }
+      size_type
+      _M_check_len(size_type __n, const char* __s) const
+      {
+       if (max_size() - size() < __n)
+         __throw_length_error(__N(__s));
 
-    void
-    _M_erase_at_end(iterator __pos)
-    { this->_M_impl._M_finish = __pos; }
+       const size_type __len = size() + std::max(size(), __n);
+       return (__len < size() || __len > max_size()) ? max_size() : __len;
+      }
 
-    iterator
-    _M_erase(iterator __pos);
+      void
+      _M_erase_at_end(iterator __pos)
+      { this->_M_impl._M_finish = __pos; }
 
-    iterator
-    _M_erase(iterator __first, iterator __last);
+      iterator
+      _M_erase(iterator __pos);
+
+      iterator
+      _M_erase(iterator __first, iterator __last);
   };
 
 _GLIBCXX_END_NAMESPACE_CONTAINER
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/default_init.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/default_init.cc
new file mode 100644 (file)
index 0000000..9ee4697
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (C) 2017 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 <vector>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+#include <ext/aligned_buffer.h>
+
+using T = bool;
+
+using __gnu_test::default_init_allocator;
+
+void test01()
+{
+  typedef default_init_allocator<T> alloc_type;
+  typedef std::vector<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::vector<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;
+}