1132720Skan// vector<bool> specialization -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
4169691Skan// Free Software Foundation, Inc.
597403Sobrien//
697403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
797403Sobrien// software; you can redistribute it and/or modify it under the
897403Sobrien// terms of the GNU General Public License as published by the
997403Sobrien// Free Software Foundation; either version 2, or (at your option)
1097403Sobrien// any later version.
1197403Sobrien
1297403Sobrien// This library is distributed in the hope that it will be useful,
1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1597403Sobrien// GNU General Public License for more details.
1697403Sobrien
1797403Sobrien// You should have received a copy of the GNU General Public License along
1897403Sobrien// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2097403Sobrien// USA.
2197403Sobrien
2297403Sobrien// As a special exception, you may use this file as part of a free software
2397403Sobrien// library without restriction.  Specifically, if other files instantiate
2497403Sobrien// templates or use macros or inline functions from this file, or you compile
2597403Sobrien// this file and link it with other files to produce an executable, this
2697403Sobrien// file does not by itself cause the resulting executable to be covered by
2797403Sobrien// the GNU General Public License.  This exception does not however
2897403Sobrien// invalidate any other reasons why the executable file might be covered by
2997403Sobrien// the GNU General Public License.
3097403Sobrien
3197403Sobrien/*
3297403Sobrien *
3397403Sobrien * Copyright (c) 1994
3497403Sobrien * Hewlett-Packard Company
3597403Sobrien *
3697403Sobrien * Permission to use, copy, modify, distribute and sell this software
3797403Sobrien * and its documentation for any purpose is hereby granted without fee,
3897403Sobrien * provided that the above copyright notice appear in all copies and
3997403Sobrien * that both that copyright notice and this permission notice appear
4097403Sobrien * in supporting documentation.  Hewlett-Packard Company makes no
4197403Sobrien * representations about the suitability of this software for any
4297403Sobrien * purpose.  It is provided "as is" without express or implied warranty.
4397403Sobrien *
4497403Sobrien *
4597403Sobrien * Copyright (c) 1996-1999
4697403Sobrien * Silicon Graphics Computer Systems, Inc.
4797403Sobrien *
4897403Sobrien * Permission to use, copy, modify, distribute and sell this software
4997403Sobrien * and its documentation for any purpose is hereby granted without fee,
5097403Sobrien * provided that the above copyright notice appear in all copies and
5197403Sobrien * that both that copyright notice and this permission notice appear
5297403Sobrien * in supporting documentation.  Silicon Graphics makes no
5397403Sobrien * representations about the suitability of this software for any
5497403Sobrien * purpose.  It is provided "as is" without express or implied warranty.
5597403Sobrien */
5697403Sobrien
5797403Sobrien/** @file stl_bvector.h
5897403Sobrien *  This is an internal header file, included by other library headers.
5997403Sobrien *  You should not attempt to use it directly.
6097403Sobrien */
6197403Sobrien
62132720Skan#ifndef _BVECTOR_H
63132720Skan#define _BVECTOR_H 1
6497403Sobrien
65169691Skan_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
66169691Skan
6797403Sobrien  typedef unsigned long _Bit_type;
68132720Skan  enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) };
6997403Sobrien
70132720Skan  struct _Bit_reference
71132720Skan  {
72132720Skan    _Bit_type * _M_p;
73132720Skan    _Bit_type _M_mask;
7497403Sobrien
75132720Skan    _Bit_reference(_Bit_type * __x, _Bit_type __y)
76132720Skan    : _M_p(__x), _M_mask(__y) { }
7797403Sobrien
78132720Skan    _Bit_reference() : _M_p(0), _M_mask(0) { }
79132720Skan
80169691Skan    operator bool() const
81169691Skan    { return !!(*_M_p & _M_mask); }
82132720Skan
83132720Skan    _Bit_reference&
84132720Skan    operator=(bool __x)
85132720Skan    {
86132720Skan      if (__x)
87132720Skan	*_M_p |= _M_mask;
88132720Skan      else
89132720Skan	*_M_p &= ~_M_mask;
90132720Skan      return *this;
91132720Skan    }
92132720Skan
93132720Skan    _Bit_reference&
94132720Skan    operator=(const _Bit_reference& __x)
9597403Sobrien    { return *this = bool(__x); }
96132720Skan
97132720Skan    bool
98132720Skan    operator==(const _Bit_reference& __x) const
9997403Sobrien    { return bool(*this) == bool(__x); }
100132720Skan
101132720Skan    bool
102132720Skan    operator<(const _Bit_reference& __x) const
10397403Sobrien    { return !bool(*this) && bool(__x); }
10497403Sobrien
105132720Skan    void
106169691Skan    flip()
107169691Skan    { *_M_p ^= _M_mask; }
108132720Skan  };
10997403Sobrien
110169691Skan  struct _Bit_iterator_base
111169691Skan  : public std::iterator<std::random_access_iterator_tag, bool>
112132720Skan  {
113132720Skan    _Bit_type * _M_p;
114132720Skan    unsigned int _M_offset;
11597403Sobrien
116132720Skan    _Bit_iterator_base(_Bit_type * __x, unsigned int __y)
117132720Skan    : _M_p(__x), _M_offset(__y) { }
118132720Skan
119132720Skan    void
120132720Skan    _M_bump_up()
121132720Skan    {
122169691Skan      if (_M_offset++ == int(_S_word_bit) - 1)
123132720Skan	{
124132720Skan	  _M_offset = 0;
125132720Skan	  ++_M_p;
126132720Skan	}
12797403Sobrien    }
128132720Skan
129132720Skan    void
130132720Skan    _M_bump_down()
131132720Skan    {
132132720Skan      if (_M_offset-- == 0)
133132720Skan	{
134169691Skan	  _M_offset = int(_S_word_bit) - 1;
135132720Skan	  --_M_p;
136132720Skan	}
13797403Sobrien    }
13897403Sobrien
139132720Skan    void
140132720Skan    _M_incr(ptrdiff_t __i)
141132720Skan    {
142132720Skan      difference_type __n = __i + _M_offset;
143169691Skan      _M_p += __n / int(_S_word_bit);
144169691Skan      __n = __n % int(_S_word_bit);
145132720Skan      if (__n < 0)
146132720Skan	{
147169691Skan	  __n += int(_S_word_bit);
148132720Skan	  --_M_p;
149132720Skan	}
150169691Skan      _M_offset = static_cast<unsigned int>(__n);
151132720Skan    }
15297403Sobrien
153132720Skan    bool
154132720Skan    operator==(const _Bit_iterator_base& __i) const
155132720Skan    { return _M_p == __i._M_p && _M_offset == __i._M_offset; }
15697403Sobrien
157132720Skan    bool
158132720Skan    operator<(const _Bit_iterator_base& __i) const
159132720Skan    {
160132720Skan      return _M_p < __i._M_p
161132720Skan	     || (_M_p == __i._M_p && _M_offset < __i._M_offset);
162132720Skan    }
16397403Sobrien
164132720Skan    bool
165132720Skan    operator!=(const _Bit_iterator_base& __i) const
166132720Skan    { return !(*this == __i); }
16797403Sobrien
168132720Skan    bool
169132720Skan    operator>(const _Bit_iterator_base& __i) const
170132720Skan    { return __i < *this; }
17197403Sobrien
172132720Skan    bool
173132720Skan    operator<=(const _Bit_iterator_base& __i) const
174132720Skan    { return !(__i < *this); }
17597403Sobrien
176132720Skan    bool
177132720Skan    operator>=(const _Bit_iterator_base& __i) const
178132720Skan    { return !(*this < __i); }
179132720Skan  };
180132720Skan
181132720Skan  inline ptrdiff_t
182132720Skan  operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
183132720Skan  {
184169691Skan    return (int(_S_word_bit) * (__x._M_p - __y._M_p)
185169691Skan	    + __x._M_offset - __y._M_offset);
18697403Sobrien  }
18797403Sobrien
188132720Skan  struct _Bit_iterator : public _Bit_iterator_base
189132720Skan  {
190132720Skan    typedef _Bit_reference  reference;
191132720Skan    typedef _Bit_reference* pointer;
192132720Skan    typedef _Bit_iterator   iterator;
19397403Sobrien
194132720Skan    _Bit_iterator() : _Bit_iterator_base(0, 0) { }
195169691Skan
196132720Skan    _Bit_iterator(_Bit_type * __x, unsigned int __y)
197132720Skan    : _Bit_iterator_base(__x, __y) { }
19897403Sobrien
199132720Skan    reference
200169691Skan    operator*() const
201169691Skan    { return reference(_M_p, 1UL << _M_offset); }
20297403Sobrien
203132720Skan    iterator&
204132720Skan    operator++()
205132720Skan    {
206132720Skan      _M_bump_up();
207132720Skan      return *this;
208132720Skan    }
20997403Sobrien
210132720Skan    iterator
211132720Skan    operator++(int)
212132720Skan    {
213132720Skan      iterator __tmp = *this;
214132720Skan      _M_bump_up();
215132720Skan      return __tmp;
216132720Skan    }
21797403Sobrien
218132720Skan    iterator&
219132720Skan    operator--()
220132720Skan    {
221132720Skan      _M_bump_down();
222132720Skan      return *this;
223132720Skan    }
22497403Sobrien
225132720Skan    iterator
226132720Skan    operator--(int)
227132720Skan    {
228132720Skan      iterator __tmp = *this;
229132720Skan      _M_bump_down();
230132720Skan      return __tmp;
231132720Skan    }
23297403Sobrien
233132720Skan    iterator&
234132720Skan    operator+=(difference_type __i)
235132720Skan    {
236132720Skan      _M_incr(__i);
237132720Skan      return *this;
238132720Skan    }
23997403Sobrien
240132720Skan    iterator&
241132720Skan    operator-=(difference_type __i)
242132720Skan    {
243132720Skan      *this += -__i;
244132720Skan      return *this;
245132720Skan    }
24697403Sobrien
247132720Skan    iterator
248132720Skan    operator+(difference_type __i) const
249132720Skan    {
250132720Skan      iterator __tmp = *this;
251132720Skan      return __tmp += __i;
252132720Skan    }
25397403Sobrien
254132720Skan    iterator
255132720Skan    operator-(difference_type __i) const
256132720Skan    {
257132720Skan      iterator __tmp = *this;
258132720Skan      return __tmp -= __i;
259132720Skan    }
26097403Sobrien
261132720Skan    reference
262169691Skan    operator[](difference_type __i) const
263132720Skan    { return *(*this + __i); }
264132720Skan  };
26597403Sobrien
266132720Skan  inline _Bit_iterator
267169691Skan  operator+(ptrdiff_t __n, const _Bit_iterator& __x)
268169691Skan  { return __x + __n; }
26997403Sobrien
270132720Skan  struct _Bit_const_iterator : public _Bit_iterator_base
271132720Skan  {
272132720Skan    typedef bool                 reference;
273132720Skan    typedef bool                 const_reference;
274132720Skan    typedef const bool*          pointer;
275132720Skan    typedef _Bit_const_iterator  const_iterator;
27697403Sobrien
277132720Skan    _Bit_const_iterator() : _Bit_iterator_base(0, 0) { }
278169691Skan
279132720Skan    _Bit_const_iterator(_Bit_type * __x, unsigned int __y)
280132720Skan    : _Bit_iterator_base(__x, __y) { }
281169691Skan
282132720Skan    _Bit_const_iterator(const _Bit_iterator& __x)
283132720Skan    : _Bit_iterator_base(__x._M_p, __x._M_offset) { }
28497403Sobrien
285132720Skan    const_reference
286132720Skan    operator*() const
287132720Skan    { return _Bit_reference(_M_p, 1UL << _M_offset); }
28897403Sobrien
289132720Skan    const_iterator&
290132720Skan    operator++()
291132720Skan    {
292132720Skan      _M_bump_up();
293132720Skan      return *this;
294132720Skan    }
29597403Sobrien
296132720Skan    const_iterator
297132720Skan    operator++(int)
298132720Skan    {
299132720Skan      const_iterator __tmp = *this;
300132720Skan      _M_bump_up();
301132720Skan      return __tmp;
302132720Skan    }
30397403Sobrien
304132720Skan    const_iterator&
305132720Skan    operator--()
306132720Skan    {
307132720Skan      _M_bump_down();
308132720Skan      return *this;
309132720Skan    }
310132720Skan
311132720Skan    const_iterator
312132720Skan    operator--(int)
313132720Skan    {
314132720Skan      const_iterator __tmp = *this;
315132720Skan      _M_bump_down();
316132720Skan      return __tmp;
317132720Skan    }
318132720Skan
319132720Skan    const_iterator&
320132720Skan    operator+=(difference_type __i)
321132720Skan    {
322132720Skan      _M_incr(__i);
323132720Skan      return *this;
324132720Skan    }
325132720Skan
326132720Skan    const_iterator&
327132720Skan    operator-=(difference_type __i)
328132720Skan    {
329132720Skan      *this += -__i;
330132720Skan      return *this;
331132720Skan    }
332132720Skan
333132720Skan    const_iterator
334169691Skan    operator+(difference_type __i) const
335169691Skan    {
336132720Skan      const_iterator __tmp = *this;
337132720Skan      return __tmp += __i;
338132720Skan    }
339132720Skan
340132720Skan    const_iterator
341132720Skan    operator-(difference_type __i) const
342132720Skan    {
343132720Skan      const_iterator __tmp = *this;
344132720Skan      return __tmp -= __i;
345132720Skan    }
346132720Skan
347132720Skan    const_reference
348169691Skan    operator[](difference_type __i) const
349132720Skan    { return *(*this + __i); }
350132720Skan  };
351132720Skan
352132720Skan  inline _Bit_const_iterator
353132720Skan  operator+(ptrdiff_t __n, const _Bit_const_iterator& __x)
354132720Skan  { return __x + __n; }
355132720Skan
356169691Skan  inline void
357169691Skan  __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x)
358169691Skan  {
359169691Skan    for (; __first != __last; ++__first)
360169691Skan      *__first = __x;
361169691Skan  }
362169691Skan
363169691Skan  inline void
364169691Skan  fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x)
365169691Skan  {
366169691Skan    if (__first._M_p != __last._M_p)
367169691Skan      {
368169691Skan	std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0);
369169691Skan	__fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x);
370169691Skan	__fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x);
371169691Skan      }
372169691Skan    else
373169691Skan      __fill_bvector(__first, __last, __x);
374169691Skan  }
375169691Skan
376132720Skan  template<class _Alloc>
377169691Skan    struct _Bvector_base
378132720Skan    {
379132720Skan      typedef typename _Alloc::template rebind<_Bit_type>::other
380132720Skan        _Bit_alloc_type;
381132720Skan
382169691Skan      struct _Bvector_impl
383169691Skan      : public _Bit_alloc_type
384132720Skan      {
385132720Skan	_Bit_iterator 	_M_start;
386132720Skan	_Bit_iterator 	_M_finish;
387132720Skan	_Bit_type* 	_M_end_of_storage;
388236829Spfg
389236829Spfg	_Bvector_impl()
390236829Spfg	: _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage(0)
391236829Spfg	{ }
392236829Spfg
393132720Skan	_Bvector_impl(const _Bit_alloc_type& __a)
394132720Skan	: _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0)
395132720Skan	{ }
396132720Skan      };
397132720Skan
398132720Skan    public:
399132720Skan      typedef _Alloc allocator_type;
400132720Skan
401169691Skan      _Bit_alloc_type&
402169691Skan      _M_get_Bit_allocator()
403169691Skan      { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); }
404169691Skan
405169691Skan      const _Bit_alloc_type&
406169691Skan      _M_get_Bit_allocator() const
407169691Skan      { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); }
408169691Skan
409132720Skan      allocator_type
410132720Skan      get_allocator() const
411169691Skan      { return allocator_type(_M_get_Bit_allocator()); }
412132720Skan
413236829Spfg      _Bvector_base()
414236829Spfg      : _M_impl() { }
415132720Skan
416236829Spfg      _Bvector_base(const allocator_type& __a)
417236829Spfg      : _M_impl(__a) { }
418236829Spfg
419169691Skan      ~_Bvector_base()
420169691Skan      { this->_M_deallocate(); }
421132720Skan
422132720Skan    protected:
423132720Skan      _Bvector_impl _M_impl;
424132720Skan
425132720Skan      _Bit_type*
426132720Skan      _M_allocate(size_t __n)
427169691Skan      { return _M_impl.allocate((__n + int(_S_word_bit) - 1)
428169691Skan				/ int(_S_word_bit)); }
429132720Skan
430132720Skan      void
431132720Skan      _M_deallocate()
432132720Skan      {
433132720Skan	if (_M_impl._M_start._M_p)
434132720Skan	  _M_impl.deallocate(_M_impl._M_start._M_p,
435169691Skan			     _M_impl._M_end_of_storage - _M_impl._M_start._M_p);
436132720Skan      }
437132720Skan    };
43897403Sobrien
439169691Skan_GLIBCXX_END_NESTED_NAMESPACE
440169691Skan
44197403Sobrien// Declare a partial specialization of vector<T, Alloc>.
44297403Sobrien#include <bits/stl_vector.h>
443132720Skan
444169691Skan_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
445169691Skan
446132720Skan  /**
447132720Skan   *  @brief  A specialization of vector for booleans which offers fixed time
448132720Skan   *  access to individual elements in any order.
449132720Skan   *
450132720Skan   *  Note that vector<bool> does not actually meet the requirements for being
451132720Skan   *  a container.  This is because the reference and pointer types are not
452132720Skan   *  really references and pointers to bool.  See DR96 for details.  @see
453132720Skan   *  vector for function documentation.
454132720Skan   *
455132720Skan   *  @ingroup Containers
456132720Skan   *  @ingroup Sequences
457132720Skan   *
458132720Skan   *  In some terminology a %vector can be described as a dynamic
459132720Skan   *  C-style array, it offers fast and efficient access to individual
460132720Skan   *  elements in any order and saves the user from worrying about
461132720Skan   *  memory and size allocation.  Subscripting ( @c [] ) access is
462132720Skan   *  also provided as with C-style arrays.
463132720Skan  */
464132720Skantemplate<typename _Alloc>
465169691Skan  class vector<bool, _Alloc> : protected _Bvector_base<_Alloc>
46697403Sobrien  {
467169691Skan    typedef _Bvector_base<_Alloc>			 _Base;
468169691Skan
46997403Sobrien  public:
470169691Skan    typedef bool                                         value_type;
471169691Skan    typedef size_t                                       size_type;
472169691Skan    typedef ptrdiff_t                                    difference_type;
473169691Skan    typedef _Bit_reference                               reference;
474169691Skan    typedef bool                                         const_reference;
475169691Skan    typedef _Bit_reference*                              pointer;
476169691Skan    typedef const bool*                                  const_pointer;
477169691Skan    typedef _Bit_iterator                                iterator;
478169691Skan    typedef _Bit_const_iterator                          const_iterator;
479169691Skan    typedef std::reverse_iterator<const_iterator>        const_reverse_iterator;
480169691Skan    typedef std::reverse_iterator<iterator>              reverse_iterator;
481169691Skan    typedef _Alloc                        		 allocator_type;
482132720Skan
483132720Skan    allocator_type get_allocator() const
484169691Skan    { return _Base::get_allocator(); }
485132720Skan
48697403Sobrien  protected:
487169691Skan    using _Base::_M_allocate;
488169691Skan    using _Base::_M_deallocate;
489169691Skan    using _Base::_M_get_Bit_allocator;
490132720Skan
491169691Skan  public:
492236829Spfg    vector()
493236829Spfg    : _Base() { }
494236829Spfg
495169691Skan    explicit
496236829Spfg    vector(const allocator_type& __a)
497169691Skan    : _Base(__a) { }
498169691Skan
499169691Skan    explicit
500169691Skan    vector(size_type __n, const bool& __value = bool(),
501169691Skan	   const allocator_type& __a = allocator_type())
502169691Skan    : _Base(__a)
503132720Skan    {
504169691Skan      _M_initialize(__n);
505169691Skan      std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage,
506169691Skan		__value ? ~0 : 0);
50797403Sobrien    }
508132720Skan
509169691Skan    vector(const vector& __x)
510169691Skan    : _Base(__x._M_get_Bit_allocator())
511132720Skan    {
512169691Skan      _M_initialize(__x.size());
513169691Skan      _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
51497403Sobrien    }
515132720Skan
516132720Skan    template<class _InputIterator>
517169691Skan      vector(_InputIterator __first, _InputIterator __last,
518169691Skan	     const allocator_type& __a = allocator_type())
519169691Skan      : _Base(__a)
520169691Skan      {
521169691Skan	typedef typename std::__is_integer<_InputIterator>::__type _Integral;
522169691Skan	_M_initialize_dispatch(__first, __last, _Integral());
523169691Skan      }
524132720Skan
525169691Skan    ~vector() { }
526132720Skan
527169691Skan    vector&
528169691Skan    operator=(const vector& __x)
529132720Skan    {
530169691Skan      if (&__x == this)
531169691Skan	return *this;
532169691Skan      if (__x.size() > capacity())
533132720Skan	{
534169691Skan	  this->_M_deallocate();
535169691Skan	  _M_initialize(__x.size());
536132720Skan	}
537169691Skan      this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
538169691Skan						begin());
539169691Skan      return *this;
54097403Sobrien    }
541132720Skan
542169691Skan    // assign(), a generalized assignment member function.  Two
543169691Skan    // versions: one that takes a count, and one that takes a range.
544169691Skan    // The range version is a member template, so we dispatch on whether
545169691Skan    // or not the type is an integer.
546169691Skan    void
547169691Skan    assign(size_type __n, const bool& __x)
548169691Skan    { _M_fill_assign(__n, __x); }
549132720Skan
550169691Skan    template<class _InputIterator>
551169691Skan      void
552169691Skan      assign(_InputIterator __first, _InputIterator __last)
553169691Skan      {
554169691Skan	typedef typename std::__is_integer<_InputIterator>::__type _Integral;
555169691Skan	_M_assign_dispatch(__first, __last, _Integral());
556169691Skan      }
557169691Skan
558169691Skan    iterator
559169691Skan    begin()
560132720Skan    { return this->_M_impl._M_start; }
561132720Skan
562169691Skan    const_iterator
563169691Skan    begin() const
564132720Skan    { return this->_M_impl._M_start; }
565132720Skan
566169691Skan    iterator
567169691Skan    end()
568132720Skan    { return this->_M_impl._M_finish; }
569132720Skan
570169691Skan    const_iterator
571169691Skan    end() const
572132720Skan    { return this->_M_impl._M_finish; }
573132720Skan
574169691Skan    reverse_iterator
575169691Skan    rbegin()
576132720Skan    { return reverse_iterator(end()); }
577132720Skan
578169691Skan    const_reverse_iterator
579169691Skan    rbegin() const
580132720Skan    { return const_reverse_iterator(end()); }
581132720Skan
582169691Skan    reverse_iterator
583169691Skan    rend()
584132720Skan    { return reverse_iterator(begin()); }
585132720Skan
586169691Skan    const_reverse_iterator
587169691Skan    rend() const
588132720Skan    { return const_reverse_iterator(begin()); }
589132720Skan
590169691Skan    size_type
591169691Skan    size() const
592132720Skan    { return size_type(end() - begin()); }
593132720Skan
594169691Skan    size_type
595169691Skan    max_size() const
596169691Skan    {
597169691Skan      const size_type __asize = _M_get_Bit_allocator().max_size();
598169691Skan      return (__asize <= size_type(-1) / int(_S_word_bit) ?
599169691Skan	      __asize * int(_S_word_bit) : size_type(-1));
600169691Skan    }
601132720Skan
602169691Skan    size_type
603169691Skan    capacity() const
604132720Skan    { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0)
605132720Skan		       - begin()); }
606169691Skan
607169691Skan    bool
608169691Skan    empty() const
609132720Skan    { return begin() == end(); }
610132720Skan
611169691Skan    reference
612169691Skan    operator[](size_type __n)
613169691Skan    {
614169691Skan      return *iterator(this->_M_impl._M_start._M_p
615169691Skan		       + __n / int(_S_word_bit), __n % int(_S_word_bit));
616169691Skan    }
617132720Skan
618169691Skan    const_reference
619169691Skan    operator[](size_type __n) const
620169691Skan    {
621169691Skan      return *const_iterator(this->_M_impl._M_start._M_p
622169691Skan			     + __n / int(_S_word_bit), __n % int(_S_word_bit));
623169691Skan    }
624132720Skan
625169691Skan  protected:
626169691Skan    void
627169691Skan    _M_range_check(size_type __n) const
628132720Skan    {
62997403Sobrien      if (__n >= this->size())
630132720Skan        __throw_out_of_range(__N("vector<bool>::_M_range_check"));
63197403Sobrien    }
632132720Skan
633169691Skan  public:
634169691Skan    reference
635169691Skan    at(size_type __n)
636132720Skan    { _M_range_check(__n); return (*this)[__n]; }
637132720Skan
638169691Skan    const_reference
639169691Skan    at(size_type __n) const
640132720Skan    { _M_range_check(__n); return (*this)[__n]; }
641132720Skan
642169691Skan    void
643169691Skan    reserve(size_type __n)
64497403Sobrien    {
645110614Skan      if (__n > this->max_size())
646132720Skan	__throw_length_error(__N("vector::reserve"));
647132720Skan      if (this->capacity() < __n)
648132720Skan	{
649132720Skan	  _Bit_type* __q = this->_M_allocate(__n);
650169691Skan	  this->_M_impl._M_finish = _M_copy_aligned(begin(), end(),
651169691Skan						    iterator(__q, 0));
652132720Skan	  this->_M_deallocate();
653132720Skan	  this->_M_impl._M_start = iterator(__q, 0);
654169691Skan	  this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1)
655169691Skan					     / int(_S_word_bit));
656132720Skan	}
65797403Sobrien    }
658132720Skan
659169691Skan    reference
660169691Skan    front()
661132720Skan    { return *begin(); }
662132720Skan
663169691Skan    const_reference
664169691Skan    front() const
665132720Skan    { return *begin(); }
666132720Skan
667169691Skan    reference
668169691Skan    back()
669132720Skan    { return *(end() - 1); }
670132720Skan
671169691Skan    const_reference
672169691Skan    back() const
673132720Skan    { return *(end() - 1); }
674132720Skan
675169691Skan    // _GLIBCXX_RESOLVE_LIB_DEFECTS
676169691Skan    // DR 464. Suggestion for new member functions in standard containers.
677169691Skan    // N.B. DR 464 says nothing about vector<bool> but we need something
678169691Skan    // here due to the way we are implementing DR 464 in the debug-mode
679169691Skan    // vector class.
680169691Skan    void
681169691Skan    data() { }
682169691Skan
683169691Skan    void
684169691Skan    push_back(bool __x)
685132720Skan    {
686132720Skan      if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
687132720Skan        *this->_M_impl._M_finish++ = __x;
68897403Sobrien      else
68997403Sobrien        _M_insert_aux(end(), __x);
69097403Sobrien    }
691132720Skan
692169691Skan    void
693236829Spfg    swap(vector& __x)
694132720Skan    {
695132720Skan      std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
696132720Skan      std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
697132720Skan      std::swap(this->_M_impl._M_end_of_storage,
698132720Skan		__x._M_impl._M_end_of_storage);
699169691Skan
700169691Skan      // _GLIBCXX_RESOLVE_LIB_DEFECTS
701169691Skan      // 431. Swapping containers with unequal allocators.
702169691Skan      std::__alloc_swap<typename _Base::_Bit_alloc_type>::
703169691Skan	_S_do_it(_M_get_Bit_allocator(), __x._M_get_Bit_allocator());
70497403Sobrien    }
705117397Skan
706117397Skan    // [23.2.5]/1, third-to-last entry in synopsis listing
707169691Skan    static void
708169691Skan    swap(reference __x, reference __y)
709132720Skan    {
710117397Skan      bool __tmp = __x;
711117397Skan      __x = __y;
712117397Skan      __y = __tmp;
713117397Skan    }
714117397Skan
715169691Skan    iterator
716169691Skan    insert(iterator __position, const bool& __x = bool())
717132720Skan    {
718132720Skan      const difference_type __n = __position - begin();
719132720Skan      if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage
720132720Skan	  && __position == end())
721132720Skan        *this->_M_impl._M_finish++ = __x;
72297403Sobrien      else
72397403Sobrien        _M_insert_aux(__position, __x);
72497403Sobrien      return begin() + __n;
72597403Sobrien    }
726132720Skan
727169691Skan    template<class _InputIterator>
728169691Skan      void
729169691Skan      insert(iterator __position,
730169691Skan	     _InputIterator __first, _InputIterator __last)
731169691Skan      {
732169691Skan	typedef typename std::__is_integer<_InputIterator>::__type _Integral;
733169691Skan	_M_insert_dispatch(__position, __first, __last, _Integral());
734169691Skan      }
735169691Skan
736169691Skan    void
737169691Skan    insert(iterator __position, size_type __n, const bool& __x)
738169691Skan    { _M_fill_insert(__position, __n, __x); }
739169691Skan
740169691Skan    void
741169691Skan    pop_back()
742169691Skan    { --this->_M_impl._M_finish; }
743169691Skan
744169691Skan    iterator
745169691Skan    erase(iterator __position)
746169691Skan    {
747169691Skan      if (__position + 1 != end())
748169691Skan        std::copy(__position + 1, end(), __position);
749169691Skan      --this->_M_impl._M_finish;
750169691Skan      return __position;
751169691Skan    }
752169691Skan
753169691Skan    iterator
754169691Skan    erase(iterator __first, iterator __last)
755169691Skan    {
756169691Skan      _M_erase_at_end(std::copy(__last, end(), __first));
757169691Skan      return __first;
758169691Skan    }
759169691Skan
760169691Skan    void
761169691Skan    resize(size_type __new_size, bool __x = bool())
762169691Skan    {
763169691Skan      if (__new_size < size())
764169691Skan        _M_erase_at_end(begin() + difference_type(__new_size));
765169691Skan      else
766169691Skan        insert(end(), __new_size - size(), __x);
767169691Skan    }
768169691Skan
769169691Skan    void
770169691Skan    flip()
771169691Skan    {
772169691Skan      for (_Bit_type * __p = this->_M_impl._M_start._M_p;
773169691Skan	   __p != this->_M_impl._M_end_of_storage; ++__p)
774169691Skan        *__p = ~*__p;
775169691Skan    }
776169691Skan
777169691Skan    void
778169691Skan    clear()
779169691Skan    { _M_erase_at_end(begin()); }
780169691Skan
781169691Skan
782169691Skan  protected:
783169691Skan    // Precondition: __first._M_offset == 0 && __result._M_offset == 0.
784169691Skan    iterator
785169691Skan    _M_copy_aligned(const_iterator __first, const_iterator __last,
786169691Skan		    iterator __result)
787169691Skan    {
788169691Skan      _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p);
789169691Skan      return std::copy(const_iterator(__last._M_p, 0), __last,
790169691Skan		       iterator(__q, 0));
791169691Skan    }
792169691Skan
793169691Skan    void
794169691Skan    _M_initialize(size_type __n)
795169691Skan    {
796169691Skan      _Bit_type* __q = this->_M_allocate(__n);
797169691Skan      this->_M_impl._M_end_of_storage = (__q
798169691Skan					 + ((__n + int(_S_word_bit) - 1)
799169691Skan					    / int(_S_word_bit)));
800169691Skan      this->_M_impl._M_start = iterator(__q, 0);
801169691Skan      this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
802169691Skan    }
803169691Skan
80497403Sobrien    // Check whether it's an integral type.  If so, it's not an iterator.
805169691Skan    template<class _Integer>
806169691Skan      void
807169691Skan      _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
808169691Skan      {
809169691Skan	_M_initialize(__n);
810169691Skan	std::fill(this->_M_impl._M_start._M_p,
811169691Skan		  this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
812169691Skan      }
813132720Skan
814169691Skan    template<class _InputIterator>
815169691Skan      void
816169691Skan      _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
817169691Skan			     __false_type)
818169691Skan      { _M_initialize_range(__first, __last,
819169691Skan			    std::__iterator_category(__first)); }
820169691Skan
821169691Skan    template<class _InputIterator>
822169691Skan      void
823169691Skan      _M_initialize_range(_InputIterator __first, _InputIterator __last,
824169691Skan			  std::input_iterator_tag)
825169691Skan      {
826169691Skan	for (; __first != __last; ++__first)
827169691Skan	  push_back(*__first);
828169691Skan      }
829169691Skan
830169691Skan    template<class _ForwardIterator>
831169691Skan      void
832169691Skan      _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last,
833169691Skan			  std::forward_iterator_tag)
834169691Skan      {
835169691Skan	const size_type __n = std::distance(__first, __last);
836169691Skan	_M_initialize(__n);
837169691Skan	std::copy(__first, __last, this->_M_impl._M_start);
838169691Skan      }
839169691Skan
840132720Skan    template<class _Integer>
841169691Skan      void
842169691Skan      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
843169691Skan      { _M_fill_assign((size_t) __n, (bool) __val); }
844132720Skan
845132720Skan    template<class _InputIterator>
846169691Skan      void
847169691Skan      _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
848169691Skan			 __false_type)
849169691Skan      { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
850132720Skan
851169691Skan    void
852169691Skan    _M_fill_assign(size_t __n, bool __x)
853132720Skan    {
854169691Skan      if (__n > size())
855169691Skan	{
856169691Skan	  std::fill(this->_M_impl._M_start._M_p,
857169691Skan		    this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
858169691Skan	  insert(end(), __n - size(), __x);
859169691Skan	}
860169691Skan      else
861169691Skan	{
862169691Skan	  _M_erase_at_end(begin() + __n);
863169691Skan	  std::fill(this->_M_impl._M_start._M_p,
864169691Skan		    this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
865169691Skan	}
86697403Sobrien    }
867132720Skan
868169691Skan    template<class _InputIterator>
869169691Skan      void
870169691Skan      _M_assign_aux(_InputIterator __first, _InputIterator __last,
871169691Skan		    std::input_iterator_tag)
872169691Skan      {
873169691Skan	iterator __cur = begin();
874169691Skan	for (; __first != __last && __cur != end(); ++__cur, ++__first)
875169691Skan	  *__cur = *__first;
876169691Skan	if (__first == __last)
877169691Skan	  _M_erase_at_end(__cur);
878169691Skan	else
879169691Skan	  insert(end(), __first, __last);
880169691Skan      }
881169691Skan
882169691Skan    template<class _ForwardIterator>
883169691Skan      void
884169691Skan      _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
885169691Skan		    std::forward_iterator_tag)
886169691Skan      {
887169691Skan	const size_type __len = std::distance(__first, __last);
888169691Skan	if (__len < size())
889169691Skan	  _M_erase_at_end(std::copy(__first, __last, begin()));
890169691Skan	else
891169691Skan	  {
892169691Skan	    _ForwardIterator __mid = __first;
893169691Skan	    std::advance(__mid, size());
894169691Skan	    std::copy(__first, __mid, begin());
895169691Skan	    insert(end(), __mid, __last);
896169691Skan	  }
897169691Skan      }
898169691Skan
899169691Skan    // Check whether it's an integral type.  If so, it's not an iterator.
900169691Skan    template<class _Integer>
901169691Skan      void
902169691Skan      _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
903169691Skan			 __true_type)
904169691Skan      { _M_fill_insert(__pos, __n, __x); }
905169691Skan
906169691Skan    template<class _InputIterator>
907169691Skan      void
908169691Skan      _M_insert_dispatch(iterator __pos,
909169691Skan			 _InputIterator __first, _InputIterator __last,
910169691Skan			 __false_type)
911169691Skan      { _M_insert_range(__pos, __first, __last,
912169691Skan			std::__iterator_category(__first)); }
913169691Skan
914169691Skan    void
915169691Skan    _M_fill_insert(iterator __position, size_type __n, bool __x)
916132720Skan    {
917132720Skan      if (__n == 0)
918132720Skan	return;
919132720Skan      if (capacity() - size() >= __n)
920132720Skan	{
921132720Skan	  std::copy_backward(__position, end(),
922132720Skan			     this->_M_impl._M_finish + difference_type(__n));
923132720Skan	  std::fill(__position, __position + difference_type(__n), __x);
924132720Skan	  this->_M_impl._M_finish += difference_type(__n);
925132720Skan	}
926132720Skan      else
927132720Skan	{
928132720Skan	  const size_type __len = size() + std::max(size(), __n);
929132720Skan	  _Bit_type * __q = this->_M_allocate(__len);
930169691Skan	  iterator __i = _M_copy_aligned(begin(), __position,
931169691Skan					 iterator(__q, 0));
932169691Skan	  std::fill(__i, __i + difference_type(__n), __x);
933132720Skan	  this->_M_impl._M_finish = std::copy(__position, end(),
934132720Skan					      __i + difference_type(__n));
935132720Skan	  this->_M_deallocate();
936169691Skan	  this->_M_impl._M_end_of_storage = (__q + ((__len
937169691Skan						     + int(_S_word_bit) - 1)
938169691Skan						    / int(_S_word_bit)));
939132720Skan	  this->_M_impl._M_start = iterator(__q, 0);
940132720Skan	}
94197403Sobrien    }
942132720Skan
943169691Skan    template<class _InputIterator>
944169691Skan      void
945169691Skan      _M_insert_range(iterator __pos, _InputIterator __first,
946169691Skan		      _InputIterator __last, std::input_iterator_tag)
947169691Skan      {
948169691Skan	for (; __first != __last; ++__first)
949169691Skan	  {
950169691Skan	    __pos = insert(__pos, *__first);
951169691Skan	    ++__pos;
952169691Skan	  }
953169691Skan      }
954132720Skan
955169691Skan    template<class _ForwardIterator>
956169691Skan      void
957169691Skan      _M_insert_range(iterator __position, _ForwardIterator __first,
958169691Skan		      _ForwardIterator __last, std::forward_iterator_tag)
959169691Skan      {
960169691Skan	if (__first != __last)
961169691Skan	  {
962169691Skan	    size_type __n = std::distance(__first, __last);
963169691Skan	    if (capacity() - size() >= __n)
964169691Skan	      {
965169691Skan		std::copy_backward(__position, end(),
966169691Skan				   this->_M_impl._M_finish
967169691Skan				   + difference_type(__n));
968169691Skan		std::copy(__first, __last, __position);
969169691Skan		this->_M_impl._M_finish += difference_type(__n);
970169691Skan	      }
971169691Skan	    else
972169691Skan	      {
973169691Skan		const size_type __len = size() + std::max(size(), __n);
974169691Skan		_Bit_type * __q = this->_M_allocate(__len);
975169691Skan		iterator __i = _M_copy_aligned(begin(), __position,
976169691Skan					       iterator(__q, 0));
977169691Skan		__i = std::copy(__first, __last, __i);
978169691Skan		this->_M_impl._M_finish = std::copy(__position, end(), __i);
979169691Skan		this->_M_deallocate();
980169691Skan		this->_M_impl._M_end_of_storage = (__q
981169691Skan						   + ((__len
982169691Skan						       + int(_S_word_bit) - 1)
983169691Skan						      / int(_S_word_bit)));
984169691Skan		this->_M_impl._M_start = iterator(__q, 0);
985169691Skan	      }
986169691Skan	  }
987169691Skan      }
988132720Skan
989169691Skan    void
990169691Skan    _M_insert_aux(iterator __position, bool __x)
991132720Skan    {
992169691Skan      if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
993169691Skan	{
994169691Skan	  std::copy_backward(__position, this->_M_impl._M_finish,
995169691Skan			     this->_M_impl._M_finish + 1);
996169691Skan	  *__position = __x;
997169691Skan	  ++this->_M_impl._M_finish;
998169691Skan	}
99997403Sobrien      else
1000169691Skan	{
1001169691Skan	  const size_type __len = size() ? 2 * size()
1002169691Skan	                                 : static_cast<size_type>(_S_word_bit);
1003169691Skan	  _Bit_type * __q = this->_M_allocate(__len);
1004169691Skan	  iterator __i = _M_copy_aligned(begin(), __position,
1005169691Skan					 iterator(__q, 0));
1006169691Skan	  *__i++ = __x;
1007169691Skan	  this->_M_impl._M_finish = std::copy(__position, end(), __i);
1008169691Skan	  this->_M_deallocate();
1009169691Skan	  this->_M_impl._M_end_of_storage = (__q + ((__len
1010169691Skan						     + int(_S_word_bit) - 1)
1011169691Skan						    / int(_S_word_bit)));
1012169691Skan	  this->_M_impl._M_start = iterator(__q, 0);
1013169691Skan	}
101497403Sobrien    }
1015132720Skan
1016169691Skan    void
1017169691Skan    _M_erase_at_end(iterator __pos)
1018169691Skan    { this->_M_impl._M_finish = __pos; }
101997403Sobrien  };
102097403Sobrien
1021169691Skan_GLIBCXX_END_NESTED_NAMESPACE
1022169691Skan
1023132720Skan#endif
1024