1// vector<bool> specialization -*- C++ -*-
2
3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4// 2011 Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24// <http://www.gnu.org/licenses/>.
25
26/*
27 *
28 * Copyright (c) 1994
29 * Hewlett-Packard Company
30 *
31 * Permission to use, copy, modify, distribute and sell this software
32 * and its documentation for any purpose is hereby granted without fee,
33 * provided that the above copyright notice appear in all copies and
34 * that both that copyright notice and this permission notice appear
35 * in supporting documentation.  Hewlett-Packard Company makes no
36 * representations about the suitability of this software for any
37 * purpose.  It is provided "as is" without express or implied warranty.
38 *
39 *
40 * Copyright (c) 1996-1999
41 * Silicon Graphics Computer Systems, Inc.
42 *
43 * Permission to use, copy, modify, distribute and sell this software
44 * and its documentation for any purpose is hereby granted without fee,
45 * provided that the above copyright notice appear in all copies and
46 * that both that copyright notice and this permission notice appear
47 * in supporting documentation.  Silicon Graphics makes no
48 * representations about the suitability of this software for any
49 * purpose.  It is provided "as is" without express or implied warranty.
50 */
51
52/** @file bits/stl_bvector.h
53 *  This is an internal header file, included by other library headers.
54 *  Do not attempt to use it directly. @headername{vector}
55 */
56
57#ifndef _STL_BVECTOR_H
58#define _STL_BVECTOR_H 1
59
60#ifdef __GXX_EXPERIMENTAL_CXX0X__
61#include <initializer_list>
62#endif
63
64namespace std _GLIBCXX_VISIBILITY(default)
65{
66_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
67
68  typedef unsigned long _Bit_type;
69  enum { _S_word_bit = int(__CHAR_BIT__ * sizeof(_Bit_type)) };
70
71  struct _Bit_reference
72  {
73    _Bit_type * _M_p;
74    _Bit_type _M_mask;
75
76    _Bit_reference(_Bit_type * __x, _Bit_type __y)
77    : _M_p(__x), _M_mask(__y) { }
78
79    _Bit_reference() _GLIBCXX_NOEXCEPT : _M_p(0), _M_mask(0) { }
80
81    operator bool() const _GLIBCXX_NOEXCEPT
82    { return !!(*_M_p & _M_mask); }
83
84    _Bit_reference&
85    operator=(bool __x) _GLIBCXX_NOEXCEPT
86    {
87      if (__x)
88	*_M_p |= _M_mask;
89      else
90	*_M_p &= ~_M_mask;
91      return *this;
92    }
93
94    _Bit_reference&
95    operator=(const _Bit_reference& __x) _GLIBCXX_NOEXCEPT
96    { return *this = bool(__x); }
97
98    bool
99    operator==(const _Bit_reference& __x) const
100    { return bool(*this) == bool(__x); }
101
102    bool
103    operator<(const _Bit_reference& __x) const
104    { return !bool(*this) && bool(__x); }
105
106    void
107    flip() _GLIBCXX_NOEXCEPT
108    { *_M_p ^= _M_mask; }
109  };
110
111  struct _Bit_iterator_base
112  : public std::iterator<std::random_access_iterator_tag, bool>
113  {
114    _Bit_type * _M_p;
115    unsigned int _M_offset;
116
117    _Bit_iterator_base(_Bit_type * __x, unsigned int __y)
118    : _M_p(__x), _M_offset(__y) { }
119
120    void
121    _M_bump_up()
122    {
123      if (_M_offset++ == int(_S_word_bit) - 1)
124	{
125	  _M_offset = 0;
126	  ++_M_p;
127	}
128    }
129
130    void
131    _M_bump_down()
132    {
133      if (_M_offset-- == 0)
134	{
135	  _M_offset = int(_S_word_bit) - 1;
136	  --_M_p;
137	}
138    }
139
140    void
141    _M_incr(ptrdiff_t __i)
142    {
143      difference_type __n = __i + _M_offset;
144      _M_p += __n / int(_S_word_bit);
145      __n = __n % int(_S_word_bit);
146      if (__n < 0)
147	{
148	  __n += int(_S_word_bit);
149	  --_M_p;
150	}
151      _M_offset = static_cast<unsigned int>(__n);
152    }
153
154    bool
155    operator==(const _Bit_iterator_base& __i) const
156    { return _M_p == __i._M_p && _M_offset == __i._M_offset; }
157
158    bool
159    operator<(const _Bit_iterator_base& __i) const
160    {
161      return _M_p < __i._M_p
162	     || (_M_p == __i._M_p && _M_offset < __i._M_offset);
163    }
164
165    bool
166    operator!=(const _Bit_iterator_base& __i) const
167    { return !(*this == __i); }
168
169    bool
170    operator>(const _Bit_iterator_base& __i) const
171    { return __i < *this; }
172
173    bool
174    operator<=(const _Bit_iterator_base& __i) const
175    { return !(__i < *this); }
176
177    bool
178    operator>=(const _Bit_iterator_base& __i) const
179    { return !(*this < __i); }
180  };
181
182  inline ptrdiff_t
183  operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
184  {
185    return (int(_S_word_bit) * (__x._M_p - __y._M_p)
186	    + __x._M_offset - __y._M_offset);
187  }
188
189  struct _Bit_iterator : public _Bit_iterator_base
190  {
191    typedef _Bit_reference  reference;
192    typedef _Bit_reference* pointer;
193    typedef _Bit_iterator   iterator;
194
195    _Bit_iterator() : _Bit_iterator_base(0, 0) { }
196
197    _Bit_iterator(_Bit_type * __x, unsigned int __y)
198    : _Bit_iterator_base(__x, __y) { }
199
200    reference
201    operator*() const
202    { return reference(_M_p, 1UL << _M_offset); }
203
204    iterator&
205    operator++()
206    {
207      _M_bump_up();
208      return *this;
209    }
210
211    iterator
212    operator++(int)
213    {
214      iterator __tmp = *this;
215      _M_bump_up();
216      return __tmp;
217    }
218
219    iterator&
220    operator--()
221    {
222      _M_bump_down();
223      return *this;
224    }
225
226    iterator
227    operator--(int)
228    {
229      iterator __tmp = *this;
230      _M_bump_down();
231      return __tmp;
232    }
233
234    iterator&
235    operator+=(difference_type __i)
236    {
237      _M_incr(__i);
238      return *this;
239    }
240
241    iterator&
242    operator-=(difference_type __i)
243    {
244      *this += -__i;
245      return *this;
246    }
247
248    iterator
249    operator+(difference_type __i) const
250    {
251      iterator __tmp = *this;
252      return __tmp += __i;
253    }
254
255    iterator
256    operator-(difference_type __i) const
257    {
258      iterator __tmp = *this;
259      return __tmp -= __i;
260    }
261
262    reference
263    operator[](difference_type __i) const
264    { return *(*this + __i); }
265  };
266
267  inline _Bit_iterator
268  operator+(ptrdiff_t __n, const _Bit_iterator& __x)
269  { return __x + __n; }
270
271  struct _Bit_const_iterator : public _Bit_iterator_base
272  {
273    typedef bool                 reference;
274    typedef bool                 const_reference;
275    typedef const bool*          pointer;
276    typedef _Bit_const_iterator  const_iterator;
277
278    _Bit_const_iterator() : _Bit_iterator_base(0, 0) { }
279
280    _Bit_const_iterator(_Bit_type * __x, unsigned int __y)
281    : _Bit_iterator_base(__x, __y) { }
282
283    _Bit_const_iterator(const _Bit_iterator& __x)
284    : _Bit_iterator_base(__x._M_p, __x._M_offset) { }
285
286    const_reference
287    operator*() const
288    { return _Bit_reference(_M_p, 1UL << _M_offset); }
289
290    const_iterator&
291    operator++()
292    {
293      _M_bump_up();
294      return *this;
295    }
296
297    const_iterator
298    operator++(int)
299    {
300      const_iterator __tmp = *this;
301      _M_bump_up();
302      return __tmp;
303    }
304
305    const_iterator&
306    operator--()
307    {
308      _M_bump_down();
309      return *this;
310    }
311
312    const_iterator
313    operator--(int)
314    {
315      const_iterator __tmp = *this;
316      _M_bump_down();
317      return __tmp;
318    }
319
320    const_iterator&
321    operator+=(difference_type __i)
322    {
323      _M_incr(__i);
324      return *this;
325    }
326
327    const_iterator&
328    operator-=(difference_type __i)
329    {
330      *this += -__i;
331      return *this;
332    }
333
334    const_iterator
335    operator+(difference_type __i) const
336    {
337      const_iterator __tmp = *this;
338      return __tmp += __i;
339    }
340
341    const_iterator
342    operator-(difference_type __i) const
343    {
344      const_iterator __tmp = *this;
345      return __tmp -= __i;
346    }
347
348    const_reference
349    operator[](difference_type __i) const
350    { return *(*this + __i); }
351  };
352
353  inline _Bit_const_iterator
354  operator+(ptrdiff_t __n, const _Bit_const_iterator& __x)
355  { return __x + __n; }
356
357  inline void
358  __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x)
359  {
360    for (; __first != __last; ++__first)
361      *__first = __x;
362  }
363
364  inline void
365  fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x)
366  {
367    if (__first._M_p != __last._M_p)
368      {
369	std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0);
370	__fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x);
371	__fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x);
372      }
373    else
374      __fill_bvector(__first, __last, __x);
375  }
376
377  template<typename _Alloc>
378    struct _Bvector_base
379    {
380      typedef typename _Alloc::template rebind<_Bit_type>::other
381        _Bit_alloc_type;
382
383      struct _Bvector_impl
384      : public _Bit_alloc_type
385      {
386	_Bit_iterator 	_M_start;
387	_Bit_iterator 	_M_finish;
388	_Bit_type* 	_M_end_of_storage;
389
390	_Bvector_impl()
391	: _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage(0)
392	{ }
393
394	_Bvector_impl(const _Bit_alloc_type& __a)
395	: _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0)
396	{ }
397
398#ifdef __GXX_EXPERIMENTAL_CXX0X__
399	_Bvector_impl(_Bit_alloc_type&& __a)
400	: _Bit_alloc_type(std::move(__a)), _M_start(), _M_finish(),
401	  _M_end_of_storage(0)
402	{ }
403#endif
404      };
405
406    public:
407      typedef _Alloc allocator_type;
408
409      _Bit_alloc_type&
410      _M_get_Bit_allocator() _GLIBCXX_NOEXCEPT
411      { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); }
412
413      const _Bit_alloc_type&
414      _M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT
415      { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); }
416
417      allocator_type
418      get_allocator() const _GLIBCXX_NOEXCEPT
419      { return allocator_type(_M_get_Bit_allocator()); }
420
421      _Bvector_base()
422      : _M_impl() { }
423
424      _Bvector_base(const allocator_type& __a)
425      : _M_impl(__a) { }
426
427#ifdef __GXX_EXPERIMENTAL_CXX0X__
428      _Bvector_base(_Bvector_base&& __x) noexcept
429      : _M_impl(std::move(__x._M_get_Bit_allocator()))
430      {
431	this->_M_impl._M_start = __x._M_impl._M_start;
432	this->_M_impl._M_finish = __x._M_impl._M_finish;
433	this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage;
434	__x._M_impl._M_start = _Bit_iterator();
435	__x._M_impl._M_finish = _Bit_iterator();
436	__x._M_impl._M_end_of_storage = 0;
437      }
438#endif
439
440      ~_Bvector_base()
441      { this->_M_deallocate(); }
442
443    protected:
444      _Bvector_impl _M_impl;
445
446      _Bit_type*
447      _M_allocate(size_t __n)
448      { return _M_impl.allocate(_S_nword(__n)); }
449
450      void
451      _M_deallocate()
452      {
453	if (_M_impl._M_start._M_p)
454	  _M_impl.deallocate(_M_impl._M_start._M_p,
455			     _M_impl._M_end_of_storage - _M_impl._M_start._M_p);
456      }
457
458      static size_t
459      _S_nword(size_t __n)
460      { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); }
461    };
462
463_GLIBCXX_END_NAMESPACE_CONTAINER
464} // namespace std
465
466// Declare a partial specialization of vector<T, Alloc>.
467#include <bits/stl_vector.h>
468
469namespace std _GLIBCXX_VISIBILITY(default)
470{
471_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
472
473  /**
474   *  @brief  A specialization of vector for booleans which offers fixed time
475   *  access to individual elements in any order.
476   *
477   *  Note that vector<bool> does not actually meet the requirements for being
478   *  a container.  This is because the reference and pointer types are not
479   *  really references and pointers to bool.  See DR96 for details.  @see
480   *  vector for function documentation.
481   *
482   *  @ingroup sequences
483   *
484   *  In some terminology a %vector can be described as a dynamic
485   *  C-style array, it offers fast and efficient access to individual
486   *  elements in any order and saves the user from worrying about
487   *  memory and size allocation.  Subscripting ( @c [] ) access is
488   *  also provided as with C-style arrays.
489  */
490template<typename _Alloc>
491  class vector<bool, _Alloc> : protected _Bvector_base<_Alloc>
492  {
493    typedef _Bvector_base<_Alloc>			 _Base;
494
495#ifdef __GXX_EXPERIMENTAL_CXX0X__
496    template<typename> friend class hash;
497#endif
498
499  public:
500    typedef bool                                         value_type;
501    typedef size_t                                       size_type;
502    typedef ptrdiff_t                                    difference_type;
503    typedef _Bit_reference                               reference;
504    typedef bool                                         const_reference;
505    typedef _Bit_reference*                              pointer;
506    typedef const bool*                                  const_pointer;
507    typedef _Bit_iterator                                iterator;
508    typedef _Bit_const_iterator                          const_iterator;
509    typedef std::reverse_iterator<const_iterator>        const_reverse_iterator;
510    typedef std::reverse_iterator<iterator>              reverse_iterator;
511    typedef _Alloc                        		 allocator_type;
512
513    allocator_type get_allocator() const
514    { return _Base::get_allocator(); }
515
516  protected:
517    using _Base::_M_allocate;
518    using _Base::_M_deallocate;
519    using _Base::_S_nword;
520    using _Base::_M_get_Bit_allocator;
521
522  public:
523    vector()
524    : _Base() { }
525
526    explicit
527    vector(const allocator_type& __a)
528    : _Base(__a) { }
529
530    explicit
531    vector(size_type __n, const bool& __value = bool(),
532	   const allocator_type& __a = allocator_type())
533    : _Base(__a)
534    {
535      _M_initialize(__n);
536      std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage,
537		__value ? ~0 : 0);
538    }
539
540    vector(const vector& __x)
541    : _Base(__x._M_get_Bit_allocator())
542    {
543      _M_initialize(__x.size());
544      _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
545    }
546
547#ifdef __GXX_EXPERIMENTAL_CXX0X__
548    vector(vector&& __x) noexcept
549    : _Base(std::move(__x)) { }
550
551    vector(initializer_list<bool> __l,
552	   const allocator_type& __a = allocator_type())
553    : _Base(__a)
554    {
555      _M_initialize_range(__l.begin(), __l.end(),
556			  random_access_iterator_tag());
557    }
558#endif
559
560    template<typename _InputIterator>
561      vector(_InputIterator __first, _InputIterator __last,
562	     const allocator_type& __a = allocator_type())
563      : _Base(__a)
564      {
565	typedef typename std::__is_integer<_InputIterator>::__type _Integral;
566	_M_initialize_dispatch(__first, __last, _Integral());
567      }
568
569    ~vector() _GLIBCXX_NOEXCEPT { }
570
571    vector&
572    operator=(const vector& __x)
573    {
574      if (&__x == this)
575	return *this;
576      if (__x.size() > capacity())
577	{
578	  this->_M_deallocate();
579	  _M_initialize(__x.size());
580	}
581      this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
582						begin());
583      return *this;
584    }
585
586#ifdef __GXX_EXPERIMENTAL_CXX0X__
587    vector&
588    operator=(vector&& __x)
589    {
590      // NB: DR 1204.
591      // NB: DR 675.
592      this->clear();
593      this->swap(__x);
594      return *this;
595    }
596
597    vector&
598    operator=(initializer_list<bool> __l)
599    {
600      this->assign (__l.begin(), __l.end());
601      return *this;
602    }
603#endif
604
605    // assign(), a generalized assignment member function.  Two
606    // versions: one that takes a count, and one that takes a range.
607    // The range version is a member template, so we dispatch on whether
608    // or not the type is an integer.
609    void
610    assign(size_type __n, const bool& __x)
611    { _M_fill_assign(__n, __x); }
612
613    template<typename _InputIterator>
614      void
615      assign(_InputIterator __first, _InputIterator __last)
616      {
617	typedef typename std::__is_integer<_InputIterator>::__type _Integral;
618	_M_assign_dispatch(__first, __last, _Integral());
619      }
620
621#ifdef __GXX_EXPERIMENTAL_CXX0X__
622    void
623    assign(initializer_list<bool> __l)
624    { this->assign(__l.begin(), __l.end()); }
625#endif
626
627    iterator
628    begin() _GLIBCXX_NOEXCEPT
629    { return this->_M_impl._M_start; }
630
631    const_iterator
632    begin() const _GLIBCXX_NOEXCEPT
633    { return this->_M_impl._M_start; }
634
635    iterator
636    end() _GLIBCXX_NOEXCEPT
637    { return this->_M_impl._M_finish; }
638
639    const_iterator
640    end() const _GLIBCXX_NOEXCEPT
641    { return this->_M_impl._M_finish; }
642
643    reverse_iterator
644    rbegin() _GLIBCXX_NOEXCEPT
645    { return reverse_iterator(end()); }
646
647    const_reverse_iterator
648    rbegin() const _GLIBCXX_NOEXCEPT
649    { return const_reverse_iterator(end()); }
650
651    reverse_iterator
652    rend() _GLIBCXX_NOEXCEPT
653    { return reverse_iterator(begin()); }
654
655    const_reverse_iterator
656    rend() const _GLIBCXX_NOEXCEPT
657    { return const_reverse_iterator(begin()); }
658
659#ifdef __GXX_EXPERIMENTAL_CXX0X__
660    const_iterator
661    cbegin() const noexcept
662    { return this->_M_impl._M_start; }
663
664    const_iterator
665    cend() const noexcept
666    { return this->_M_impl._M_finish; }
667
668    const_reverse_iterator
669    crbegin() const noexcept
670    { return const_reverse_iterator(end()); }
671
672    const_reverse_iterator
673    crend() const noexcept
674    { return const_reverse_iterator(begin()); }
675#endif
676
677    size_type
678    size() const _GLIBCXX_NOEXCEPT
679    { return size_type(end() - begin()); }
680
681    size_type
682    max_size() const _GLIBCXX_NOEXCEPT
683    {
684      const size_type __isize =
685	__gnu_cxx::__numeric_traits<difference_type>::__max
686	- int(_S_word_bit) + 1;
687      const size_type __asize = _M_get_Bit_allocator().max_size();
688      return (__asize <= __isize / int(_S_word_bit)
689	      ? __asize * int(_S_word_bit) : __isize);
690    }
691
692    size_type
693    capacity() const _GLIBCXX_NOEXCEPT
694    { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0)
695		       - begin()); }
696
697    bool
698    empty() const _GLIBCXX_NOEXCEPT
699    { return begin() == end(); }
700
701    reference
702    operator[](size_type __n)
703    {
704      return *iterator(this->_M_impl._M_start._M_p
705		       + __n / int(_S_word_bit), __n % int(_S_word_bit));
706    }
707
708    const_reference
709    operator[](size_type __n) const
710    {
711      return *const_iterator(this->_M_impl._M_start._M_p
712			     + __n / int(_S_word_bit), __n % int(_S_word_bit));
713    }
714
715  protected:
716    void
717    _M_range_check(size_type __n) const
718    {
719      if (__n >= this->size())
720        __throw_out_of_range(__N("vector<bool>::_M_range_check"));
721    }
722
723  public:
724    reference
725    at(size_type __n)
726    { _M_range_check(__n); return (*this)[__n]; }
727
728    const_reference
729    at(size_type __n) const
730    { _M_range_check(__n); return (*this)[__n]; }
731
732    void
733    reserve(size_type __n)
734    {
735      if (__n > max_size())
736	__throw_length_error(__N("vector::reserve"));
737      if (capacity() < __n)
738	_M_reallocate(__n);
739    }
740
741    reference
742    front()
743    { return *begin(); }
744
745    const_reference
746    front() const
747    { return *begin(); }
748
749    reference
750    back()
751    { return *(end() - 1); }
752
753    const_reference
754    back() const
755    { return *(end() - 1); }
756
757    // _GLIBCXX_RESOLVE_LIB_DEFECTS
758    // DR 464. Suggestion for new member functions in standard containers.
759    // N.B. DR 464 says nothing about vector<bool> but we need something
760    // here due to the way we are implementing DR 464 in the debug-mode
761    // vector class.
762    void
763    data() _GLIBCXX_NOEXCEPT { }
764
765    void
766    push_back(bool __x)
767    {
768      if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
769        *this->_M_impl._M_finish++ = __x;
770      else
771        _M_insert_aux(end(), __x);
772    }
773
774    void
775    swap(vector& __x)
776    {
777      std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
778      std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
779      std::swap(this->_M_impl._M_end_of_storage,
780		__x._M_impl._M_end_of_storage);
781
782      // _GLIBCXX_RESOLVE_LIB_DEFECTS
783      // 431. Swapping containers with unequal allocators.
784      std::__alloc_swap<typename _Base::_Bit_alloc_type>::
785	_S_do_it(_M_get_Bit_allocator(), __x._M_get_Bit_allocator());
786    }
787
788    // [23.2.5]/1, third-to-last entry in synopsis listing
789    static void
790    swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT
791    {
792      bool __tmp = __x;
793      __x = __y;
794      __y = __tmp;
795    }
796
797    iterator
798    insert(iterator __position, const bool& __x = bool())
799    {
800      const difference_type __n = __position - begin();
801      if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage
802	  && __position == end())
803        *this->_M_impl._M_finish++ = __x;
804      else
805        _M_insert_aux(__position, __x);
806      return begin() + __n;
807    }
808
809    template<typename _InputIterator>
810      void
811      insert(iterator __position,
812	     _InputIterator __first, _InputIterator __last)
813      {
814	typedef typename std::__is_integer<_InputIterator>::__type _Integral;
815	_M_insert_dispatch(__position, __first, __last, _Integral());
816      }
817
818    void
819    insert(iterator __position, size_type __n, const bool& __x)
820    { _M_fill_insert(__position, __n, __x); }
821
822#ifdef __GXX_EXPERIMENTAL_CXX0X__
823    void insert(iterator __p, initializer_list<bool> __l)
824    { this->insert(__p, __l.begin(), __l.end()); }
825#endif
826
827    void
828    pop_back()
829    { --this->_M_impl._M_finish; }
830
831    iterator
832    erase(iterator __position)
833    {
834      if (__position + 1 != end())
835        std::copy(__position + 1, end(), __position);
836      --this->_M_impl._M_finish;
837      return __position;
838    }
839
840    iterator
841    erase(iterator __first, iterator __last)
842    {
843      if (__first != __last)
844	_M_erase_at_end(std::copy(__last, end(), __first));
845      return __first;
846    }
847
848    void
849    resize(size_type __new_size, bool __x = bool())
850    {
851      if (__new_size < size())
852        _M_erase_at_end(begin() + difference_type(__new_size));
853      else
854        insert(end(), __new_size - size(), __x);
855    }
856
857#ifdef __GXX_EXPERIMENTAL_CXX0X__
858    void
859    shrink_to_fit()
860    { _M_shrink_to_fit(); }
861#endif
862
863    void
864    flip() _GLIBCXX_NOEXCEPT
865    {
866      for (_Bit_type * __p = this->_M_impl._M_start._M_p;
867	   __p != this->_M_impl._M_end_of_storage; ++__p)
868        *__p = ~*__p;
869    }
870
871    void
872    clear() _GLIBCXX_NOEXCEPT
873    { _M_erase_at_end(begin()); }
874
875
876  protected:
877    // Precondition: __first._M_offset == 0 && __result._M_offset == 0.
878    iterator
879    _M_copy_aligned(const_iterator __first, const_iterator __last,
880		    iterator __result)
881    {
882      _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p);
883      return std::copy(const_iterator(__last._M_p, 0), __last,
884		       iterator(__q, 0));
885    }
886
887    void
888    _M_initialize(size_type __n)
889    {
890      _Bit_type* __q = this->_M_allocate(__n);
891      this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
892      this->_M_impl._M_start = iterator(__q, 0);
893      this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
894    }
895
896    void
897    _M_reallocate(size_type __n);
898
899#ifdef __GXX_EXPERIMENTAL_CXX0X__
900    bool
901    _M_shrink_to_fit();
902#endif
903
904    // Check whether it's an integral type.  If so, it's not an iterator.
905
906    // _GLIBCXX_RESOLVE_LIB_DEFECTS
907    // 438. Ambiguity in the "do the right thing" clause
908    template<typename _Integer>
909      void
910      _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
911      {
912	_M_initialize(static_cast<size_type>(__n));
913	std::fill(this->_M_impl._M_start._M_p,
914		  this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
915      }
916
917    template<typename _InputIterator>
918      void
919      _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
920			     __false_type)
921      { _M_initialize_range(__first, __last,
922			    std::__iterator_category(__first)); }
923
924    template<typename _InputIterator>
925      void
926      _M_initialize_range(_InputIterator __first, _InputIterator __last,
927			  std::input_iterator_tag)
928      {
929	for (; __first != __last; ++__first)
930	  push_back(*__first);
931      }
932
933    template<typename _ForwardIterator>
934      void
935      _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last,
936			  std::forward_iterator_tag)
937      {
938	const size_type __n = std::distance(__first, __last);
939	_M_initialize(__n);
940	std::copy(__first, __last, this->_M_impl._M_start);
941      }
942
943    // _GLIBCXX_RESOLVE_LIB_DEFECTS
944    // 438. Ambiguity in the "do the right thing" clause
945    template<typename _Integer>
946      void
947      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
948      { _M_fill_assign(__n, __val); }
949
950    template<class _InputIterator>
951      void
952      _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
953			 __false_type)
954      { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
955
956    void
957    _M_fill_assign(size_t __n, bool __x)
958    {
959      if (__n > size())
960	{
961	  std::fill(this->_M_impl._M_start._M_p,
962		    this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
963	  insert(end(), __n - size(), __x);
964	}
965      else
966	{
967	  _M_erase_at_end(begin() + __n);
968	  std::fill(this->_M_impl._M_start._M_p,
969		    this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
970	}
971    }
972
973    template<typename _InputIterator>
974      void
975      _M_assign_aux(_InputIterator __first, _InputIterator __last,
976		    std::input_iterator_tag)
977      {
978	iterator __cur = begin();
979	for (; __first != __last && __cur != end(); ++__cur, ++__first)
980	  *__cur = *__first;
981	if (__first == __last)
982	  _M_erase_at_end(__cur);
983	else
984	  insert(end(), __first, __last);
985      }
986
987    template<typename _ForwardIterator>
988      void
989      _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
990		    std::forward_iterator_tag)
991      {
992	const size_type __len = std::distance(__first, __last);
993	if (__len < size())
994	  _M_erase_at_end(std::copy(__first, __last, begin()));
995	else
996	  {
997	    _ForwardIterator __mid = __first;
998	    std::advance(__mid, size());
999	    std::copy(__first, __mid, begin());
1000	    insert(end(), __mid, __last);
1001	  }
1002      }
1003
1004    // Check whether it's an integral type.  If so, it's not an iterator.
1005
1006    // _GLIBCXX_RESOLVE_LIB_DEFECTS
1007    // 438. Ambiguity in the "do the right thing" clause
1008    template<typename _Integer>
1009      void
1010      _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
1011			 __true_type)
1012      { _M_fill_insert(__pos, __n, __x); }
1013
1014    template<typename _InputIterator>
1015      void
1016      _M_insert_dispatch(iterator __pos,
1017			 _InputIterator __first, _InputIterator __last,
1018			 __false_type)
1019      { _M_insert_range(__pos, __first, __last,
1020			std::__iterator_category(__first)); }
1021
1022    void
1023    _M_fill_insert(iterator __position, size_type __n, bool __x);
1024
1025    template<typename _InputIterator>
1026      void
1027      _M_insert_range(iterator __pos, _InputIterator __first,
1028		      _InputIterator __last, std::input_iterator_tag)
1029      {
1030	for (; __first != __last; ++__first)
1031	  {
1032	    __pos = insert(__pos, *__first);
1033	    ++__pos;
1034	  }
1035      }
1036
1037    template<typename _ForwardIterator>
1038      void
1039      _M_insert_range(iterator __position, _ForwardIterator __first,
1040		      _ForwardIterator __last, std::forward_iterator_tag);
1041
1042    void
1043    _M_insert_aux(iterator __position, bool __x);
1044
1045    size_type
1046    _M_check_len(size_type __n, const char* __s) const
1047    {
1048      if (max_size() - size() < __n)
1049	__throw_length_error(__N(__s));
1050
1051      const size_type __len = size() + std::max(size(), __n);
1052      return (__len < size() || __len > max_size()) ? max_size() : __len;
1053    }
1054
1055    void
1056    _M_erase_at_end(iterator __pos)
1057    { this->_M_impl._M_finish = __pos; }
1058  };
1059
1060_GLIBCXX_END_NAMESPACE_CONTAINER
1061} // namespace std
1062
1063#ifdef __GXX_EXPERIMENTAL_CXX0X__
1064
1065#include <bits/functional_hash.h>
1066
1067namespace std _GLIBCXX_VISIBILITY(default)
1068{
1069_GLIBCXX_BEGIN_NAMESPACE_VERSION
1070
1071  // DR 1182.
1072  /// std::hash specialization for vector<bool>.
1073  template<typename _Alloc>
1074    struct hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>
1075    : public __hash_base<size_t, _GLIBCXX_STD_C::vector<bool, _Alloc>>
1076    {
1077      size_t
1078      operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>&) const noexcept;
1079    };
1080
1081_GLIBCXX_END_NAMESPACE_VERSION
1082}// namespace std
1083
1084#endif // __GXX_EXPERIMENTAL_CXX0X__
1085
1086#endif
1087