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