xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/stl_bvector.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // vector<bool> specialization -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 2001-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj 
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj 
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj 
2538fd1498Szrj /*
2638fd1498Szrj  *
2738fd1498Szrj  * Copyright (c) 1994
2838fd1498Szrj  * Hewlett-Packard Company
2938fd1498Szrj  *
3038fd1498Szrj  * Permission to use, copy, modify, distribute and sell this software
3138fd1498Szrj  * and its documentation for any purpose is hereby granted without fee,
3238fd1498Szrj  * provided that the above copyright notice appear in all copies and
3338fd1498Szrj  * that both that copyright notice and this permission notice appear
3438fd1498Szrj  * in supporting documentation.  Hewlett-Packard Company makes no
3538fd1498Szrj  * representations about the suitability of this software for any
3638fd1498Szrj  * purpose.  It is provided "as is" without express or implied warranty.
3738fd1498Szrj  *
3838fd1498Szrj  *
3938fd1498Szrj  * Copyright (c) 1996-1999
4038fd1498Szrj  * Silicon Graphics Computer Systems, Inc.
4138fd1498Szrj  *
4238fd1498Szrj  * Permission to use, copy, modify, distribute and sell this software
4338fd1498Szrj  * and its documentation for any purpose is hereby granted without fee,
4438fd1498Szrj  * provided that the above copyright notice appear in all copies and
4538fd1498Szrj  * that both that copyright notice and this permission notice appear
4638fd1498Szrj  * in supporting documentation.  Silicon Graphics makes no
4738fd1498Szrj  * representations about the suitability of this software for any
4838fd1498Szrj  * purpose.  It is provided "as is" without express or implied warranty.
4938fd1498Szrj  */
5038fd1498Szrj 
5138fd1498Szrj /** @file bits/stl_bvector.h
5238fd1498Szrj  *  This is an internal header file, included by other library headers.
5338fd1498Szrj  *  Do not attempt to use it directly. @headername{vector}
5438fd1498Szrj  */
5538fd1498Szrj 
5638fd1498Szrj #ifndef _STL_BVECTOR_H
5738fd1498Szrj #define _STL_BVECTOR_H 1
5838fd1498Szrj 
5938fd1498Szrj #if __cplusplus >= 201103L
6038fd1498Szrj #include <initializer_list>
6138fd1498Szrj #include <bits/functional_hash.h>
6238fd1498Szrj #endif
6338fd1498Szrj 
_GLIBCXX_VISIBILITY(default)6438fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
6538fd1498Szrj {
6638fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
6738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
6838fd1498Szrj 
6938fd1498Szrj   typedef unsigned long _Bit_type;
7038fd1498Szrj   enum { _S_word_bit = int(__CHAR_BIT__ * sizeof(_Bit_type)) };
7138fd1498Szrj 
7238fd1498Szrj   struct _Bit_reference
7338fd1498Szrj   {
7438fd1498Szrj     _Bit_type * _M_p;
7538fd1498Szrj     _Bit_type _M_mask;
7638fd1498Szrj 
7738fd1498Szrj     _Bit_reference(_Bit_type * __x, _Bit_type __y)
7838fd1498Szrj     : _M_p(__x), _M_mask(__y) { }
7938fd1498Szrj 
8038fd1498Szrj     _Bit_reference() _GLIBCXX_NOEXCEPT : _M_p(0), _M_mask(0) { }
8138fd1498Szrj 
8238fd1498Szrj     operator bool() const _GLIBCXX_NOEXCEPT
8338fd1498Szrj     { return !!(*_M_p & _M_mask); }
8438fd1498Szrj 
8538fd1498Szrj     _Bit_reference&
8638fd1498Szrj     operator=(bool __x) _GLIBCXX_NOEXCEPT
8738fd1498Szrj     {
8838fd1498Szrj       if (__x)
8938fd1498Szrj 	*_M_p |= _M_mask;
9038fd1498Szrj       else
9138fd1498Szrj 	*_M_p &= ~_M_mask;
9238fd1498Szrj       return *this;
9338fd1498Szrj     }
9438fd1498Szrj 
9538fd1498Szrj     _Bit_reference&
9638fd1498Szrj     operator=(const _Bit_reference& __x) _GLIBCXX_NOEXCEPT
9738fd1498Szrj     { return *this = bool(__x); }
9838fd1498Szrj 
9938fd1498Szrj     bool
10038fd1498Szrj     operator==(const _Bit_reference& __x) const
10138fd1498Szrj     { return bool(*this) == bool(__x); }
10238fd1498Szrj 
10338fd1498Szrj     bool
10438fd1498Szrj     operator<(const _Bit_reference& __x) const
10538fd1498Szrj     { return !bool(*this) && bool(__x); }
10638fd1498Szrj 
10738fd1498Szrj     void
10838fd1498Szrj     flip() _GLIBCXX_NOEXCEPT
10938fd1498Szrj     { *_M_p ^= _M_mask; }
11038fd1498Szrj   };
11138fd1498Szrj 
11238fd1498Szrj #if __cplusplus >= 201103L
11338fd1498Szrj   inline void
11438fd1498Szrj   swap(_Bit_reference __x, _Bit_reference __y) noexcept
11538fd1498Szrj   {
11638fd1498Szrj     bool __tmp = __x;
11738fd1498Szrj     __x = __y;
11838fd1498Szrj     __y = __tmp;
11938fd1498Szrj   }
12038fd1498Szrj 
12138fd1498Szrj   inline void
12238fd1498Szrj   swap(_Bit_reference __x, bool& __y) noexcept
12338fd1498Szrj   {
12438fd1498Szrj     bool __tmp = __x;
12538fd1498Szrj     __x = __y;
12638fd1498Szrj     __y = __tmp;
12738fd1498Szrj   }
12838fd1498Szrj 
12938fd1498Szrj   inline void
13038fd1498Szrj   swap(bool& __x, _Bit_reference __y) noexcept
13138fd1498Szrj   {
13238fd1498Szrj     bool __tmp = __x;
13338fd1498Szrj     __x = __y;
13438fd1498Szrj     __y = __tmp;
13538fd1498Szrj   }
13638fd1498Szrj #endif
13738fd1498Szrj 
13838fd1498Szrj   struct _Bit_iterator_base
13938fd1498Szrj   : public std::iterator<std::random_access_iterator_tag, bool>
14038fd1498Szrj   {
14138fd1498Szrj     _Bit_type * _M_p;
14238fd1498Szrj     unsigned int _M_offset;
14338fd1498Szrj 
14438fd1498Szrj     _Bit_iterator_base(_Bit_type * __x, unsigned int __y)
14538fd1498Szrj     : _M_p(__x), _M_offset(__y) { }
14638fd1498Szrj 
14738fd1498Szrj     void
14838fd1498Szrj     _M_bump_up()
14938fd1498Szrj     {
15038fd1498Szrj       if (_M_offset++ == int(_S_word_bit) - 1)
15138fd1498Szrj 	{
15238fd1498Szrj 	  _M_offset = 0;
15338fd1498Szrj 	  ++_M_p;
15438fd1498Szrj 	}
15538fd1498Szrj     }
15638fd1498Szrj 
15738fd1498Szrj     void
15838fd1498Szrj     _M_bump_down()
15938fd1498Szrj     {
16038fd1498Szrj       if (_M_offset-- == 0)
16138fd1498Szrj 	{
16238fd1498Szrj 	  _M_offset = int(_S_word_bit) - 1;
16338fd1498Szrj 	  --_M_p;
16438fd1498Szrj 	}
16538fd1498Szrj     }
16638fd1498Szrj 
16738fd1498Szrj     void
16838fd1498Szrj     _M_incr(ptrdiff_t __i)
16938fd1498Szrj     {
17038fd1498Szrj       difference_type __n = __i + _M_offset;
17138fd1498Szrj       _M_p += __n / int(_S_word_bit);
17238fd1498Szrj       __n = __n % int(_S_word_bit);
17338fd1498Szrj       if (__n < 0)
17438fd1498Szrj 	{
17538fd1498Szrj 	  __n += int(_S_word_bit);
17638fd1498Szrj 	  --_M_p;
17738fd1498Szrj 	}
17838fd1498Szrj       _M_offset = static_cast<unsigned int>(__n);
17938fd1498Szrj     }
18038fd1498Szrj 
18138fd1498Szrj     bool
18238fd1498Szrj     operator==(const _Bit_iterator_base& __i) const
18338fd1498Szrj     { return _M_p == __i._M_p && _M_offset == __i._M_offset; }
18438fd1498Szrj 
18538fd1498Szrj     bool
18638fd1498Szrj     operator<(const _Bit_iterator_base& __i) const
18738fd1498Szrj     {
18838fd1498Szrj       return _M_p < __i._M_p
18938fd1498Szrj 	    || (_M_p == __i._M_p && _M_offset < __i._M_offset);
19038fd1498Szrj     }
19138fd1498Szrj 
19238fd1498Szrj     bool
19338fd1498Szrj     operator!=(const _Bit_iterator_base& __i) const
19438fd1498Szrj     { return !(*this == __i); }
19538fd1498Szrj 
19638fd1498Szrj     bool
19738fd1498Szrj     operator>(const _Bit_iterator_base& __i) const
19838fd1498Szrj     { return __i < *this; }
19938fd1498Szrj 
20038fd1498Szrj     bool
20138fd1498Szrj     operator<=(const _Bit_iterator_base& __i) const
20238fd1498Szrj     { return !(__i < *this); }
20338fd1498Szrj 
20438fd1498Szrj     bool
20538fd1498Szrj     operator>=(const _Bit_iterator_base& __i) const
20638fd1498Szrj     { return !(*this < __i); }
20738fd1498Szrj   };
20838fd1498Szrj 
20938fd1498Szrj   inline ptrdiff_t
21038fd1498Szrj   operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
21138fd1498Szrj   {
21238fd1498Szrj     return (int(_S_word_bit) * (__x._M_p - __y._M_p)
21338fd1498Szrj 	    + __x._M_offset - __y._M_offset);
21438fd1498Szrj   }
21538fd1498Szrj 
21638fd1498Szrj   struct _Bit_iterator : public _Bit_iterator_base
21738fd1498Szrj   {
21838fd1498Szrj     typedef _Bit_reference  reference;
21938fd1498Szrj     typedef _Bit_reference* pointer;
22038fd1498Szrj     typedef _Bit_iterator   iterator;
22138fd1498Szrj 
22238fd1498Szrj     _Bit_iterator() : _Bit_iterator_base(0, 0) { }
22338fd1498Szrj 
22438fd1498Szrj     _Bit_iterator(_Bit_type * __x, unsigned int __y)
22538fd1498Szrj     : _Bit_iterator_base(__x, __y) { }
22638fd1498Szrj 
22738fd1498Szrj     iterator
22838fd1498Szrj     _M_const_cast() const
22938fd1498Szrj     { return *this; }
23038fd1498Szrj 
23138fd1498Szrj     reference
23238fd1498Szrj     operator*() const
23338fd1498Szrj     { return reference(_M_p, 1UL << _M_offset); }
23438fd1498Szrj 
23538fd1498Szrj     iterator&
23638fd1498Szrj     operator++()
23738fd1498Szrj     {
23838fd1498Szrj       _M_bump_up();
23938fd1498Szrj       return *this;
24038fd1498Szrj     }
24138fd1498Szrj 
24238fd1498Szrj     iterator
24338fd1498Szrj     operator++(int)
24438fd1498Szrj     {
24538fd1498Szrj       iterator __tmp = *this;
24638fd1498Szrj       _M_bump_up();
24738fd1498Szrj       return __tmp;
24838fd1498Szrj     }
24938fd1498Szrj 
25038fd1498Szrj     iterator&
25138fd1498Szrj     operator--()
25238fd1498Szrj     {
25338fd1498Szrj       _M_bump_down();
25438fd1498Szrj       return *this;
25538fd1498Szrj     }
25638fd1498Szrj 
25738fd1498Szrj     iterator
25838fd1498Szrj     operator--(int)
25938fd1498Szrj     {
26038fd1498Szrj       iterator __tmp = *this;
26138fd1498Szrj       _M_bump_down();
26238fd1498Szrj       return __tmp;
26338fd1498Szrj     }
26438fd1498Szrj 
26538fd1498Szrj     iterator&
26638fd1498Szrj     operator+=(difference_type __i)
26738fd1498Szrj     {
26838fd1498Szrj       _M_incr(__i);
26938fd1498Szrj       return *this;
27038fd1498Szrj     }
27138fd1498Szrj 
27238fd1498Szrj     iterator&
27338fd1498Szrj     operator-=(difference_type __i)
27438fd1498Szrj     {
27538fd1498Szrj       *this += -__i;
27638fd1498Szrj       return *this;
27738fd1498Szrj     }
27838fd1498Szrj 
27938fd1498Szrj     iterator
28038fd1498Szrj     operator+(difference_type __i) const
28138fd1498Szrj     {
28238fd1498Szrj       iterator __tmp = *this;
28338fd1498Szrj       return __tmp += __i;
28438fd1498Szrj     }
28538fd1498Szrj 
28638fd1498Szrj     iterator
28738fd1498Szrj     operator-(difference_type __i) const
28838fd1498Szrj     {
28938fd1498Szrj       iterator __tmp = *this;
29038fd1498Szrj       return __tmp -= __i;
29138fd1498Szrj     }
29238fd1498Szrj 
29338fd1498Szrj     reference
29438fd1498Szrj     operator[](difference_type __i) const
29538fd1498Szrj     { return *(*this + __i); }
29638fd1498Szrj   };
29738fd1498Szrj 
29838fd1498Szrj   inline _Bit_iterator
29938fd1498Szrj   operator+(ptrdiff_t __n, const _Bit_iterator& __x)
30038fd1498Szrj   { return __x + __n; }
30138fd1498Szrj 
30238fd1498Szrj   struct _Bit_const_iterator : public _Bit_iterator_base
30338fd1498Szrj   {
30438fd1498Szrj     typedef bool                 reference;
30538fd1498Szrj     typedef bool                 const_reference;
30638fd1498Szrj     typedef const bool*          pointer;
30738fd1498Szrj     typedef _Bit_const_iterator  const_iterator;
30838fd1498Szrj 
30938fd1498Szrj     _Bit_const_iterator() : _Bit_iterator_base(0, 0) { }
31038fd1498Szrj 
31138fd1498Szrj     _Bit_const_iterator(_Bit_type * __x, unsigned int __y)
31238fd1498Szrj     : _Bit_iterator_base(__x, __y) { }
31338fd1498Szrj 
31438fd1498Szrj     _Bit_const_iterator(const _Bit_iterator& __x)
31538fd1498Szrj     : _Bit_iterator_base(__x._M_p, __x._M_offset) { }
31638fd1498Szrj 
31738fd1498Szrj     _Bit_iterator
31838fd1498Szrj     _M_const_cast() const
31938fd1498Szrj     { return _Bit_iterator(_M_p, _M_offset); }
32038fd1498Szrj 
32138fd1498Szrj     const_reference
32238fd1498Szrj     operator*() const
32338fd1498Szrj     { return _Bit_reference(_M_p, 1UL << _M_offset); }
32438fd1498Szrj 
32538fd1498Szrj     const_iterator&
32638fd1498Szrj     operator++()
32738fd1498Szrj     {
32838fd1498Szrj       _M_bump_up();
32938fd1498Szrj       return *this;
33038fd1498Szrj     }
33138fd1498Szrj 
33238fd1498Szrj     const_iterator
33338fd1498Szrj     operator++(int)
33438fd1498Szrj     {
33538fd1498Szrj       const_iterator __tmp = *this;
33638fd1498Szrj       _M_bump_up();
33738fd1498Szrj       return __tmp;
33838fd1498Szrj     }
33938fd1498Szrj 
34038fd1498Szrj     const_iterator&
34138fd1498Szrj     operator--()
34238fd1498Szrj     {
34338fd1498Szrj       _M_bump_down();
34438fd1498Szrj       return *this;
34538fd1498Szrj     }
34638fd1498Szrj 
34738fd1498Szrj     const_iterator
34838fd1498Szrj     operator--(int)
34938fd1498Szrj     {
35038fd1498Szrj       const_iterator __tmp = *this;
35138fd1498Szrj       _M_bump_down();
35238fd1498Szrj       return __tmp;
35338fd1498Szrj     }
35438fd1498Szrj 
35538fd1498Szrj     const_iterator&
35638fd1498Szrj     operator+=(difference_type __i)
35738fd1498Szrj     {
35838fd1498Szrj       _M_incr(__i);
35938fd1498Szrj       return *this;
36038fd1498Szrj     }
36138fd1498Szrj 
36238fd1498Szrj     const_iterator&
36338fd1498Szrj     operator-=(difference_type __i)
36438fd1498Szrj     {
36538fd1498Szrj       *this += -__i;
36638fd1498Szrj       return *this;
36738fd1498Szrj     }
36838fd1498Szrj 
36938fd1498Szrj     const_iterator
37038fd1498Szrj     operator+(difference_type __i) const
37138fd1498Szrj     {
37238fd1498Szrj       const_iterator __tmp = *this;
37338fd1498Szrj       return __tmp += __i;
37438fd1498Szrj     }
37538fd1498Szrj 
37638fd1498Szrj     const_iterator
37738fd1498Szrj     operator-(difference_type __i) const
37838fd1498Szrj     {
37938fd1498Szrj       const_iterator __tmp = *this;
38038fd1498Szrj       return __tmp -= __i;
38138fd1498Szrj     }
38238fd1498Szrj 
38338fd1498Szrj     const_reference
38438fd1498Szrj     operator[](difference_type __i) const
38538fd1498Szrj     { return *(*this + __i); }
38638fd1498Szrj   };
38738fd1498Szrj 
38838fd1498Szrj   inline _Bit_const_iterator
38938fd1498Szrj   operator+(ptrdiff_t __n, const _Bit_const_iterator& __x)
39038fd1498Szrj   { return __x + __n; }
39138fd1498Szrj 
39238fd1498Szrj   inline void
39338fd1498Szrj   __fill_bvector(_Bit_type * __v,
39438fd1498Szrj 		 unsigned int __first, unsigned int __last, bool __x)
39538fd1498Szrj   {
39638fd1498Szrj     const _Bit_type __fmask = ~0ul << __first;
39738fd1498Szrj     const _Bit_type __lmask = ~0ul >> (_S_word_bit - __last);
39838fd1498Szrj     const _Bit_type __mask = __fmask & __lmask;
39938fd1498Szrj 
40038fd1498Szrj     if (__x)
40138fd1498Szrj       *__v |= __mask;
40238fd1498Szrj     else
40338fd1498Szrj       *__v &= ~__mask;
40438fd1498Szrj   }
40538fd1498Szrj 
40638fd1498Szrj   inline void
40738fd1498Szrj   fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x)
40838fd1498Szrj   {
40938fd1498Szrj     if (__first._M_p != __last._M_p)
41038fd1498Szrj       {
41138fd1498Szrj 	_Bit_type* __first_p = __first._M_p;
41238fd1498Szrj 	if (__first._M_offset != 0)
41338fd1498Szrj 	  __fill_bvector(__first_p++, __first._M_offset, _S_word_bit, __x);
41438fd1498Szrj 
41538fd1498Szrj 	__builtin_memset(__first_p, __x ? ~0 : 0,
41638fd1498Szrj 			 (__last._M_p - __first_p) * sizeof(_Bit_type));
41738fd1498Szrj 
41838fd1498Szrj 	if (__last._M_offset != 0)
41938fd1498Szrj 	  __fill_bvector(__last._M_p, 0, __last._M_offset, __x);
42038fd1498Szrj       }
42138fd1498Szrj     else if (__first._M_offset != __last._M_offset)
42238fd1498Szrj       __fill_bvector(__first._M_p, __first._M_offset, __last._M_offset, __x);
42338fd1498Szrj   }
42438fd1498Szrj 
42538fd1498Szrj   template<typename _Alloc>
42638fd1498Szrj     struct _Bvector_base
42738fd1498Szrj     {
42838fd1498Szrj       typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
42938fd1498Szrj         rebind<_Bit_type>::other _Bit_alloc_type;
43038fd1498Szrj       typedef typename __gnu_cxx::__alloc_traits<_Bit_alloc_type>
43138fd1498Szrj 	_Bit_alloc_traits;
43238fd1498Szrj       typedef typename _Bit_alloc_traits::pointer _Bit_pointer;
43338fd1498Szrj 
43438fd1498Szrj       struct _Bvector_impl_data
43538fd1498Szrj       {
43638fd1498Szrj 	_Bit_iterator 	_M_start;
43738fd1498Szrj 	_Bit_iterator 	_M_finish;
43838fd1498Szrj 	_Bit_pointer 	_M_end_of_storage;
43938fd1498Szrj 
44038fd1498Szrj 	_Bvector_impl_data() _GLIBCXX_NOEXCEPT
44138fd1498Szrj 	: _M_start(), _M_finish(), _M_end_of_storage()
44238fd1498Szrj 	{ }
44338fd1498Szrj 
44438fd1498Szrj #if __cplusplus >= 201103L
44538fd1498Szrj 	_Bvector_impl_data(_Bvector_impl_data&& __x) noexcept
44638fd1498Szrj 	: _M_start(__x._M_start), _M_finish(__x._M_finish)
44738fd1498Szrj 	, _M_end_of_storage(__x._M_end_of_storage)
44838fd1498Szrj 	{ __x._M_reset(); }
44938fd1498Szrj 
45038fd1498Szrj 	void
45138fd1498Szrj 	_M_move_data(_Bvector_impl_data&& __x) noexcept
45238fd1498Szrj 	{
45338fd1498Szrj 	  this->_M_start = __x._M_start;
45438fd1498Szrj 	  this->_M_finish = __x._M_finish;
45538fd1498Szrj 	  this->_M_end_of_storage = __x._M_end_of_storage;
45638fd1498Szrj 	  __x._M_reset();
45738fd1498Szrj 	}
45838fd1498Szrj #endif
45938fd1498Szrj 
46038fd1498Szrj 	void
46138fd1498Szrj 	_M_reset() _GLIBCXX_NOEXCEPT
46238fd1498Szrj 	{
46338fd1498Szrj 	  _M_start = _M_finish = _Bit_iterator();
46438fd1498Szrj 	  _M_end_of_storage = _Bit_pointer();
46538fd1498Szrj 	}
46638fd1498Szrj       };
46738fd1498Szrj 
46838fd1498Szrj       struct _Bvector_impl
46938fd1498Szrj 	: public _Bit_alloc_type, public _Bvector_impl_data
47038fd1498Szrj 	{
47138fd1498Szrj 	public:
472*58e805e6Szrj 	  _Bvector_impl() _GLIBCXX_NOEXCEPT_IF(
473*58e805e6Szrj 		is_nothrow_default_constructible<_Bit_alloc_type>::value)
47438fd1498Szrj 	  : _Bit_alloc_type()
47538fd1498Szrj 	  { }
47638fd1498Szrj 
47738fd1498Szrj 	  _Bvector_impl(const _Bit_alloc_type& __a) _GLIBCXX_NOEXCEPT
47838fd1498Szrj 	  : _Bit_alloc_type(__a)
47938fd1498Szrj 	  { }
48038fd1498Szrj 
48138fd1498Szrj #if __cplusplus >= 201103L
48238fd1498Szrj 	_Bvector_impl(_Bvector_impl&&) = default;
48338fd1498Szrj #endif
48438fd1498Szrj 
48538fd1498Szrj 	_Bit_type*
48638fd1498Szrj 	_M_end_addr() const _GLIBCXX_NOEXCEPT
48738fd1498Szrj 	{
48838fd1498Szrj 	  if (this->_M_end_of_storage)
48938fd1498Szrj 	    return std::__addressof(this->_M_end_of_storage[-1]) + 1;
49038fd1498Szrj 	  return 0;
49138fd1498Szrj 	}
49238fd1498Szrj       };
49338fd1498Szrj 
49438fd1498Szrj     public:
49538fd1498Szrj       typedef _Alloc allocator_type;
49638fd1498Szrj 
49738fd1498Szrj       _Bit_alloc_type&
49838fd1498Szrj       _M_get_Bit_allocator() _GLIBCXX_NOEXCEPT
49938fd1498Szrj       { return this->_M_impl; }
50038fd1498Szrj 
50138fd1498Szrj       const _Bit_alloc_type&
50238fd1498Szrj       _M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT
50338fd1498Szrj       { return this->_M_impl; }
50438fd1498Szrj 
50538fd1498Szrj       allocator_type
50638fd1498Szrj       get_allocator() const _GLIBCXX_NOEXCEPT
50738fd1498Szrj       { return allocator_type(_M_get_Bit_allocator()); }
50838fd1498Szrj 
50938fd1498Szrj #if __cplusplus >= 201103L
51038fd1498Szrj       _Bvector_base() = default;
51138fd1498Szrj #else
51238fd1498Szrj       _Bvector_base() { }
51338fd1498Szrj #endif
51438fd1498Szrj 
51538fd1498Szrj       _Bvector_base(const allocator_type& __a)
51638fd1498Szrj       : _M_impl(__a) { }
51738fd1498Szrj 
51838fd1498Szrj #if __cplusplus >= 201103L
51938fd1498Szrj       _Bvector_base(_Bvector_base&&) = default;
52038fd1498Szrj #endif
52138fd1498Szrj 
52238fd1498Szrj       ~_Bvector_base()
52338fd1498Szrj       { this->_M_deallocate(); }
52438fd1498Szrj 
52538fd1498Szrj     protected:
52638fd1498Szrj       _Bvector_impl _M_impl;
52738fd1498Szrj 
52838fd1498Szrj       _Bit_pointer
52938fd1498Szrj       _M_allocate(size_t __n)
53038fd1498Szrj       { return _Bit_alloc_traits::allocate(_M_impl, _S_nword(__n)); }
53138fd1498Szrj 
53238fd1498Szrj       void
53338fd1498Szrj       _M_deallocate()
53438fd1498Szrj       {
53538fd1498Szrj 	if (_M_impl._M_start._M_p)
53638fd1498Szrj 	  {
53738fd1498Szrj 	    const size_t __n = _M_impl._M_end_addr() - _M_impl._M_start._M_p;
53838fd1498Szrj 	    _Bit_alloc_traits::deallocate(_M_impl,
53938fd1498Szrj 					  _M_impl._M_end_of_storage - __n,
54038fd1498Szrj 					  __n);
54138fd1498Szrj 	    _M_impl._M_reset();
54238fd1498Szrj 	  }
54338fd1498Szrj       }
54438fd1498Szrj 
54538fd1498Szrj #if __cplusplus >= 201103L
54638fd1498Szrj       void
54738fd1498Szrj       _M_move_data(_Bvector_base&& __x) noexcept
54838fd1498Szrj       { _M_impl._M_move_data(std::move(__x._M_impl)); }
54938fd1498Szrj #endif
55038fd1498Szrj 
55138fd1498Szrj       static size_t
55238fd1498Szrj       _S_nword(size_t __n)
55338fd1498Szrj       { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); }
55438fd1498Szrj     };
55538fd1498Szrj 
55638fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER
55738fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
55838fd1498Szrj } // namespace std
55938fd1498Szrj 
56038fd1498Szrj // Declare a partial specialization of vector<T, Alloc>.
56138fd1498Szrj #include <bits/stl_vector.h>
56238fd1498Szrj 
_GLIBCXX_VISIBILITY(default)56338fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
56438fd1498Szrj {
56538fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
56638fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
56738fd1498Szrj 
56838fd1498Szrj   /**
56938fd1498Szrj    *  @brief  A specialization of vector for booleans which offers fixed time
57038fd1498Szrj    *  access to individual elements in any order.
57138fd1498Szrj    *
57238fd1498Szrj    *  @ingroup sequences
57338fd1498Szrj    *
57438fd1498Szrj    *  @tparam _Alloc  Allocator type.
57538fd1498Szrj    *
57638fd1498Szrj    *  Note that vector<bool> does not actually meet the requirements for being
57738fd1498Szrj    *  a container.  This is because the reference and pointer types are not
57838fd1498Szrj    *  really references and pointers to bool.  See DR96 for details.  @see
57938fd1498Szrj    *  vector for function documentation.
58038fd1498Szrj    *
58138fd1498Szrj    *  In some terminology a %vector can be described as a dynamic
58238fd1498Szrj    *  C-style array, it offers fast and efficient access to individual
58338fd1498Szrj    *  elements in any order and saves the user from worrying about
58438fd1498Szrj    *  memory and size allocation.  Subscripting ( @c [] ) access is
58538fd1498Szrj    *  also provided as with C-style arrays.
58638fd1498Szrj   */
58738fd1498Szrj   template<typename _Alloc>
58838fd1498Szrj     class vector<bool, _Alloc> : protected _Bvector_base<_Alloc>
58938fd1498Szrj     {
59038fd1498Szrj       typedef _Bvector_base<_Alloc>			_Base;
59138fd1498Szrj       typedef typename _Base::_Bit_pointer		_Bit_pointer;
59238fd1498Szrj       typedef typename _Base::_Bit_alloc_traits		_Bit_alloc_traits;
59338fd1498Szrj 
59438fd1498Szrj #if __cplusplus >= 201103L
59538fd1498Szrj       friend struct std::hash<vector>;
59638fd1498Szrj #endif
59738fd1498Szrj 
59838fd1498Szrj     public:
59938fd1498Szrj       typedef bool					value_type;
60038fd1498Szrj       typedef size_t					size_type;
60138fd1498Szrj       typedef ptrdiff_t					difference_type;
60238fd1498Szrj       typedef _Bit_reference				reference;
60338fd1498Szrj       typedef bool					const_reference;
60438fd1498Szrj       typedef _Bit_reference*				pointer;
60538fd1498Szrj       typedef const bool*				const_pointer;
60638fd1498Szrj       typedef _Bit_iterator				iterator;
60738fd1498Szrj       typedef _Bit_const_iterator			const_iterator;
60838fd1498Szrj       typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
60938fd1498Szrj       typedef std::reverse_iterator<iterator>		reverse_iterator;
61038fd1498Szrj       typedef _Alloc					allocator_type;
61138fd1498Szrj 
61238fd1498Szrj       allocator_type
61338fd1498Szrj       get_allocator() const
61438fd1498Szrj       { return _Base::get_allocator(); }
61538fd1498Szrj 
61638fd1498Szrj     protected:
61738fd1498Szrj       using _Base::_M_allocate;
61838fd1498Szrj       using _Base::_M_deallocate;
61938fd1498Szrj       using _Base::_S_nword;
62038fd1498Szrj       using _Base::_M_get_Bit_allocator;
62138fd1498Szrj 
62238fd1498Szrj     public:
62338fd1498Szrj #if __cplusplus >= 201103L
62438fd1498Szrj       vector() = default;
62538fd1498Szrj #else
62638fd1498Szrj       vector() { }
62738fd1498Szrj #endif
62838fd1498Szrj 
62938fd1498Szrj       explicit
63038fd1498Szrj       vector(const allocator_type& __a)
63138fd1498Szrj       : _Base(__a) { }
63238fd1498Szrj 
63338fd1498Szrj #if __cplusplus >= 201103L
63438fd1498Szrj       explicit
63538fd1498Szrj       vector(size_type __n, const allocator_type& __a = allocator_type())
63638fd1498Szrj       : vector(__n, false, __a)
63738fd1498Szrj       { }
63838fd1498Szrj 
63938fd1498Szrj       vector(size_type __n, const bool& __value,
64038fd1498Szrj 	     const allocator_type& __a = allocator_type())
64138fd1498Szrj #else
64238fd1498Szrj       explicit
64338fd1498Szrj       vector(size_type __n, const bool& __value = bool(),
64438fd1498Szrj 	     const allocator_type& __a = allocator_type())
64538fd1498Szrj #endif
64638fd1498Szrj       : _Base(__a)
64738fd1498Szrj       {
64838fd1498Szrj 	_M_initialize(__n);
64938fd1498Szrj 	_M_initialize_value(__value);
65038fd1498Szrj       }
65138fd1498Szrj 
65238fd1498Szrj       vector(const vector& __x)
65338fd1498Szrj       : _Base(_Bit_alloc_traits::_S_select_on_copy(__x._M_get_Bit_allocator()))
65438fd1498Szrj       {
65538fd1498Szrj 	_M_initialize(__x.size());
65638fd1498Szrj 	_M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
65738fd1498Szrj       }
65838fd1498Szrj 
65938fd1498Szrj #if __cplusplus >= 201103L
66038fd1498Szrj       vector(vector&&) = default;
66138fd1498Szrj 
66238fd1498Szrj       vector(vector&& __x, const allocator_type& __a)
66338fd1498Szrj       noexcept(_Bit_alloc_traits::_S_always_equal())
66438fd1498Szrj       : _Base(__a)
66538fd1498Szrj       {
66638fd1498Szrj 	if (__x.get_allocator() == __a)
66738fd1498Szrj 	  this->_M_move_data(std::move(__x));
66838fd1498Szrj 	else
66938fd1498Szrj 	  {
67038fd1498Szrj 	    _M_initialize(__x.size());
67138fd1498Szrj 	    _M_copy_aligned(__x.begin(), __x.end(), begin());
67238fd1498Szrj 	    __x.clear();
67338fd1498Szrj 	  }
67438fd1498Szrj       }
67538fd1498Szrj 
67638fd1498Szrj       vector(const vector& __x, const allocator_type& __a)
67738fd1498Szrj       : _Base(__a)
67838fd1498Szrj       {
67938fd1498Szrj 	_M_initialize(__x.size());
68038fd1498Szrj 	_M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
68138fd1498Szrj       }
68238fd1498Szrj 
68338fd1498Szrj       vector(initializer_list<bool> __l,
68438fd1498Szrj 	     const allocator_type& __a = allocator_type())
68538fd1498Szrj       : _Base(__a)
68638fd1498Szrj       {
68738fd1498Szrj 	_M_initialize_range(__l.begin(), __l.end(),
68838fd1498Szrj 			    random_access_iterator_tag());
68938fd1498Szrj       }
69038fd1498Szrj #endif
69138fd1498Szrj 
69238fd1498Szrj #if __cplusplus >= 201103L
69338fd1498Szrj       template<typename _InputIterator,
69438fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
69538fd1498Szrj 	vector(_InputIterator __first, _InputIterator __last,
69638fd1498Szrj 	       const allocator_type& __a = allocator_type())
69738fd1498Szrj 	: _Base(__a)
69838fd1498Szrj 	{ _M_initialize_dispatch(__first, __last, __false_type()); }
69938fd1498Szrj #else
70038fd1498Szrj       template<typename _InputIterator>
70138fd1498Szrj 	vector(_InputIterator __first, _InputIterator __last,
70238fd1498Szrj 	       const allocator_type& __a = allocator_type())
70338fd1498Szrj 	: _Base(__a)
70438fd1498Szrj 	{
70538fd1498Szrj 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
70638fd1498Szrj 	  _M_initialize_dispatch(__first, __last, _Integral());
70738fd1498Szrj 	}
70838fd1498Szrj #endif
70938fd1498Szrj 
71038fd1498Szrj       ~vector() _GLIBCXX_NOEXCEPT { }
71138fd1498Szrj 
71238fd1498Szrj       vector&
71338fd1498Szrj       operator=(const vector& __x)
71438fd1498Szrj       {
71538fd1498Szrj 	if (&__x == this)
71638fd1498Szrj 	  return *this;
71738fd1498Szrj #if __cplusplus >= 201103L
71838fd1498Szrj 	if (_Bit_alloc_traits::_S_propagate_on_copy_assign())
71938fd1498Szrj 	  {
72038fd1498Szrj 	    if (this->_M_get_Bit_allocator() != __x._M_get_Bit_allocator())
72138fd1498Szrj 	      {
72238fd1498Szrj 		this->_M_deallocate();
72338fd1498Szrj 		std::__alloc_on_copy(_M_get_Bit_allocator(),
72438fd1498Szrj 				     __x._M_get_Bit_allocator());
72538fd1498Szrj 		_M_initialize(__x.size());
72638fd1498Szrj 	      }
72738fd1498Szrj 	    else
72838fd1498Szrj 	      std::__alloc_on_copy(_M_get_Bit_allocator(),
72938fd1498Szrj 				   __x._M_get_Bit_allocator());
73038fd1498Szrj 	  }
73138fd1498Szrj #endif
73238fd1498Szrj 	if (__x.size() > capacity())
73338fd1498Szrj 	  {
73438fd1498Szrj 	    this->_M_deallocate();
73538fd1498Szrj 	    _M_initialize(__x.size());
73638fd1498Szrj 	  }
73738fd1498Szrj 	this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
73838fd1498Szrj 						  begin());
73938fd1498Szrj 	return *this;
74038fd1498Szrj       }
74138fd1498Szrj 
74238fd1498Szrj #if __cplusplus >= 201103L
74338fd1498Szrj       vector&
74438fd1498Szrj       operator=(vector&& __x) noexcept(_Bit_alloc_traits::_S_nothrow_move())
74538fd1498Szrj       {
74638fd1498Szrj 	if (_Bit_alloc_traits::_S_propagate_on_move_assign()
74738fd1498Szrj 	    || this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator())
74838fd1498Szrj 	  {
74938fd1498Szrj 	    this->_M_deallocate();
75038fd1498Szrj 	    this->_M_move_data(std::move(__x));
75138fd1498Szrj 	    std::__alloc_on_move(_M_get_Bit_allocator(),
75238fd1498Szrj 				 __x._M_get_Bit_allocator());
75338fd1498Szrj 	  }
75438fd1498Szrj 	else
75538fd1498Szrj 	  {
75638fd1498Szrj 	    if (__x.size() > capacity())
75738fd1498Szrj 	      {
75838fd1498Szrj 		this->_M_deallocate();
75938fd1498Szrj 		_M_initialize(__x.size());
76038fd1498Szrj 	      }
76138fd1498Szrj 	    this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
76238fd1498Szrj 						      begin());
76338fd1498Szrj 	    __x.clear();
76438fd1498Szrj 	  }
76538fd1498Szrj 	return *this;
76638fd1498Szrj       }
76738fd1498Szrj 
76838fd1498Szrj       vector&
76938fd1498Szrj       operator=(initializer_list<bool> __l)
77038fd1498Szrj       {
77138fd1498Szrj 	this->assign (__l.begin(), __l.end());
77238fd1498Szrj 	return *this;
77338fd1498Szrj       }
77438fd1498Szrj #endif
77538fd1498Szrj 
77638fd1498Szrj       // assign(), a generalized assignment member function.  Two
77738fd1498Szrj       // versions: one that takes a count, and one that takes a range.
77838fd1498Szrj       // The range version is a member template, so we dispatch on whether
77938fd1498Szrj       // or not the type is an integer.
78038fd1498Szrj       void
78138fd1498Szrj       assign(size_type __n, const bool& __x)
78238fd1498Szrj       { _M_fill_assign(__n, __x); }
78338fd1498Szrj 
78438fd1498Szrj #if __cplusplus >= 201103L
78538fd1498Szrj       template<typename _InputIterator,
78638fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
78738fd1498Szrj 	void
78838fd1498Szrj 	assign(_InputIterator __first, _InputIterator __last)
78938fd1498Szrj 	{ _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
79038fd1498Szrj #else
79138fd1498Szrj       template<typename _InputIterator>
79238fd1498Szrj 	void
79338fd1498Szrj 	assign(_InputIterator __first, _InputIterator __last)
79438fd1498Szrj 	{
79538fd1498Szrj 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
79638fd1498Szrj 	  _M_assign_dispatch(__first, __last, _Integral());
79738fd1498Szrj 	}
79838fd1498Szrj #endif
79938fd1498Szrj 
80038fd1498Szrj #if __cplusplus >= 201103L
80138fd1498Szrj       void
80238fd1498Szrj       assign(initializer_list<bool> __l)
80338fd1498Szrj       { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); }
80438fd1498Szrj #endif
80538fd1498Szrj 
80638fd1498Szrj       iterator
80738fd1498Szrj       begin() _GLIBCXX_NOEXCEPT
80838fd1498Szrj       { return this->_M_impl._M_start; }
80938fd1498Szrj 
81038fd1498Szrj       const_iterator
81138fd1498Szrj       begin() const _GLIBCXX_NOEXCEPT
81238fd1498Szrj       { return this->_M_impl._M_start; }
81338fd1498Szrj 
81438fd1498Szrj       iterator
81538fd1498Szrj       end() _GLIBCXX_NOEXCEPT
81638fd1498Szrj       { return this->_M_impl._M_finish; }
81738fd1498Szrj 
81838fd1498Szrj       const_iterator
81938fd1498Szrj       end() const _GLIBCXX_NOEXCEPT
82038fd1498Szrj       { return this->_M_impl._M_finish; }
82138fd1498Szrj 
82238fd1498Szrj       reverse_iterator
82338fd1498Szrj       rbegin() _GLIBCXX_NOEXCEPT
82438fd1498Szrj       { return reverse_iterator(end()); }
82538fd1498Szrj 
82638fd1498Szrj       const_reverse_iterator
82738fd1498Szrj       rbegin() const _GLIBCXX_NOEXCEPT
82838fd1498Szrj       { return const_reverse_iterator(end()); }
82938fd1498Szrj 
83038fd1498Szrj       reverse_iterator
83138fd1498Szrj       rend() _GLIBCXX_NOEXCEPT
83238fd1498Szrj       { return reverse_iterator(begin()); }
83338fd1498Szrj 
83438fd1498Szrj       const_reverse_iterator
83538fd1498Szrj       rend() const _GLIBCXX_NOEXCEPT
83638fd1498Szrj       { return const_reverse_iterator(begin()); }
83738fd1498Szrj 
83838fd1498Szrj #if __cplusplus >= 201103L
83938fd1498Szrj       const_iterator
84038fd1498Szrj       cbegin() const noexcept
84138fd1498Szrj       { return this->_M_impl._M_start; }
84238fd1498Szrj 
84338fd1498Szrj       const_iterator
84438fd1498Szrj       cend() const noexcept
84538fd1498Szrj       { return this->_M_impl._M_finish; }
84638fd1498Szrj 
84738fd1498Szrj       const_reverse_iterator
84838fd1498Szrj       crbegin() const noexcept
84938fd1498Szrj       { return const_reverse_iterator(end()); }
85038fd1498Szrj 
85138fd1498Szrj       const_reverse_iterator
85238fd1498Szrj       crend() const noexcept
85338fd1498Szrj       { return const_reverse_iterator(begin()); }
85438fd1498Szrj #endif
85538fd1498Szrj 
85638fd1498Szrj       size_type
85738fd1498Szrj       size() const _GLIBCXX_NOEXCEPT
85838fd1498Szrj       { return size_type(end() - begin()); }
85938fd1498Szrj 
86038fd1498Szrj       size_type
86138fd1498Szrj       max_size() const _GLIBCXX_NOEXCEPT
86238fd1498Szrj       {
86338fd1498Szrj 	const size_type __isize =
86438fd1498Szrj 	  __gnu_cxx::__numeric_traits<difference_type>::__max
86538fd1498Szrj 	  - int(_S_word_bit) + 1;
86638fd1498Szrj 	const size_type __asize
86738fd1498Szrj 	  = _Bit_alloc_traits::max_size(_M_get_Bit_allocator());
86838fd1498Szrj 	return (__asize <= __isize / int(_S_word_bit)
86938fd1498Szrj 		? __asize * int(_S_word_bit) : __isize);
87038fd1498Szrj       }
87138fd1498Szrj 
87238fd1498Szrj       size_type
87338fd1498Szrj       capacity() const _GLIBCXX_NOEXCEPT
87438fd1498Szrj       { return size_type(const_iterator(this->_M_impl._M_end_addr(), 0)
87538fd1498Szrj 			 - begin()); }
87638fd1498Szrj 
87738fd1498Szrj       bool
87838fd1498Szrj       empty() const _GLIBCXX_NOEXCEPT
87938fd1498Szrj       { return begin() == end(); }
88038fd1498Szrj 
88138fd1498Szrj       reference
88238fd1498Szrj       operator[](size_type __n)
88338fd1498Szrj       {
88438fd1498Szrj 	return *iterator(this->_M_impl._M_start._M_p
88538fd1498Szrj 			 + __n / int(_S_word_bit), __n % int(_S_word_bit));
88638fd1498Szrj       }
88738fd1498Szrj 
88838fd1498Szrj       const_reference
88938fd1498Szrj       operator[](size_type __n) const
89038fd1498Szrj       {
89138fd1498Szrj 	return *const_iterator(this->_M_impl._M_start._M_p
89238fd1498Szrj 			     + __n / int(_S_word_bit), __n % int(_S_word_bit));
89338fd1498Szrj       }
89438fd1498Szrj 
89538fd1498Szrj     protected:
89638fd1498Szrj       void
89738fd1498Szrj       _M_range_check(size_type __n) const
89838fd1498Szrj       {
89938fd1498Szrj 	if (__n >= this->size())
90038fd1498Szrj 	  __throw_out_of_range_fmt(__N("vector<bool>::_M_range_check: __n "
90138fd1498Szrj 				       "(which is %zu) >= this->size() "
90238fd1498Szrj 				       "(which is %zu)"),
90338fd1498Szrj 				   __n, this->size());
90438fd1498Szrj       }
90538fd1498Szrj 
90638fd1498Szrj     public:
90738fd1498Szrj       reference
90838fd1498Szrj       at(size_type __n)
90938fd1498Szrj       { _M_range_check(__n); return (*this)[__n]; }
91038fd1498Szrj 
91138fd1498Szrj       const_reference
91238fd1498Szrj       at(size_type __n) const
91338fd1498Szrj       { _M_range_check(__n); return (*this)[__n]; }
91438fd1498Szrj 
91538fd1498Szrj       void
91638fd1498Szrj       reserve(size_type __n)
91738fd1498Szrj       {
91838fd1498Szrj 	if (__n > max_size())
91938fd1498Szrj 	  __throw_length_error(__N("vector::reserve"));
92038fd1498Szrj 	if (capacity() < __n)
92138fd1498Szrj 	  _M_reallocate(__n);
92238fd1498Szrj       }
92338fd1498Szrj 
92438fd1498Szrj       reference
92538fd1498Szrj       front()
92638fd1498Szrj       { return *begin(); }
92738fd1498Szrj 
92838fd1498Szrj       const_reference
92938fd1498Szrj       front() const
93038fd1498Szrj       { return *begin(); }
93138fd1498Szrj 
93238fd1498Szrj       reference
93338fd1498Szrj       back()
93438fd1498Szrj       { return *(end() - 1); }
93538fd1498Szrj 
93638fd1498Szrj       const_reference
93738fd1498Szrj       back() const
93838fd1498Szrj       { return *(end() - 1); }
93938fd1498Szrj 
94038fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
94138fd1498Szrj       // DR 464. Suggestion for new member functions in standard containers.
94238fd1498Szrj       // N.B. DR 464 says nothing about vector<bool> but we need something
94338fd1498Szrj       // here due to the way we are implementing DR 464 in the debug-mode
94438fd1498Szrj       // vector class.
94538fd1498Szrj       void
94638fd1498Szrj       data() _GLIBCXX_NOEXCEPT { }
94738fd1498Szrj 
94838fd1498Szrj       void
94938fd1498Szrj       push_back(bool __x)
95038fd1498Szrj       {
95138fd1498Szrj 	if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr())
95238fd1498Szrj 	  *this->_M_impl._M_finish++ = __x;
95338fd1498Szrj 	else
95438fd1498Szrj 	  _M_insert_aux(end(), __x);
95538fd1498Szrj       }
95638fd1498Szrj 
95738fd1498Szrj       void
95838fd1498Szrj       swap(vector& __x) _GLIBCXX_NOEXCEPT
95938fd1498Szrj       {
96038fd1498Szrj 	std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
96138fd1498Szrj 	std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
96238fd1498Szrj 	std::swap(this->_M_impl._M_end_of_storage,
96338fd1498Szrj 		  __x._M_impl._M_end_of_storage);
96438fd1498Szrj 	_Bit_alloc_traits::_S_on_swap(_M_get_Bit_allocator(),
96538fd1498Szrj 				      __x._M_get_Bit_allocator());
96638fd1498Szrj       }
96738fd1498Szrj 
96838fd1498Szrj       // [23.2.5]/1, third-to-last entry in synopsis listing
96938fd1498Szrj       static void
97038fd1498Szrj       swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT
97138fd1498Szrj       {
97238fd1498Szrj 	bool __tmp = __x;
97338fd1498Szrj 	__x = __y;
97438fd1498Szrj 	__y = __tmp;
97538fd1498Szrj       }
97638fd1498Szrj 
97738fd1498Szrj       iterator
97838fd1498Szrj #if __cplusplus >= 201103L
97938fd1498Szrj       insert(const_iterator __position, const bool& __x = bool())
98038fd1498Szrj #else
98138fd1498Szrj       insert(iterator __position, const bool& __x = bool())
98238fd1498Szrj #endif
98338fd1498Szrj       {
98438fd1498Szrj 	const difference_type __n = __position - begin();
98538fd1498Szrj 	if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()
98638fd1498Szrj 	    && __position == end())
98738fd1498Szrj 	  *this->_M_impl._M_finish++ = __x;
98838fd1498Szrj 	else
98938fd1498Szrj 	  _M_insert_aux(__position._M_const_cast(), __x);
99038fd1498Szrj 	return begin() + __n;
99138fd1498Szrj       }
99238fd1498Szrj 
99338fd1498Szrj #if __cplusplus >= 201103L
99438fd1498Szrj       template<typename _InputIterator,
99538fd1498Szrj 	       typename = std::_RequireInputIter<_InputIterator>>
99638fd1498Szrj 	iterator
99738fd1498Szrj 	insert(const_iterator __position,
99838fd1498Szrj 	       _InputIterator __first, _InputIterator __last)
99938fd1498Szrj 	{
100038fd1498Szrj 	  difference_type __offset = __position - cbegin();
100138fd1498Szrj 	  _M_insert_dispatch(__position._M_const_cast(),
100238fd1498Szrj 			     __first, __last, __false_type());
100338fd1498Szrj 	  return begin() + __offset;
100438fd1498Szrj 	}
100538fd1498Szrj #else
100638fd1498Szrj       template<typename _InputIterator>
100738fd1498Szrj 	void
100838fd1498Szrj 	insert(iterator __position,
100938fd1498Szrj 	       _InputIterator __first, _InputIterator __last)
101038fd1498Szrj 	{
101138fd1498Szrj 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
101238fd1498Szrj 	  _M_insert_dispatch(__position, __first, __last, _Integral());
101338fd1498Szrj 	}
101438fd1498Szrj #endif
101538fd1498Szrj 
101638fd1498Szrj #if __cplusplus >= 201103L
101738fd1498Szrj       iterator
101838fd1498Szrj       insert(const_iterator __position, size_type __n, const bool& __x)
101938fd1498Szrj       {
102038fd1498Szrj 	difference_type __offset = __position - cbegin();
102138fd1498Szrj 	_M_fill_insert(__position._M_const_cast(), __n, __x);
102238fd1498Szrj 	return begin() + __offset;
102338fd1498Szrj       }
102438fd1498Szrj #else
102538fd1498Szrj       void
102638fd1498Szrj       insert(iterator __position, size_type __n, const bool& __x)
102738fd1498Szrj       { _M_fill_insert(__position, __n, __x); }
102838fd1498Szrj #endif
102938fd1498Szrj 
103038fd1498Szrj #if __cplusplus >= 201103L
103138fd1498Szrj       iterator
103238fd1498Szrj       insert(const_iterator __p, initializer_list<bool> __l)
103338fd1498Szrj       { return this->insert(__p, __l.begin(), __l.end()); }
103438fd1498Szrj #endif
103538fd1498Szrj 
103638fd1498Szrj       void
103738fd1498Szrj       pop_back()
103838fd1498Szrj       { --this->_M_impl._M_finish; }
103938fd1498Szrj 
104038fd1498Szrj       iterator
104138fd1498Szrj #if __cplusplus >= 201103L
104238fd1498Szrj       erase(const_iterator __position)
104338fd1498Szrj #else
104438fd1498Szrj       erase(iterator __position)
104538fd1498Szrj #endif
104638fd1498Szrj       { return _M_erase(__position._M_const_cast()); }
104738fd1498Szrj 
104838fd1498Szrj       iterator
104938fd1498Szrj #if __cplusplus >= 201103L
105038fd1498Szrj       erase(const_iterator __first, const_iterator __last)
105138fd1498Szrj #else
105238fd1498Szrj       erase(iterator __first, iterator __last)
105338fd1498Szrj #endif
105438fd1498Szrj       { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); }
105538fd1498Szrj 
105638fd1498Szrj       void
105738fd1498Szrj       resize(size_type __new_size, bool __x = bool())
105838fd1498Szrj       {
105938fd1498Szrj 	if (__new_size < size())
106038fd1498Szrj 	  _M_erase_at_end(begin() + difference_type(__new_size));
106138fd1498Szrj 	else
106238fd1498Szrj 	  insert(end(), __new_size - size(), __x);
106338fd1498Szrj       }
106438fd1498Szrj 
106538fd1498Szrj #if __cplusplus >= 201103L
106638fd1498Szrj       void
106738fd1498Szrj       shrink_to_fit()
106838fd1498Szrj       { _M_shrink_to_fit(); }
106938fd1498Szrj #endif
107038fd1498Szrj 
107138fd1498Szrj       void
107238fd1498Szrj       flip() _GLIBCXX_NOEXCEPT
107338fd1498Szrj       {
107438fd1498Szrj 	_Bit_type * const __end = this->_M_impl._M_end_addr();
107538fd1498Szrj 	for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != __end; ++__p)
107638fd1498Szrj 	  *__p = ~*__p;
107738fd1498Szrj       }
107838fd1498Szrj 
107938fd1498Szrj       void
108038fd1498Szrj       clear() _GLIBCXX_NOEXCEPT
108138fd1498Szrj       { _M_erase_at_end(begin()); }
108238fd1498Szrj 
108338fd1498Szrj #if __cplusplus >= 201103L
108438fd1498Szrj       template<typename... _Args>
108538fd1498Szrj #if __cplusplus > 201402L
108638fd1498Szrj 	reference
108738fd1498Szrj #else
108838fd1498Szrj 	void
108938fd1498Szrj #endif
109038fd1498Szrj 	emplace_back(_Args&&... __args)
109138fd1498Szrj 	{
109238fd1498Szrj 	  push_back(bool(__args...));
109338fd1498Szrj #if __cplusplus > 201402L
109438fd1498Szrj 	  return back();
109538fd1498Szrj #endif
109638fd1498Szrj 	}
109738fd1498Szrj 
109838fd1498Szrj       template<typename... _Args>
109938fd1498Szrj 	iterator
110038fd1498Szrj 	emplace(const_iterator __pos, _Args&&... __args)
110138fd1498Szrj 	{ return insert(__pos, bool(__args...)); }
110238fd1498Szrj #endif
110338fd1498Szrj 
110438fd1498Szrj     protected:
110538fd1498Szrj       // Precondition: __first._M_offset == 0 && __result._M_offset == 0.
110638fd1498Szrj       iterator
110738fd1498Szrj       _M_copy_aligned(const_iterator __first, const_iterator __last,
110838fd1498Szrj 		      iterator __result)
110938fd1498Szrj       {
111038fd1498Szrj 	_Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p);
111138fd1498Szrj 	return std::copy(const_iterator(__last._M_p, 0), __last,
111238fd1498Szrj 			 iterator(__q, 0));
111338fd1498Szrj       }
111438fd1498Szrj 
111538fd1498Szrj       void
111638fd1498Szrj       _M_initialize(size_type __n)
111738fd1498Szrj       {
111838fd1498Szrj 	if (__n)
111938fd1498Szrj 	  {
112038fd1498Szrj 	    _Bit_pointer __q = this->_M_allocate(__n);
112138fd1498Szrj 	    this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
112238fd1498Szrj 	    this->_M_impl._M_start = iterator(std::__addressof(*__q), 0);
112338fd1498Szrj 	  }
112438fd1498Szrj 	else
112538fd1498Szrj 	  {
112638fd1498Szrj 	    this->_M_impl._M_end_of_storage = _Bit_pointer();
112738fd1498Szrj 	    this->_M_impl._M_start = iterator(0, 0);
112838fd1498Szrj 	  }
112938fd1498Szrj 	this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
113038fd1498Szrj 
113138fd1498Szrj       }
113238fd1498Szrj 
113338fd1498Szrj       void
113438fd1498Szrj       _M_initialize_value(bool __x)
113538fd1498Szrj       {
113638fd1498Szrj 	if (_Bit_type* __p = this->_M_impl._M_start._M_p)
113738fd1498Szrj 	  __builtin_memset(__p, __x ? ~0 : 0,
113838fd1498Szrj 			   (this->_M_impl._M_end_addr() - __p)
113938fd1498Szrj 			   * sizeof(_Bit_type));
114038fd1498Szrj       }
114138fd1498Szrj 
114238fd1498Szrj       void
114338fd1498Szrj       _M_reallocate(size_type __n);
114438fd1498Szrj 
114538fd1498Szrj #if __cplusplus >= 201103L
114638fd1498Szrj       bool
114738fd1498Szrj       _M_shrink_to_fit();
114838fd1498Szrj #endif
114938fd1498Szrj 
115038fd1498Szrj       // Check whether it's an integral type.  If so, it's not an iterator.
115138fd1498Szrj 
115238fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
115338fd1498Szrj       // 438. Ambiguity in the "do the right thing" clause
115438fd1498Szrj       template<typename _Integer>
115538fd1498Szrj 	void
115638fd1498Szrj 	_M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
115738fd1498Szrj 	{
115838fd1498Szrj 	  _M_initialize(static_cast<size_type>(__n));
115938fd1498Szrj 	  _M_initialize_value(__x);
116038fd1498Szrj 	}
116138fd1498Szrj 
116238fd1498Szrj       template<typename _InputIterator>
116338fd1498Szrj 	void
116438fd1498Szrj 	_M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
116538fd1498Szrj 			       __false_type)
116638fd1498Szrj 	{ _M_initialize_range(__first, __last,
116738fd1498Szrj 			      std::__iterator_category(__first)); }
116838fd1498Szrj 
116938fd1498Szrj       template<typename _InputIterator>
117038fd1498Szrj 	void
117138fd1498Szrj 	_M_initialize_range(_InputIterator __first, _InputIterator __last,
117238fd1498Szrj 			    std::input_iterator_tag)
117338fd1498Szrj 	{
117438fd1498Szrj 	  for (; __first != __last; ++__first)
117538fd1498Szrj 	    push_back(*__first);
117638fd1498Szrj 	}
117738fd1498Szrj 
117838fd1498Szrj       template<typename _ForwardIterator>
117938fd1498Szrj 	void
118038fd1498Szrj 	_M_initialize_range(_ForwardIterator __first, _ForwardIterator __last,
118138fd1498Szrj 			    std::forward_iterator_tag)
118238fd1498Szrj 	{
118338fd1498Szrj 	  const size_type __n = std::distance(__first, __last);
118438fd1498Szrj 	  _M_initialize(__n);
118538fd1498Szrj 	  std::copy(__first, __last, this->_M_impl._M_start);
118638fd1498Szrj 	}
118738fd1498Szrj 
118838fd1498Szrj #if __cplusplus < 201103L
118938fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
119038fd1498Szrj       // 438. Ambiguity in the "do the right thing" clause
119138fd1498Szrj       template<typename _Integer>
119238fd1498Szrj 	void
119338fd1498Szrj 	_M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
119438fd1498Szrj 	{ _M_fill_assign(__n, __val); }
119538fd1498Szrj 
119638fd1498Szrj       template<class _InputIterator>
119738fd1498Szrj 	void
119838fd1498Szrj 	_M_assign_dispatch(_InputIterator __first, _InputIterator __last,
119938fd1498Szrj 			   __false_type)
120038fd1498Szrj 	{ _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
120138fd1498Szrj #endif
120238fd1498Szrj 
120338fd1498Szrj       void
120438fd1498Szrj       _M_fill_assign(size_t __n, bool __x)
120538fd1498Szrj       {
120638fd1498Szrj 	if (__n > size())
120738fd1498Szrj 	  {
120838fd1498Szrj 	    _M_initialize_value(__x);
120938fd1498Szrj 	    insert(end(), __n - size(), __x);
121038fd1498Szrj 	  }
121138fd1498Szrj 	else
121238fd1498Szrj 	  {
121338fd1498Szrj 	    _M_erase_at_end(begin() + __n);
121438fd1498Szrj 	    _M_initialize_value(__x);
121538fd1498Szrj 	  }
121638fd1498Szrj       }
121738fd1498Szrj 
121838fd1498Szrj       template<typename _InputIterator>
121938fd1498Szrj 	void
122038fd1498Szrj 	_M_assign_aux(_InputIterator __first, _InputIterator __last,
122138fd1498Szrj 		      std::input_iterator_tag)
122238fd1498Szrj 	{
122338fd1498Szrj 	  iterator __cur = begin();
122438fd1498Szrj 	  for (; __first != __last && __cur != end(); ++__cur, ++__first)
122538fd1498Szrj 	    *__cur = *__first;
122638fd1498Szrj 	  if (__first == __last)
122738fd1498Szrj 	    _M_erase_at_end(__cur);
122838fd1498Szrj 	  else
122938fd1498Szrj 	    insert(end(), __first, __last);
123038fd1498Szrj 	}
123138fd1498Szrj 
123238fd1498Szrj       template<typename _ForwardIterator>
123338fd1498Szrj 	void
123438fd1498Szrj 	_M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
123538fd1498Szrj 		      std::forward_iterator_tag)
123638fd1498Szrj 	{
123738fd1498Szrj 	  const size_type __len = std::distance(__first, __last);
123838fd1498Szrj 	  if (__len < size())
123938fd1498Szrj 	    _M_erase_at_end(std::copy(__first, __last, begin()));
124038fd1498Szrj 	  else
124138fd1498Szrj 	    {
124238fd1498Szrj 	      _ForwardIterator __mid = __first;
124338fd1498Szrj 	      std::advance(__mid, size());
124438fd1498Szrj 	      std::copy(__first, __mid, begin());
124538fd1498Szrj 	      insert(end(), __mid, __last);
124638fd1498Szrj 	    }
124738fd1498Szrj 	}
124838fd1498Szrj 
124938fd1498Szrj       // Check whether it's an integral type.  If so, it's not an iterator.
125038fd1498Szrj 
125138fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
125238fd1498Szrj       // 438. Ambiguity in the "do the right thing" clause
125338fd1498Szrj       template<typename _Integer>
125438fd1498Szrj 	void
125538fd1498Szrj 	_M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
125638fd1498Szrj 			   __true_type)
125738fd1498Szrj 	{ _M_fill_insert(__pos, __n, __x); }
125838fd1498Szrj 
125938fd1498Szrj       template<typename _InputIterator>
126038fd1498Szrj 	void
126138fd1498Szrj 	_M_insert_dispatch(iterator __pos,
126238fd1498Szrj 			   _InputIterator __first, _InputIterator __last,
126338fd1498Szrj 			   __false_type)
126438fd1498Szrj 	{ _M_insert_range(__pos, __first, __last,
126538fd1498Szrj 			  std::__iterator_category(__first)); }
126638fd1498Szrj 
126738fd1498Szrj       void
126838fd1498Szrj       _M_fill_insert(iterator __position, size_type __n, bool __x);
126938fd1498Szrj 
127038fd1498Szrj       template<typename _InputIterator>
127138fd1498Szrj 	void
127238fd1498Szrj 	_M_insert_range(iterator __pos, _InputIterator __first,
127338fd1498Szrj 			_InputIterator __last, std::input_iterator_tag)
127438fd1498Szrj 	{
127538fd1498Szrj 	  for (; __first != __last; ++__first)
127638fd1498Szrj 	    {
127738fd1498Szrj 	      __pos = insert(__pos, *__first);
127838fd1498Szrj 	      ++__pos;
127938fd1498Szrj 	    }
128038fd1498Szrj 	}
128138fd1498Szrj 
128238fd1498Szrj       template<typename _ForwardIterator>
128338fd1498Szrj 	void
128438fd1498Szrj 	_M_insert_range(iterator __position, _ForwardIterator __first,
128538fd1498Szrj 			_ForwardIterator __last, std::forward_iterator_tag);
128638fd1498Szrj 
128738fd1498Szrj       void
128838fd1498Szrj       _M_insert_aux(iterator __position, bool __x);
128938fd1498Szrj 
129038fd1498Szrj       size_type
129138fd1498Szrj       _M_check_len(size_type __n, const char* __s) const
129238fd1498Szrj       {
129338fd1498Szrj 	if (max_size() - size() < __n)
129438fd1498Szrj 	  __throw_length_error(__N(__s));
129538fd1498Szrj 
129638fd1498Szrj 	const size_type __len = size() + std::max(size(), __n);
129738fd1498Szrj 	return (__len < size() || __len > max_size()) ? max_size() : __len;
129838fd1498Szrj       }
129938fd1498Szrj 
130038fd1498Szrj       void
130138fd1498Szrj       _M_erase_at_end(iterator __pos)
130238fd1498Szrj       { this->_M_impl._M_finish = __pos; }
130338fd1498Szrj 
130438fd1498Szrj       iterator
130538fd1498Szrj       _M_erase(iterator __pos);
130638fd1498Szrj 
130738fd1498Szrj       iterator
130838fd1498Szrj       _M_erase(iterator __first, iterator __last);
130938fd1498Szrj   };
131038fd1498Szrj 
131138fd1498Szrj _GLIBCXX_END_NAMESPACE_CONTAINER
131238fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
131338fd1498Szrj } // namespace std
131438fd1498Szrj 
131538fd1498Szrj #if __cplusplus >= 201103L
131638fd1498Szrj 
131738fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
131838fd1498Szrj {
131938fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
132038fd1498Szrj 
132138fd1498Szrj   // DR 1182.
132238fd1498Szrj   /// std::hash specialization for vector<bool>.
132338fd1498Szrj   template<typename _Alloc>
132438fd1498Szrj     struct hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>
132538fd1498Szrj     : public __hash_base<size_t, _GLIBCXX_STD_C::vector<bool, _Alloc>>
132638fd1498Szrj     {
132738fd1498Szrj       size_t
132838fd1498Szrj       operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>&) const noexcept;
132938fd1498Szrj     };
133038fd1498Szrj 
133138fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
133238fd1498Szrj }// namespace std
133338fd1498Szrj 
133438fd1498Szrj #endif // C++11
133538fd1498Szrj 
133638fd1498Szrj #endif
1337