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