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