stl_bvector.h

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