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