# 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