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