libstdc++
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 // 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