|
libstdc++
|
00001 // vector<bool> specialization -*- C++ -*- 00002 00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 00004 // 2011, 2012 Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /* 00027 * 00028 * Copyright (c) 1994 00029 * Hewlett-Packard Company 00030 * 00031 * Permission to use, copy, modify, distribute and sell this software 00032 * and its documentation for any purpose is hereby granted without fee, 00033 * provided that the above copyright notice appear in all copies and 00034 * that both that copyright notice and this permission notice appear 00035 * in supporting documentation. Hewlett-Packard Company makes no 00036 * representations about the suitability of this software for any 00037 * purpose. It is provided "as is" without express or implied warranty. 00038 * 00039 * 00040 * Copyright (c) 1996-1999 00041 * Silicon Graphics Computer Systems, Inc. 00042 * 00043 * Permission to use, copy, modify, distribute and sell this software 00044 * and its documentation for any purpose is hereby granted without fee, 00045 * provided that the above copyright notice appear in all copies and 00046 * that both that copyright notice and this permission notice appear 00047 * in supporting documentation. Silicon Graphics makes no 00048 * representations about the suitability of this software for any 00049 * purpose. It is provided "as is" without express or implied warranty. 00050 */ 00051 00052 /** @file bits/stl_bvector.h 00053 * This is an internal header file, included by other library headers. 00054 * Do not attempt to use it directly. @headername{vector} 00055 */ 00056 00057 #ifndef _STL_BVECTOR_H 00058 #define _STL_BVECTOR_H 1 00059 00060 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00061 #include <initializer_list> 00062 #endif 00063 00064 namespace std _GLIBCXX_VISIBILITY(default) 00065 { 00066 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 00067 00068 typedef unsigned long _Bit_type; 00069 enum { _S_word_bit = int(__CHAR_BIT__ * sizeof(_Bit_type)) }; 00070 00071 struct _Bit_reference 00072 { 00073 _Bit_type * _M_p; 00074 _Bit_type _M_mask; 00075 00076 _Bit_reference(_Bit_type * __x, _Bit_type __y) 00077 : _M_p(__x), _M_mask(__y) { } 00078 00079 _Bit_reference() _GLIBCXX_NOEXCEPT : _M_p(0), _M_mask(0) { } 00080 00081 operator bool() const _GLIBCXX_NOEXCEPT 00082 { return !!(*_M_p & _M_mask); } 00083 00084 _Bit_reference& 00085 operator=(bool __x) _GLIBCXX_NOEXCEPT 00086 { 00087 if (__x) 00088 *_M_p |= _M_mask; 00089 else 00090 *_M_p &= ~_M_mask; 00091 return *this; 00092 } 00093 00094 _Bit_reference& 00095 operator=(const _Bit_reference& __x) _GLIBCXX_NOEXCEPT 00096 { return *this = bool(__x); } 00097 00098 bool 00099 operator==(const _Bit_reference& __x) const 00100 { return bool(*this) == bool(__x); } 00101 00102 bool 00103 operator<(const _Bit_reference& __x) const 00104 { return !bool(*this) && bool(__x); } 00105 00106 void 00107 flip() _GLIBCXX_NOEXCEPT 00108 { *_M_p ^= _M_mask; } 00109 }; 00110 00111 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00112 inline void 00113 swap(_Bit_reference __x, _Bit_reference __y) noexcept 00114 { 00115 bool __tmp = __x; 00116 __x = __y; 00117 __y = __tmp; 00118 } 00119 00120 inline void 00121 swap(_Bit_reference __x, bool& __y) noexcept 00122 { 00123 bool __tmp = __x; 00124 __x = __y; 00125 __y = __tmp; 00126 } 00127 00128 inline void 00129 swap(bool& __x, _Bit_reference __y) noexcept 00130 { 00131 bool __tmp = __x; 00132 __x = __y; 00133 __y = __tmp; 00134 } 00135 #endif 00136 00137 struct _Bit_iterator_base 00138 : public std::iterator<std::random_access_iterator_tag, bool> 00139 { 00140 _Bit_type * _M_p; 00141 unsigned int _M_offset; 00142 00143 _Bit_iterator_base(_Bit_type * __x, unsigned int __y) 00144 : _M_p(__x), _M_offset(__y) { } 00145 00146 void 00147 _M_bump_up() 00148 { 00149 if (_M_offset++ == int(_S_word_bit) - 1) 00150 { 00151 _M_offset = 0; 00152 ++_M_p; 00153 } 00154 } 00155 00156 void 00157 _M_bump_down() 00158 { 00159 if (_M_offset-- == 0) 00160 { 00161 _M_offset = int(_S_word_bit) - 1; 00162 --_M_p; 00163 } 00164 } 00165 00166 void 00167 _M_incr(ptrdiff_t __i) 00168 { 00169 difference_type __n = __i + _M_offset; 00170 _M_p += __n / int(_S_word_bit); 00171 __n = __n % int(_S_word_bit); 00172 if (__n < 0) 00173 { 00174 __n += int(_S_word_bit); 00175 --_M_p; 00176 } 00177 _M_offset = static_cast<unsigned int>(__n); 00178 } 00179 00180 bool 00181 operator==(const _Bit_iterator_base& __i) const 00182 { return _M_p == __i._M_p && _M_offset == __i._M_offset; } 00183 00184 bool 00185 operator<(const _Bit_iterator_base& __i) const 00186 { 00187 return _M_p < __i._M_p 00188 || (_M_p == __i._M_p && _M_offset < __i._M_offset); 00189 } 00190 00191 bool 00192 operator!=(const _Bit_iterator_base& __i) const 00193 { return !(*this == __i); } 00194 00195 bool 00196 operator>(const _Bit_iterator_base& __i) const 00197 { return __i < *this; } 00198 00199 bool 00200 operator<=(const _Bit_iterator_base& __i) const 00201 { return !(__i < *this); } 00202 00203 bool 00204 operator>=(const _Bit_iterator_base& __i) const 00205 { return !(*this < __i); } 00206 }; 00207 00208 inline ptrdiff_t 00209 operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) 00210 { 00211 return (int(_S_word_bit) * (__x._M_p - __y._M_p) 00212 + __x._M_offset - __y._M_offset); 00213 } 00214 00215 struct _Bit_iterator : public _Bit_iterator_base 00216 { 00217 typedef _Bit_reference reference; 00218 typedef _Bit_reference* pointer; 00219 typedef _Bit_iterator iterator; 00220 00221 _Bit_iterator() : _Bit_iterator_base(0, 0) { } 00222 00223 _Bit_iterator(_Bit_type * __x, unsigned int __y) 00224 : _Bit_iterator_base(__x, __y) { } 00225 00226 reference 00227 operator*() const 00228 { return reference(_M_p, 1UL << _M_offset); } 00229 00230 iterator& 00231 operator++() 00232 { 00233 _M_bump_up(); 00234 return *this; 00235 } 00236 00237 iterator 00238 operator++(int) 00239 { 00240 iterator __tmp = *this; 00241 _M_bump_up(); 00242 return __tmp; 00243 } 00244 00245 iterator& 00246 operator--() 00247 { 00248 _M_bump_down(); 00249 return *this; 00250 } 00251 00252 iterator 00253 operator--(int) 00254 { 00255 iterator __tmp = *this; 00256 _M_bump_down(); 00257 return __tmp; 00258 } 00259 00260 iterator& 00261 operator+=(difference_type __i) 00262 { 00263 _M_incr(__i); 00264 return *this; 00265 } 00266 00267 iterator& 00268 operator-=(difference_type __i) 00269 { 00270 *this += -__i; 00271 return *this; 00272 } 00273 00274 iterator 00275 operator+(difference_type __i) const 00276 { 00277 iterator __tmp = *this; 00278 return __tmp += __i; 00279 } 00280 00281 iterator 00282 operator-(difference_type __i) const 00283 { 00284 iterator __tmp = *this; 00285 return __tmp -= __i; 00286 } 00287 00288 reference 00289 operator[](difference_type __i) const 00290 { return *(*this + __i); } 00291 }; 00292 00293 inline _Bit_iterator 00294 operator+(ptrdiff_t __n, const _Bit_iterator& __x) 00295 { return __x + __n; } 00296 00297 struct _Bit_const_iterator : public _Bit_iterator_base 00298 { 00299 typedef bool reference; 00300 typedef bool const_reference; 00301 typedef const bool* pointer; 00302 typedef _Bit_const_iterator const_iterator; 00303 00304 _Bit_const_iterator() : _Bit_iterator_base(0, 0) { } 00305 00306 _Bit_const_iterator(_Bit_type * __x, unsigned int __y) 00307 : _Bit_iterator_base(__x, __y) { } 00308 00309 _Bit_const_iterator(const _Bit_iterator& __x) 00310 : _Bit_iterator_base(__x._M_p, __x._M_offset) { } 00311 00312 const_reference 00313 operator*() const 00314 { return _Bit_reference(_M_p, 1UL << _M_offset); } 00315 00316 const_iterator& 00317 operator++() 00318 { 00319 _M_bump_up(); 00320 return *this; 00321 } 00322 00323 const_iterator 00324 operator++(int) 00325 { 00326 const_iterator __tmp = *this; 00327 _M_bump_up(); 00328 return __tmp; 00329 } 00330 00331 const_iterator& 00332 operator--() 00333 { 00334 _M_bump_down(); 00335 return *this; 00336 } 00337 00338 const_iterator 00339 operator--(int) 00340 { 00341 const_iterator __tmp = *this; 00342 _M_bump_down(); 00343 return __tmp; 00344 } 00345 00346 const_iterator& 00347 operator+=(difference_type __i) 00348 { 00349 _M_incr(__i); 00350 return *this; 00351 } 00352 00353 const_iterator& 00354 operator-=(difference_type __i) 00355 { 00356 *this += -__i; 00357 return *this; 00358 } 00359 00360 const_iterator 00361 operator+(difference_type __i) const 00362 { 00363 const_iterator __tmp = *this; 00364 return __tmp += __i; 00365 } 00366 00367 const_iterator 00368 operator-(difference_type __i) const 00369 { 00370 const_iterator __tmp = *this; 00371 return __tmp -= __i; 00372 } 00373 00374 const_reference 00375 operator[](difference_type __i) const 00376 { return *(*this + __i); } 00377 }; 00378 00379 inline _Bit_const_iterator 00380 operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) 00381 { return __x + __n; } 00382 00383 inline void 00384 __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x) 00385 { 00386 for (; __first != __last; ++__first) 00387 *__first = __x; 00388 } 00389 00390 inline void 00391 fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x) 00392 { 00393 if (__first._M_p != __last._M_p) 00394 { 00395 std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0); 00396 __fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x); 00397 __fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x); 00398 } 00399 else 00400 __fill_bvector(__first, __last, __x); 00401 } 00402 00403 template<typename _Alloc> 00404 struct _Bvector_base 00405 { 00406 typedef typename _Alloc::template rebind<_Bit_type>::other 00407 _Bit_alloc_type; 00408 00409 struct _Bvector_impl 00410 : public _Bit_alloc_type 00411 { 00412 _Bit_iterator _M_start; 00413 _Bit_iterator _M_finish; 00414 _Bit_type* _M_end_of_storage; 00415 00416 _Bvector_impl() 00417 : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage(0) 00418 { } 00419 00420 _Bvector_impl(const _Bit_alloc_type& __a) 00421 : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) 00422 { } 00423 00424 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00425 _Bvector_impl(_Bit_alloc_type&& __a) 00426 : _Bit_alloc_type(std::move(__a)), _M_start(), _M_finish(), 00427 _M_end_of_storage(0) 00428 { } 00429 #endif 00430 }; 00431 00432 public: 00433 typedef _Alloc allocator_type; 00434 00435 _Bit_alloc_type& 00436 _M_get_Bit_allocator() _GLIBCXX_NOEXCEPT 00437 { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); } 00438 00439 const _Bit_alloc_type& 00440 _M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT 00441 { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); } 00442 00443 allocator_type 00444 get_allocator() const _GLIBCXX_NOEXCEPT 00445 { return allocator_type(_M_get_Bit_allocator()); } 00446 00447 _Bvector_base() 00448 : _M_impl() { } 00449 00450 _Bvector_base(const allocator_type& __a) 00451 : _M_impl(__a) { } 00452 00453 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00454 _Bvector_base(_Bvector_base&& __x) noexcept 00455 : _M_impl(std::move(__x._M_get_Bit_allocator())) 00456 { 00457 this->_M_impl._M_start = __x._M_impl._M_start; 00458 this->_M_impl._M_finish = __x._M_impl._M_finish; 00459 this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage; 00460 __x._M_impl._M_start = _Bit_iterator(); 00461 __x._M_impl._M_finish = _Bit_iterator(); 00462 __x._M_impl._M_end_of_storage = 0; 00463 } 00464 #endif 00465 00466 ~_Bvector_base() 00467 { this->_M_deallocate(); } 00468 00469 protected: 00470 _Bvector_impl _M_impl; 00471 00472 _Bit_type* 00473 _M_allocate(size_t __n) 00474 { return _M_impl.allocate(_S_nword(__n)); } 00475 00476 void 00477 _M_deallocate() 00478 { 00479 if (_M_impl._M_start._M_p) 00480 _M_impl.deallocate(_M_impl._M_start._M_p, 00481 _M_impl._M_end_of_storage - _M_impl._M_start._M_p); 00482 } 00483 00484 static size_t 00485 _S_nword(size_t __n) 00486 { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); } 00487 }; 00488 00489 _GLIBCXX_END_NAMESPACE_CONTAINER 00490 } // namespace std 00491 00492 // Declare a partial specialization of vector<T, Alloc>. 00493 #include <bits/stl_vector.h> 00494 00495 namespace std _GLIBCXX_VISIBILITY(default) 00496 { 00497 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 00498 00499 /** 00500 * @brief A specialization of vector for booleans which offers fixed time 00501 * access to individual elements in any order. 00502 * 00503 * @ingroup sequences 00504 * 00505 * @tparam _Alloc Allocator type. 00506 * 00507 * Note that vector<bool> does not actually meet the requirements for being 00508 * a container. This is because the reference and pointer types are not 00509 * really references and pointers to bool. See DR96 for details. @see 00510 * vector for function documentation. 00511 * 00512 * In some terminology a %vector can be described as a dynamic 00513 * C-style array, it offers fast and efficient access to individual 00514 * elements in any order and saves the user from worrying about 00515 * memory and size allocation. Subscripting ( @c [] ) access is 00516 * also provided as with C-style arrays. 00517 */ 00518 template<typename _Alloc> 00519 class vector<bool, _Alloc> : protected _Bvector_base<_Alloc> 00520 { 00521 typedef _Bvector_base<_Alloc> _Base; 00522 00523 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00524 template<typename> friend class hash; 00525 #endif 00526 00527 public: 00528 typedef bool value_type; 00529 typedef size_t size_type; 00530 typedef ptrdiff_t difference_type; 00531 typedef _Bit_reference reference; 00532 typedef bool const_reference; 00533 typedef _Bit_reference* pointer; 00534 typedef const bool* const_pointer; 00535 typedef _Bit_iterator iterator; 00536 typedef _Bit_const_iterator const_iterator; 00537 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00538 typedef std::reverse_iterator<iterator> reverse_iterator; 00539 typedef _Alloc allocator_type; 00540 00541 allocator_type get_allocator() const 00542 { return _Base::get_allocator(); } 00543 00544 protected: 00545 using _Base::_M_allocate; 00546 using _Base::_M_deallocate; 00547 using _Base::_S_nword; 00548 using _Base::_M_get_Bit_allocator; 00549 00550 public: 00551 vector() 00552 : _Base() { } 00553 00554 explicit 00555 vector(const allocator_type& __a) 00556 : _Base(__a) { } 00557 00558 explicit 00559 vector(size_type __n, const bool& __value = bool(), 00560 const allocator_type& __a = allocator_type()) 00561 : _Base(__a) 00562 { 00563 _M_initialize(__n); 00564 std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage, 00565 __value ? ~0 : 0); 00566 } 00567 00568 vector(const vector& __x) 00569 : _Base(__x._M_get_Bit_allocator()) 00570 { 00571 _M_initialize(__x.size()); 00572 _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start); 00573 } 00574 00575 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00576 vector(vector&& __x) noexcept 00577 : _Base(std::move(__x)) { } 00578 00579 vector(initializer_list<bool> __l, 00580 const allocator_type& __a = allocator_type()) 00581 : _Base(__a) 00582 { 00583 _M_initialize_range(__l.begin(), __l.end(), 00584 random_access_iterator_tag()); 00585 } 00586 #endif 00587 00588 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00589 template<typename _InputIterator, 00590 typename = std::_RequireInputIter<_InputIterator>> 00591 vector(_InputIterator __first, _InputIterator __last, 00592 const allocator_type& __a = allocator_type()) 00593 : _Base(__a) 00594 { _M_initialize_dispatch(__first, __last, __false_type()); } 00595 #else 00596 template<typename _InputIterator> 00597 vector(_InputIterator __first, _InputIterator __last, 00598 const allocator_type& __a = allocator_type()) 00599 : _Base(__a) 00600 { 00601 typedef typename std::__is_integer<_InputIterator>::__type _Integral; 00602 _M_initialize_dispatch(__first, __last, _Integral()); 00603 } 00604 #endif 00605 00606 ~vector() _GLIBCXX_NOEXCEPT { } 00607 00608 vector& 00609 operator=(const vector& __x) 00610 { 00611 if (&__x == this) 00612 return *this; 00613 if (__x.size() > capacity()) 00614 { 00615 this->_M_deallocate(); 00616 _M_initialize(__x.size()); 00617 } 00618 this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), 00619 begin()); 00620 return *this; 00621 } 00622 00623 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00624 vector& 00625 operator=(vector&& __x) 00626 { 00627 // NB: DR 1204. 00628 // NB: DR 675. 00629 this->clear(); 00630 this->swap(__x); 00631 return *this; 00632 } 00633 00634 vector& 00635 operator=(initializer_list<bool> __l) 00636 { 00637 this->assign (__l.begin(), __l.end()); 00638 return *this; 00639 } 00640 #endif 00641 00642 // assign(), a generalized assignment member function. Two 00643 // versions: one that takes a count, and one that takes a range. 00644 // The range version is a member template, so we dispatch on whether 00645 // or not the type is an integer. 00646 void 00647 assign(size_type __n, const bool& __x) 00648 { _M_fill_assign(__n, __x); } 00649 00650 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00651 template<typename _InputIterator, 00652 typename = std::_RequireInputIter<_InputIterator>> 00653 void 00654 assign(_InputIterator __first, _InputIterator __last) 00655 { _M_assign_dispatch(__first, __last, __false_type()); } 00656 #else 00657 template<typename _InputIterator> 00658 void 00659 assign(_InputIterator __first, _InputIterator __last) 00660 { 00661 typedef typename std::__is_integer<_InputIterator>::__type _Integral; 00662 _M_assign_dispatch(__first, __last, _Integral()); 00663 } 00664 #endif 00665 00666 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00667 void 00668 assign(initializer_list<bool> __l) 00669 { this->assign(__l.begin(), __l.end()); } 00670 #endif 00671 00672 iterator 00673 begin() _GLIBCXX_NOEXCEPT 00674 { return this->_M_impl._M_start; } 00675 00676 const_iterator 00677 begin() const _GLIBCXX_NOEXCEPT 00678 { return this->_M_impl._M_start; } 00679 00680 iterator 00681 end() _GLIBCXX_NOEXCEPT 00682 { return this->_M_impl._M_finish; } 00683 00684 const_iterator 00685 end() const _GLIBCXX_NOEXCEPT 00686 { return this->_M_impl._M_finish; } 00687 00688 reverse_iterator 00689 rbegin() _GLIBCXX_NOEXCEPT 00690 { return reverse_iterator(end()); } 00691 00692 const_reverse_iterator 00693 rbegin() const _GLIBCXX_NOEXCEPT 00694 { return const_reverse_iterator(end()); } 00695 00696 reverse_iterator 00697 rend() _GLIBCXX_NOEXCEPT 00698 { return reverse_iterator(begin()); } 00699 00700 const_reverse_iterator 00701 rend() const _GLIBCXX_NOEXCEPT 00702 { return const_reverse_iterator(begin()); } 00703 00704 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00705 const_iterator 00706 cbegin() const noexcept 00707 { return this->_M_impl._M_start; } 00708 00709 const_iterator 00710 cend() const noexcept 00711 { return this->_M_impl._M_finish; } 00712 00713 const_reverse_iterator 00714 crbegin() const noexcept 00715 { return const_reverse_iterator(end()); } 00716 00717 const_reverse_iterator 00718 crend() const noexcept 00719 { return const_reverse_iterator(begin()); } 00720 #endif 00721 00722 size_type 00723 size() const _GLIBCXX_NOEXCEPT 00724 { return size_type(end() - begin()); } 00725 00726 size_type 00727 max_size() const _GLIBCXX_NOEXCEPT 00728 { 00729 const size_type __isize = 00730 __gnu_cxx::__numeric_traits<difference_type>::__max 00731 - int(_S_word_bit) + 1; 00732 const size_type __asize = _M_get_Bit_allocator().max_size(); 00733 return (__asize <= __isize / int(_S_word_bit) 00734 ? __asize * int(_S_word_bit) : __isize); 00735 } 00736 00737 size_type 00738 capacity() const _GLIBCXX_NOEXCEPT 00739 { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0) 00740 - begin()); } 00741 00742 bool 00743 empty() const _GLIBCXX_NOEXCEPT 00744 { return begin() == end(); } 00745 00746 reference 00747 operator[](size_type __n) 00748 { 00749 return *iterator(this->_M_impl._M_start._M_p 00750 + __n / int(_S_word_bit), __n % int(_S_word_bit)); 00751 } 00752 00753 const_reference 00754 operator[](size_type __n) const 00755 { 00756 return *const_iterator(this->_M_impl._M_start._M_p 00757 + __n / int(_S_word_bit), __n % int(_S_word_bit)); 00758 } 00759 00760 protected: 00761 void 00762 _M_range_check(size_type __n) const 00763 { 00764 if (__n >= this->size()) 00765 __throw_out_of_range(__N("vector<bool>::_M_range_check")); 00766 } 00767 00768 public: 00769 reference 00770 at(size_type __n) 00771 { _M_range_check(__n); return (*this)[__n]; } 00772 00773 const_reference 00774 at(size_type __n) const 00775 { _M_range_check(__n); return (*this)[__n]; } 00776 00777 void 00778 reserve(size_type __n) 00779 { 00780 if (__n > max_size()) 00781 __throw_length_error(__N("vector::reserve")); 00782 if (capacity() < __n) 00783 _M_reallocate(__n); 00784 } 00785 00786 reference 00787 front() 00788 { return *begin(); } 00789 00790 const_reference 00791 front() const 00792 { return *begin(); } 00793 00794 reference 00795 back() 00796 { return *(end() - 1); } 00797 00798 const_reference 00799 back() const 00800 { return *(end() - 1); } 00801 00802 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00803 // DR 464. Suggestion for new member functions in standard containers. 00804 // N.B. DR 464 says nothing about vector<bool> but we need something 00805 // here due to the way we are implementing DR 464 in the debug-mode 00806 // vector class. 00807 void 00808 data() _GLIBCXX_NOEXCEPT { } 00809 00810 void 00811 push_back(bool __x) 00812 { 00813 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) 00814 *this->_M_impl._M_finish++ = __x; 00815 else 00816 _M_insert_aux(end(), __x); 00817 } 00818 00819 void 00820 swap(vector& __x) 00821 { 00822 std::swap(this->_M_impl._M_start, __x._M_impl._M_start); 00823 std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); 00824 std::swap(this->_M_impl._M_end_of_storage, 00825 __x._M_impl._M_end_of_storage); 00826 00827 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00828 // 431. Swapping containers with unequal allocators. 00829 std::__alloc_swap<typename _Base::_Bit_alloc_type>:: 00830 _S_do_it(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); 00831 } 00832 00833 // [23.2.5]/1, third-to-last entry in synopsis listing 00834 static void 00835 swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT 00836 { 00837 bool __tmp = __x; 00838 __x = __y; 00839 __y = __tmp; 00840 } 00841 00842 iterator 00843 insert(iterator __position, const bool& __x = bool()) 00844 { 00845 const difference_type __n = __position - begin(); 00846 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage 00847 && __position == end()) 00848 *this->_M_impl._M_finish++ = __x; 00849 else 00850 _M_insert_aux(__position, __x); 00851 return begin() + __n; 00852 } 00853 00854 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00855 template<typename _InputIterator, 00856 typename = std::_RequireInputIter<_InputIterator>> 00857 void 00858 insert(iterator __position, 00859 _InputIterator __first, _InputIterator __last) 00860 { _M_insert_dispatch(__position, __first, __last, __false_type()); } 00861 #else 00862 template<typename _InputIterator> 00863 void 00864 insert(iterator __position, 00865 _InputIterator __first, _InputIterator __last) 00866 { 00867 typedef typename std::__is_integer<_InputIterator>::__type _Integral; 00868 _M_insert_dispatch(__position, __first, __last, _Integral()); 00869 } 00870 #endif 00871 00872 void 00873 insert(iterator __position, size_type __n, const bool& __x) 00874 { _M_fill_insert(__position, __n, __x); } 00875 00876 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00877 void insert(iterator __p, initializer_list<bool> __l) 00878 { this->insert(__p, __l.begin(), __l.end()); } 00879 #endif 00880 00881 void 00882 pop_back() 00883 { --this->_M_impl._M_finish; } 00884 00885 iterator 00886 erase(iterator __position) 00887 { 00888 if (__position + 1 != end()) 00889 std::copy(__position + 1, end(), __position); 00890 --this->_M_impl._M_finish; 00891 return __position; 00892 } 00893 00894 iterator 00895 erase(iterator __first, iterator __last) 00896 { 00897 if (__first != __last) 00898 _M_erase_at_end(std::copy(__last, end(), __first)); 00899 return __first; 00900 } 00901 00902 void 00903 resize(size_type __new_size, bool __x = bool()) 00904 { 00905 if (__new_size < size()) 00906 _M_erase_at_end(begin() + difference_type(__new_size)); 00907 else 00908 insert(end(), __new_size - size(), __x); 00909 } 00910 00911 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00912 void 00913 shrink_to_fit() 00914 { _M_shrink_to_fit(); } 00915 #endif 00916 00917 void 00918 flip() _GLIBCXX_NOEXCEPT 00919 { 00920 for (_Bit_type * __p = this->_M_impl._M_start._M_p; 00921 __p != this->_M_impl._M_end_of_storage; ++__p) 00922 *__p = ~*__p; 00923 } 00924 00925 void 00926 clear() _GLIBCXX_NOEXCEPT 00927 { _M_erase_at_end(begin()); } 00928 00929 00930 protected: 00931 // Precondition: __first._M_offset == 0 && __result._M_offset == 0. 00932 iterator 00933 _M_copy_aligned(const_iterator __first, const_iterator __last, 00934 iterator __result) 00935 { 00936 _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p); 00937 return std::copy(const_iterator(__last._M_p, 0), __last, 00938 iterator(__q, 0)); 00939 } 00940 00941 void 00942 _M_initialize(size_type __n) 00943 { 00944 _Bit_type* __q = this->_M_allocate(__n); 00945 this->_M_impl._M_end_of_storage = __q + _S_nword(__n); 00946 this->_M_impl._M_start = iterator(__q, 0); 00947 this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); 00948 } 00949 00950 void 00951 _M_reallocate(size_type __n); 00952 00953 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00954 bool 00955 _M_shrink_to_fit(); 00956 #endif 00957 00958 // Check whether it's an integral type. If so, it's not an iterator. 00959 00960 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00961 // 438. Ambiguity in the "do the right thing" clause 00962 template<typename _Integer> 00963 void 00964 _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) 00965 { 00966 _M_initialize(static_cast<size_type>(__n)); 00967 std::fill(this->_M_impl._M_start._M_p, 00968 this->_M_impl._M_end_of_storage, __x ? ~0 : 0); 00969 } 00970 00971 template<typename _InputIterator> 00972 void 00973 _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, 00974 __false_type) 00975 { _M_initialize_range(__first, __last, 00976 std::__iterator_category(__first)); } 00977 00978 template<typename _InputIterator> 00979 void 00980 _M_initialize_range(_InputIterator __first, _InputIterator __last, 00981 std::input_iterator_tag) 00982 { 00983 for (; __first != __last; ++__first) 00984 push_back(*__first); 00985 } 00986 00987 template<typename _ForwardIterator> 00988 void 00989 _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, 00990 std::forward_iterator_tag) 00991 { 00992 const size_type __n = std::distance(__first, __last); 00993 _M_initialize(__n); 00994 std::copy(__first, __last, this->_M_impl._M_start); 00995 } 00996 00997 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00998 // 438. Ambiguity in the "do the right thing" clause 00999 template<typename _Integer> 01000 void 01001 _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) 01002 { _M_fill_assign(__n, __val); } 01003 01004 template<class _InputIterator> 01005 void 01006 _M_assign_dispatch(_InputIterator __first, _InputIterator __last, 01007 __false_type) 01008 { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } 01009 01010 void 01011 _M_fill_assign(size_t __n, bool __x) 01012 { 01013 if (__n > size()) 01014 { 01015 std::fill(this->_M_impl._M_start._M_p, 01016 this->_M_impl._M_end_of_storage, __x ? ~0 : 0); 01017 insert(end(), __n - size(), __x); 01018 } 01019 else 01020 { 01021 _M_erase_at_end(begin() + __n); 01022 std::fill(this->_M_impl._M_start._M_p, 01023 this->_M_impl._M_end_of_storage, __x ? ~0 : 0); 01024 } 01025 } 01026 01027 template<typename _InputIterator> 01028 void 01029 _M_assign_aux(_InputIterator __first, _InputIterator __last, 01030 std::input_iterator_tag) 01031 { 01032 iterator __cur = begin(); 01033 for (; __first != __last && __cur != end(); ++__cur, ++__first) 01034 *__cur = *__first; 01035 if (__first == __last) 01036 _M_erase_at_end(__cur); 01037 else 01038 insert(end(), __first, __last); 01039 } 01040 01041 template<typename _ForwardIterator> 01042 void 01043 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, 01044 std::forward_iterator_tag) 01045 { 01046 const size_type __len = std::distance(__first, __last); 01047 if (__len < size()) 01048 _M_erase_at_end(std::copy(__first, __last, begin())); 01049 else 01050 { 01051 _ForwardIterator __mid = __first; 01052 std::advance(__mid, size()); 01053 std::copy(__first, __mid, begin()); 01054 insert(end(), __mid, __last); 01055 } 01056 } 01057 01058 // Check whether it's an integral type. If so, it's not an iterator. 01059 01060 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01061 // 438. Ambiguity in the "do the right thing" clause 01062 template<typename _Integer> 01063 void 01064 _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, 01065 __true_type) 01066 { _M_fill_insert(__pos, __n, __x); } 01067 01068 template<typename _InputIterator> 01069 void 01070 _M_insert_dispatch(iterator __pos, 01071 _InputIterator __first, _InputIterator __last, 01072 __false_type) 01073 { _M_insert_range(__pos, __first, __last, 01074 std::__iterator_category(__first)); } 01075 01076 void 01077 _M_fill_insert(iterator __position, size_type __n, bool __x); 01078 01079 template<typename _InputIterator> 01080 void 01081 _M_insert_range(iterator __pos, _InputIterator __first, 01082 _InputIterator __last, std::input_iterator_tag) 01083 { 01084 for (; __first != __last; ++__first) 01085 { 01086 __pos = insert(__pos, *__first); 01087 ++__pos; 01088 } 01089 } 01090 01091 template<typename _ForwardIterator> 01092 void 01093 _M_insert_range(iterator __position, _ForwardIterator __first, 01094 _ForwardIterator __last, std::forward_iterator_tag); 01095 01096 void 01097 _M_insert_aux(iterator __position, bool __x); 01098 01099 size_type 01100 _M_check_len(size_type __n, const char* __s) const 01101 { 01102 if (max_size() - size() < __n) 01103 __throw_length_error(__N(__s)); 01104 01105 const size_type __len = size() + std::max(size(), __n); 01106 return (__len < size() || __len > max_size()) ? max_size() : __len; 01107 } 01108 01109 void 01110 _M_erase_at_end(iterator __pos) 01111 { this->_M_impl._M_finish = __pos; } 01112 }; 01113 01114 _GLIBCXX_END_NAMESPACE_CONTAINER 01115 } // namespace std 01116 01117 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 01118 01119 #include <bits/functional_hash.h> 01120 01121 namespace std _GLIBCXX_VISIBILITY(default) 01122 { 01123 _GLIBCXX_BEGIN_NAMESPACE_VERSION 01124 01125 // DR 1182. 01126 /// std::hash specialization for vector<bool>. 01127 template<typename _Alloc> 01128 struct hash<_GLIBCXX_STD_C::vector<bool, _Alloc>> 01129 : public __hash_base<size_t, _GLIBCXX_STD_C::vector<bool, _Alloc>> 01130 { 01131 size_t 01132 operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>&) const noexcept; 01133 }; 01134 01135 _GLIBCXX_END_NAMESPACE_VERSION 01136 }// namespace std 01137 01138 #endif // __GXX_EXPERIMENTAL_CXX0X__ 01139 01140 #endif