1ffeaf689SAlexander Kabaev // vector<bool> specialization -*- C++ -*-
200db7afdSDavid E. O'Brien
3f8a1b7d9SAlexander Kabaev // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
4f8a1b7d9SAlexander Kabaev // Free Software Foundation, Inc.
500db7afdSDavid E. O'Brien //
600db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library. This library is free
700db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
800db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
900db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
1000db7afdSDavid E. O'Brien // any later version.
1100db7afdSDavid E. O'Brien
1200db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1300db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1400db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1500db7afdSDavid E. O'Brien // GNU General Public License for more details.
1600db7afdSDavid E. O'Brien
1700db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1800db7afdSDavid E. O'Brien // with this library; see the file COPYING. If not, write to the Free
19f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2000db7afdSDavid E. O'Brien // USA.
2100db7afdSDavid E. O'Brien
2200db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2300db7afdSDavid E. O'Brien // library without restriction. Specifically, if other files instantiate
2400db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2500db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2600db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2700db7afdSDavid E. O'Brien // the GNU General Public License. This exception does not however
2800db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2900db7afdSDavid E. O'Brien // the GNU General Public License.
3000db7afdSDavid E. O'Brien
3100db7afdSDavid E. O'Brien /*
3200db7afdSDavid E. O'Brien *
3300db7afdSDavid E. O'Brien * Copyright (c) 1994
3400db7afdSDavid E. O'Brien * Hewlett-Packard Company
3500db7afdSDavid E. O'Brien *
3600db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software
3700db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee,
3800db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and
3900db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear
4000db7afdSDavid E. O'Brien * in supporting documentation. Hewlett-Packard Company makes no
4100db7afdSDavid E. O'Brien * representations about the suitability of this software for any
4200db7afdSDavid E. O'Brien * purpose. It is provided "as is" without express or implied warranty.
4300db7afdSDavid E. O'Brien *
4400db7afdSDavid E. O'Brien *
4500db7afdSDavid E. O'Brien * Copyright (c) 1996-1999
4600db7afdSDavid E. O'Brien * Silicon Graphics Computer Systems, Inc.
4700db7afdSDavid E. O'Brien *
4800db7afdSDavid E. O'Brien * Permission to use, copy, modify, distribute and sell this software
4900db7afdSDavid E. O'Brien * and its documentation for any purpose is hereby granted without fee,
5000db7afdSDavid E. O'Brien * provided that the above copyright notice appear in all copies and
5100db7afdSDavid E. O'Brien * that both that copyright notice and this permission notice appear
5200db7afdSDavid E. O'Brien * in supporting documentation. Silicon Graphics makes no
5300db7afdSDavid E. O'Brien * representations about the suitability of this software for any
5400db7afdSDavid E. O'Brien * purpose. It is provided "as is" without express or implied warranty.
5500db7afdSDavid E. O'Brien */
5600db7afdSDavid E. O'Brien
5700db7afdSDavid E. O'Brien /** @file stl_bvector.h
5800db7afdSDavid E. O'Brien * This is an internal header file, included by other library headers.
5900db7afdSDavid E. O'Brien * You should not attempt to use it directly.
6000db7afdSDavid E. O'Brien */
6100db7afdSDavid E. O'Brien
62ffeaf689SAlexander Kabaev #ifndef _BVECTOR_H
63ffeaf689SAlexander Kabaev #define _BVECTOR_H 1
6400db7afdSDavid E. O'Brien
65f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
66f8a1b7d9SAlexander Kabaev
6700db7afdSDavid E. O'Brien typedef unsigned long _Bit_type;
68ffeaf689SAlexander Kabaev enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) };
6900db7afdSDavid E. O'Brien
70ffeaf689SAlexander Kabaev struct _Bit_reference
71ffeaf689SAlexander Kabaev {
7200db7afdSDavid E. O'Brien _Bit_type * _M_p;
7300db7afdSDavid E. O'Brien _Bit_type _M_mask;
74ffeaf689SAlexander Kabaev
_Bit_reference_Bit_reference7500db7afdSDavid E. O'Brien _Bit_reference(_Bit_type * __x, _Bit_type __y)
7600db7afdSDavid E. O'Brien : _M_p(__x), _M_mask(__y) { }
7700db7afdSDavid E. O'Brien
_Bit_reference_Bit_reference7800db7afdSDavid E. O'Brien _Bit_reference() : _M_p(0), _M_mask(0) { }
79ffeaf689SAlexander Kabaev
80f8a1b7d9SAlexander Kabaev operator bool() const
81f8a1b7d9SAlexander Kabaev { return !!(*_M_p & _M_mask); }
82ffeaf689SAlexander Kabaev
83ffeaf689SAlexander Kabaev _Bit_reference&
84ffeaf689SAlexander Kabaev operator=(bool __x)
8500db7afdSDavid E. O'Brien {
86ffeaf689SAlexander Kabaev if (__x)
87ffeaf689SAlexander Kabaev *_M_p |= _M_mask;
88ffeaf689SAlexander Kabaev else
89ffeaf689SAlexander Kabaev *_M_p &= ~_M_mask;
9000db7afdSDavid E. O'Brien return *this;
9100db7afdSDavid E. O'Brien }
92ffeaf689SAlexander Kabaev
93ffeaf689SAlexander Kabaev _Bit_reference&
94ffeaf689SAlexander Kabaev operator=(const _Bit_reference& __x)
9500db7afdSDavid E. O'Brien { return *this = bool(__x); }
96ffeaf689SAlexander Kabaev
97ffeaf689SAlexander Kabaev bool
98ffeaf689SAlexander Kabaev operator==(const _Bit_reference& __x) const
9900db7afdSDavid E. O'Brien { return bool(*this) == bool(__x); }
100ffeaf689SAlexander Kabaev
101ffeaf689SAlexander Kabaev bool
102ffeaf689SAlexander Kabaev operator<(const _Bit_reference& __x) const
10300db7afdSDavid E. O'Brien { return !bool(*this) && bool(__x); }
104ffeaf689SAlexander Kabaev
105ffeaf689SAlexander Kabaev void
flip_Bit_reference106f8a1b7d9SAlexander Kabaev flip()
107f8a1b7d9SAlexander Kabaev { *_M_p ^= _M_mask; }
10800db7afdSDavid E. O'Brien };
10900db7afdSDavid E. O'Brien
110f8a1b7d9SAlexander Kabaev struct _Bit_iterator_base
111f8a1b7d9SAlexander Kabaev : public std::iterator<std::random_access_iterator_tag, bool>
11200db7afdSDavid E. O'Brien {
11300db7afdSDavid E. O'Brien _Bit_type * _M_p;
11400db7afdSDavid E. O'Brien unsigned int _M_offset;
11500db7afdSDavid E. O'Brien
_Bit_iterator_base_Bit_iterator_base11600db7afdSDavid E. O'Brien _Bit_iterator_base(_Bit_type * __x, unsigned int __y)
11700db7afdSDavid E. O'Brien : _M_p(__x), _M_offset(__y) { }
11800db7afdSDavid E. O'Brien
119ffeaf689SAlexander Kabaev void
_M_bump_up_Bit_iterator_base120ffeaf689SAlexander Kabaev _M_bump_up()
121ffeaf689SAlexander Kabaev {
122f8a1b7d9SAlexander Kabaev if (_M_offset++ == int(_S_word_bit) - 1)
123ffeaf689SAlexander Kabaev {
12400db7afdSDavid E. O'Brien _M_offset = 0;
12500db7afdSDavid E. O'Brien ++_M_p;
12600db7afdSDavid E. O'Brien }
12700db7afdSDavid E. O'Brien }
128ffeaf689SAlexander Kabaev
129ffeaf689SAlexander Kabaev void
_M_bump_down_Bit_iterator_base130ffeaf689SAlexander Kabaev _M_bump_down()
131ffeaf689SAlexander Kabaev {
132ffeaf689SAlexander Kabaev if (_M_offset-- == 0)
133ffeaf689SAlexander Kabaev {
134f8a1b7d9SAlexander Kabaev _M_offset = int(_S_word_bit) - 1;
13500db7afdSDavid E. O'Brien --_M_p;
13600db7afdSDavid E. O'Brien }
13700db7afdSDavid E. O'Brien }
13800db7afdSDavid E. O'Brien
139ffeaf689SAlexander Kabaev void
_M_incr_Bit_iterator_base140ffeaf689SAlexander Kabaev _M_incr(ptrdiff_t __i)
141ffeaf689SAlexander Kabaev {
14200db7afdSDavid E. O'Brien difference_type __n = __i + _M_offset;
143f8a1b7d9SAlexander Kabaev _M_p += __n / int(_S_word_bit);
144f8a1b7d9SAlexander Kabaev __n = __n % int(_S_word_bit);
145ffeaf689SAlexander Kabaev if (__n < 0)
146ffeaf689SAlexander Kabaev {
147f8a1b7d9SAlexander Kabaev __n += int(_S_word_bit);
14800db7afdSDavid E. O'Brien --_M_p;
149ffeaf689SAlexander Kabaev }
150ffeaf689SAlexander Kabaev _M_offset = static_cast<unsigned int>(__n);
15100db7afdSDavid E. O'Brien }
15200db7afdSDavid E. O'Brien
153ffeaf689SAlexander Kabaev bool
154ffeaf689SAlexander Kabaev operator==(const _Bit_iterator_base& __i) const
155ffeaf689SAlexander Kabaev { return _M_p == __i._M_p && _M_offset == __i._M_offset; }
156ffeaf689SAlexander Kabaev
157ffeaf689SAlexander Kabaev bool
158ffeaf689SAlexander Kabaev operator<(const _Bit_iterator_base& __i) const
159ffeaf689SAlexander Kabaev {
160ffeaf689SAlexander Kabaev return _M_p < __i._M_p
161ffeaf689SAlexander Kabaev || (_M_p == __i._M_p && _M_offset < __i._M_offset);
16200db7afdSDavid E. O'Brien }
163ffeaf689SAlexander Kabaev
164ffeaf689SAlexander Kabaev bool
165ffeaf689SAlexander Kabaev operator!=(const _Bit_iterator_base& __i) const
166ffeaf689SAlexander Kabaev { return !(*this == __i); }
167ffeaf689SAlexander Kabaev
168ffeaf689SAlexander Kabaev bool
169ffeaf689SAlexander Kabaev operator>(const _Bit_iterator_base& __i) const
170ffeaf689SAlexander Kabaev { return __i < *this; }
171ffeaf689SAlexander Kabaev
172ffeaf689SAlexander Kabaev bool
173ffeaf689SAlexander Kabaev operator<=(const _Bit_iterator_base& __i) const
174ffeaf689SAlexander Kabaev { return !(__i < *this); }
175ffeaf689SAlexander Kabaev
176ffeaf689SAlexander Kabaev bool
177ffeaf689SAlexander Kabaev operator>=(const _Bit_iterator_base& __i) const
178ffeaf689SAlexander Kabaev { return !(*this < __i); }
17900db7afdSDavid E. O'Brien };
18000db7afdSDavid E. O'Brien
18100db7afdSDavid E. O'Brien inline ptrdiff_t
182ffeaf689SAlexander Kabaev operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
183ffeaf689SAlexander Kabaev {
184f8a1b7d9SAlexander Kabaev return (int(_S_word_bit) * (__x._M_p - __y._M_p)
185f8a1b7d9SAlexander Kabaev + __x._M_offset - __y._M_offset);
18600db7afdSDavid E. O'Brien }
18700db7afdSDavid E. O'Brien
18800db7afdSDavid E. O'Brien struct _Bit_iterator : public _Bit_iterator_base
18900db7afdSDavid E. O'Brien {
19000db7afdSDavid E. O'Brien typedef _Bit_reference reference;
19100db7afdSDavid E. O'Brien typedef _Bit_reference* pointer;
19200db7afdSDavid E. O'Brien typedef _Bit_iterator iterator;
19300db7afdSDavid E. O'Brien
_Bit_iterator_Bit_iterator19400db7afdSDavid E. O'Brien _Bit_iterator() : _Bit_iterator_base(0, 0) { }
195f8a1b7d9SAlexander Kabaev
_Bit_iterator_Bit_iterator19600db7afdSDavid E. O'Brien _Bit_iterator(_Bit_type * __x, unsigned int __y)
19700db7afdSDavid E. O'Brien : _Bit_iterator_base(__x, __y) { }
19800db7afdSDavid E. O'Brien
199ffeaf689SAlexander Kabaev reference
200f8a1b7d9SAlexander Kabaev operator*() const
201f8a1b7d9SAlexander Kabaev { return reference(_M_p, 1UL << _M_offset); }
202ffeaf689SAlexander Kabaev
203ffeaf689SAlexander Kabaev iterator&
204ffeaf689SAlexander Kabaev operator++()
205ffeaf689SAlexander Kabaev {
20600db7afdSDavid E. O'Brien _M_bump_up();
20700db7afdSDavid E. O'Brien return *this;
20800db7afdSDavid E. O'Brien }
209ffeaf689SAlexander Kabaev
210ffeaf689SAlexander Kabaev iterator
211ffeaf689SAlexander Kabaev operator++(int)
212ffeaf689SAlexander Kabaev {
21300db7afdSDavid E. O'Brien iterator __tmp = *this;
21400db7afdSDavid E. O'Brien _M_bump_up();
21500db7afdSDavid E. O'Brien return __tmp;
21600db7afdSDavid E. O'Brien }
217ffeaf689SAlexander Kabaev
218ffeaf689SAlexander Kabaev iterator&
219ffeaf689SAlexander Kabaev operator--()
220ffeaf689SAlexander Kabaev {
22100db7afdSDavid E. O'Brien _M_bump_down();
22200db7afdSDavid E. O'Brien return *this;
22300db7afdSDavid E. O'Brien }
224ffeaf689SAlexander Kabaev
225ffeaf689SAlexander Kabaev iterator
226ffeaf689SAlexander Kabaev operator--(int)
227ffeaf689SAlexander Kabaev {
22800db7afdSDavid E. O'Brien iterator __tmp = *this;
22900db7afdSDavid E. O'Brien _M_bump_down();
23000db7afdSDavid E. O'Brien return __tmp;
23100db7afdSDavid E. O'Brien }
232ffeaf689SAlexander Kabaev
233ffeaf689SAlexander Kabaev iterator&
234ffeaf689SAlexander Kabaev operator+=(difference_type __i)
235ffeaf689SAlexander Kabaev {
23600db7afdSDavid E. O'Brien _M_incr(__i);
23700db7afdSDavid E. O'Brien return *this;
23800db7afdSDavid E. O'Brien }
239ffeaf689SAlexander Kabaev
240ffeaf689SAlexander Kabaev iterator&
241ffeaf689SAlexander Kabaev operator-=(difference_type __i)
242ffeaf689SAlexander Kabaev {
24300db7afdSDavid E. O'Brien *this += -__i;
24400db7afdSDavid E. O'Brien return *this;
24500db7afdSDavid E. O'Brien }
246ffeaf689SAlexander Kabaev
247ffeaf689SAlexander Kabaev iterator
248ffeaf689SAlexander Kabaev operator+(difference_type __i) const
249ffeaf689SAlexander Kabaev {
25000db7afdSDavid E. O'Brien iterator __tmp = *this;
25100db7afdSDavid E. O'Brien return __tmp += __i;
25200db7afdSDavid E. O'Brien }
253ffeaf689SAlexander Kabaev
254ffeaf689SAlexander Kabaev iterator
255ffeaf689SAlexander Kabaev operator-(difference_type __i) const
256ffeaf689SAlexander Kabaev {
25700db7afdSDavid E. O'Brien iterator __tmp = *this;
25800db7afdSDavid E. O'Brien return __tmp -= __i;
25900db7afdSDavid E. O'Brien }
26000db7afdSDavid E. O'Brien
261ffeaf689SAlexander Kabaev reference
262f8a1b7d9SAlexander Kabaev operator[](difference_type __i) const
263ffeaf689SAlexander Kabaev { return *(*this + __i); }
26400db7afdSDavid E. O'Brien };
26500db7afdSDavid E. O'Brien
26600db7afdSDavid E. O'Brien inline _Bit_iterator
267f8a1b7d9SAlexander Kabaev operator+(ptrdiff_t __n, const _Bit_iterator& __x)
268f8a1b7d9SAlexander Kabaev { return __x + __n; }
26900db7afdSDavid E. O'Brien
27000db7afdSDavid E. O'Brien struct _Bit_const_iterator : public _Bit_iterator_base
27100db7afdSDavid E. O'Brien {
27200db7afdSDavid E. O'Brien typedef bool reference;
27300db7afdSDavid E. O'Brien typedef bool const_reference;
27400db7afdSDavid E. O'Brien typedef const bool* pointer;
27500db7afdSDavid E. O'Brien typedef _Bit_const_iterator const_iterator;
27600db7afdSDavid E. O'Brien
_Bit_const_iterator_Bit_const_iterator27700db7afdSDavid E. O'Brien _Bit_const_iterator() : _Bit_iterator_base(0, 0) { }
278f8a1b7d9SAlexander Kabaev
_Bit_const_iterator_Bit_const_iterator27900db7afdSDavid E. O'Brien _Bit_const_iterator(_Bit_type * __x, unsigned int __y)
28000db7afdSDavid E. O'Brien : _Bit_iterator_base(__x, __y) { }
281f8a1b7d9SAlexander Kabaev
_Bit_const_iterator_Bit_const_iterator28200db7afdSDavid E. O'Brien _Bit_const_iterator(const _Bit_iterator& __x)
28300db7afdSDavid E. O'Brien : _Bit_iterator_base(__x._M_p, __x._M_offset) { }
28400db7afdSDavid E. O'Brien
285ffeaf689SAlexander Kabaev const_reference
286ffeaf689SAlexander Kabaev operator*() const
287ffeaf689SAlexander Kabaev { return _Bit_reference(_M_p, 1UL << _M_offset); }
288ffeaf689SAlexander Kabaev
289ffeaf689SAlexander Kabaev const_iterator&
290ffeaf689SAlexander Kabaev operator++()
291ffeaf689SAlexander Kabaev {
29200db7afdSDavid E. O'Brien _M_bump_up();
29300db7afdSDavid E. O'Brien return *this;
29400db7afdSDavid E. O'Brien }
295ffeaf689SAlexander Kabaev
296ffeaf689SAlexander Kabaev const_iterator
297ffeaf689SAlexander Kabaev operator++(int)
298ffeaf689SAlexander Kabaev {
29900db7afdSDavid E. O'Brien const_iterator __tmp = *this;
30000db7afdSDavid E. O'Brien _M_bump_up();
30100db7afdSDavid E. O'Brien return __tmp;
30200db7afdSDavid E. O'Brien }
303ffeaf689SAlexander Kabaev
304ffeaf689SAlexander Kabaev const_iterator&
305ffeaf689SAlexander Kabaev operator--()
306ffeaf689SAlexander Kabaev {
30700db7afdSDavid E. O'Brien _M_bump_down();
30800db7afdSDavid E. O'Brien return *this;
30900db7afdSDavid E. O'Brien }
310ffeaf689SAlexander Kabaev
311ffeaf689SAlexander Kabaev const_iterator
312ffeaf689SAlexander Kabaev operator--(int)
313ffeaf689SAlexander Kabaev {
31400db7afdSDavid E. O'Brien const_iterator __tmp = *this;
31500db7afdSDavid E. O'Brien _M_bump_down();
31600db7afdSDavid E. O'Brien return __tmp;
31700db7afdSDavid E. O'Brien }
318ffeaf689SAlexander Kabaev
319ffeaf689SAlexander Kabaev const_iterator&
320ffeaf689SAlexander Kabaev operator+=(difference_type __i)
321ffeaf689SAlexander Kabaev {
32200db7afdSDavid E. O'Brien _M_incr(__i);
32300db7afdSDavid E. O'Brien return *this;
32400db7afdSDavid E. O'Brien }
325ffeaf689SAlexander Kabaev
326ffeaf689SAlexander Kabaev const_iterator&
327ffeaf689SAlexander Kabaev operator-=(difference_type __i)
328ffeaf689SAlexander Kabaev {
32900db7afdSDavid E. O'Brien *this += -__i;
33000db7afdSDavid E. O'Brien return *this;
33100db7afdSDavid E. O'Brien }
332ffeaf689SAlexander Kabaev
333ffeaf689SAlexander Kabaev const_iterator
334f8a1b7d9SAlexander Kabaev operator+(difference_type __i) const
335f8a1b7d9SAlexander Kabaev {
33600db7afdSDavid E. O'Brien const_iterator __tmp = *this;
33700db7afdSDavid E. O'Brien return __tmp += __i;
33800db7afdSDavid E. O'Brien }
339ffeaf689SAlexander Kabaev
340ffeaf689SAlexander Kabaev const_iterator
341ffeaf689SAlexander Kabaev operator-(difference_type __i) const
342ffeaf689SAlexander Kabaev {
34300db7afdSDavid E. O'Brien const_iterator __tmp = *this;
34400db7afdSDavid E. O'Brien return __tmp -= __i;
34500db7afdSDavid E. O'Brien }
346ffeaf689SAlexander Kabaev
347ffeaf689SAlexander Kabaev const_reference
348f8a1b7d9SAlexander Kabaev operator[](difference_type __i) const
349ffeaf689SAlexander Kabaev { return *(*this + __i); }
35000db7afdSDavid E. O'Brien };
35100db7afdSDavid E. O'Brien
35200db7afdSDavid E. O'Brien inline _Bit_const_iterator
353ffeaf689SAlexander Kabaev operator+(ptrdiff_t __n, const _Bit_const_iterator& __x)
354ffeaf689SAlexander Kabaev { return __x + __n; }
35500db7afdSDavid E. O'Brien
356f8a1b7d9SAlexander Kabaev inline void
__fill_bvector(_Bit_iterator __first,_Bit_iterator __last,bool __x)357f8a1b7d9SAlexander Kabaev __fill_bvector(_Bit_iterator __first, _Bit_iterator __last, bool __x)
358f8a1b7d9SAlexander Kabaev {
359f8a1b7d9SAlexander Kabaev for (; __first != __last; ++__first)
360f8a1b7d9SAlexander Kabaev *__first = __x;
361f8a1b7d9SAlexander Kabaev }
362f8a1b7d9SAlexander Kabaev
363f8a1b7d9SAlexander Kabaev inline void
fill(_Bit_iterator __first,_Bit_iterator __last,const bool & __x)364f8a1b7d9SAlexander Kabaev fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x)
365f8a1b7d9SAlexander Kabaev {
366f8a1b7d9SAlexander Kabaev if (__first._M_p != __last._M_p)
367f8a1b7d9SAlexander Kabaev {
368f8a1b7d9SAlexander Kabaev std::fill(__first._M_p + 1, __last._M_p, __x ? ~0 : 0);
369f8a1b7d9SAlexander Kabaev __fill_bvector(__first, _Bit_iterator(__first._M_p + 1, 0), __x);
370f8a1b7d9SAlexander Kabaev __fill_bvector(_Bit_iterator(__last._M_p, 0), __last, __x);
371f8a1b7d9SAlexander Kabaev }
372f8a1b7d9SAlexander Kabaev else
373f8a1b7d9SAlexander Kabaev __fill_bvector(__first, __last, __x);
374f8a1b7d9SAlexander Kabaev }
375f8a1b7d9SAlexander Kabaev
37600db7afdSDavid E. O'Brien template<class _Alloc>
377f8a1b7d9SAlexander Kabaev struct _Bvector_base
37800db7afdSDavid E. O'Brien {
379ffeaf689SAlexander Kabaev typedef typename _Alloc::template rebind<_Bit_type>::other
380ffeaf689SAlexander Kabaev _Bit_alloc_type;
38100db7afdSDavid E. O'Brien
382f8a1b7d9SAlexander Kabaev struct _Bvector_impl
383f8a1b7d9SAlexander Kabaev : public _Bit_alloc_type
384ffeaf689SAlexander Kabaev {
385ffeaf689SAlexander Kabaev _Bit_iterator _M_start;
386ffeaf689SAlexander Kabaev _Bit_iterator _M_finish;
387ffeaf689SAlexander Kabaev _Bit_type* _M_end_of_storage;
388*dc3fe0ffSPedro F. Giffuni
_Bvector_impl_Bvector_base::_Bvector_impl389*dc3fe0ffSPedro F. Giffuni _Bvector_impl()
390*dc3fe0ffSPedro F. Giffuni : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage(0)
391*dc3fe0ffSPedro F. Giffuni { }
392*dc3fe0ffSPedro F. Giffuni
_Bvector_impl_Bvector_base::_Bvector_impl393ffeaf689SAlexander Kabaev _Bvector_impl(const _Bit_alloc_type& __a)
394ffeaf689SAlexander Kabaev : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0)
395ffeaf689SAlexander Kabaev { }
39600db7afdSDavid E. O'Brien };
39700db7afdSDavid E. O'Brien
398ffeaf689SAlexander Kabaev public:
399ffeaf689SAlexander Kabaev typedef _Alloc allocator_type;
400ffeaf689SAlexander Kabaev
401f8a1b7d9SAlexander Kabaev _Bit_alloc_type&
_M_get_Bit_allocator_Bvector_base402f8a1b7d9SAlexander Kabaev _M_get_Bit_allocator()
403f8a1b7d9SAlexander Kabaev { return *static_cast<_Bit_alloc_type*>(&this->_M_impl); }
404f8a1b7d9SAlexander Kabaev
405f8a1b7d9SAlexander Kabaev const _Bit_alloc_type&
_M_get_Bit_allocator_Bvector_base406f8a1b7d9SAlexander Kabaev _M_get_Bit_allocator() const
407f8a1b7d9SAlexander Kabaev { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); }
408f8a1b7d9SAlexander Kabaev
409ffeaf689SAlexander Kabaev allocator_type
get_allocator_Bvector_base410ffeaf689SAlexander Kabaev get_allocator() const
411f8a1b7d9SAlexander Kabaev { return allocator_type(_M_get_Bit_allocator()); }
412ffeaf689SAlexander Kabaev
_Bvector_base_Bvector_base413*dc3fe0ffSPedro F. Giffuni _Bvector_base()
414*dc3fe0ffSPedro F. Giffuni : _M_impl() { }
415*dc3fe0ffSPedro F. Giffuni
_Bvector_base_Bvector_base416*dc3fe0ffSPedro F. Giffuni _Bvector_base(const allocator_type& __a)
417*dc3fe0ffSPedro F. Giffuni : _M_impl(__a) { }
418ffeaf689SAlexander Kabaev
~_Bvector_base_Bvector_base419f8a1b7d9SAlexander Kabaev ~_Bvector_base()
420f8a1b7d9SAlexander Kabaev { this->_M_deallocate(); }
421ffeaf689SAlexander Kabaev
422ffeaf689SAlexander Kabaev protected:
423ffeaf689SAlexander Kabaev _Bvector_impl _M_impl;
424ffeaf689SAlexander Kabaev
425ffeaf689SAlexander Kabaev _Bit_type*
_M_allocate_Bvector_base426ffeaf689SAlexander Kabaev _M_allocate(size_t __n)
427f8a1b7d9SAlexander Kabaev { return _M_impl.allocate((__n + int(_S_word_bit) - 1)
428f8a1b7d9SAlexander Kabaev / int(_S_word_bit)); }
429ffeaf689SAlexander Kabaev
430ffeaf689SAlexander Kabaev void
_M_deallocate_Bvector_base431ffeaf689SAlexander Kabaev _M_deallocate()
432ffeaf689SAlexander Kabaev {
433ffeaf689SAlexander Kabaev if (_M_impl._M_start._M_p)
434ffeaf689SAlexander Kabaev _M_impl.deallocate(_M_impl._M_start._M_p,
435ffeaf689SAlexander Kabaev _M_impl._M_end_of_storage - _M_impl._M_start._M_p);
436ffeaf689SAlexander Kabaev }
437ffeaf689SAlexander Kabaev };
438f8a1b7d9SAlexander Kabaev
439f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NESTED_NAMESPACE
44000db7afdSDavid E. O'Brien
44100db7afdSDavid E. O'Brien // Declare a partial specialization of vector<T, Alloc>.
44200db7afdSDavid E. O'Brien #include <bits/stl_vector.h>
44300db7afdSDavid E. O'Brien
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std,_GLIBCXX_STD)444f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
445f8a1b7d9SAlexander Kabaev
446ffeaf689SAlexander Kabaev /**
447ffeaf689SAlexander Kabaev * @brief A specialization of vector for booleans which offers fixed time
448ffeaf689SAlexander Kabaev * access to individual elements in any order.
449ffeaf689SAlexander Kabaev *
450ffeaf689SAlexander Kabaev * Note that vector<bool> does not actually meet the requirements for being
451ffeaf689SAlexander Kabaev * a container. This is because the reference and pointer types are not
452ffeaf689SAlexander Kabaev * really references and pointers to bool. See DR96 for details. @see
453ffeaf689SAlexander Kabaev * vector for function documentation.
454ffeaf689SAlexander Kabaev *
455ffeaf689SAlexander Kabaev * @ingroup Containers
456ffeaf689SAlexander Kabaev * @ingroup Sequences
457ffeaf689SAlexander Kabaev *
458ffeaf689SAlexander Kabaev * In some terminology a %vector can be described as a dynamic
459ffeaf689SAlexander Kabaev * C-style array, it offers fast and efficient access to individual
460ffeaf689SAlexander Kabaev * elements in any order and saves the user from worrying about
461ffeaf689SAlexander Kabaev * memory and size allocation. Subscripting ( @c [] ) access is
462ffeaf689SAlexander Kabaev * also provided as with C-style arrays.
463ffeaf689SAlexander Kabaev */
46400db7afdSDavid E. O'Brien template<typename _Alloc>
465f8a1b7d9SAlexander Kabaev class vector<bool, _Alloc> : protected _Bvector_base<_Alloc>
46600db7afdSDavid E. O'Brien {
467f8a1b7d9SAlexander Kabaev typedef _Bvector_base<_Alloc> _Base;
468f8a1b7d9SAlexander Kabaev
46900db7afdSDavid E. O'Brien public:
47000db7afdSDavid E. O'Brien typedef bool value_type;
47100db7afdSDavid E. O'Brien typedef size_t size_type;
47200db7afdSDavid E. O'Brien typedef ptrdiff_t difference_type;
47300db7afdSDavid E. O'Brien typedef _Bit_reference reference;
47400db7afdSDavid E. O'Brien typedef bool const_reference;
47500db7afdSDavid E. O'Brien typedef _Bit_reference* pointer;
47600db7afdSDavid E. O'Brien typedef const bool* const_pointer;
47700db7afdSDavid E. O'Brien typedef _Bit_iterator iterator;
47800db7afdSDavid E. O'Brien typedef _Bit_const_iterator const_iterator;
4791b86b14eSAlexander Kabaev typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
4801b86b14eSAlexander Kabaev typedef std::reverse_iterator<iterator> reverse_iterator;
481f8a1b7d9SAlexander Kabaev typedef _Alloc allocator_type;
482ffeaf689SAlexander Kabaev
483ffeaf689SAlexander Kabaev allocator_type get_allocator() const
484f8a1b7d9SAlexander Kabaev { return _Base::get_allocator(); }
48500db7afdSDavid E. O'Brien
48600db7afdSDavid E. O'Brien protected:
487f8a1b7d9SAlexander Kabaev using _Base::_M_allocate;
488f8a1b7d9SAlexander Kabaev using _Base::_M_deallocate;
489f8a1b7d9SAlexander Kabaev using _Base::_M_get_Bit_allocator;
49000db7afdSDavid E. O'Brien
49100db7afdSDavid E. O'Brien public:
492*dc3fe0ffSPedro F. Giffuni vector()
493*dc3fe0ffSPedro F. Giffuni : _Base() { }
494*dc3fe0ffSPedro F. Giffuni
495f8a1b7d9SAlexander Kabaev explicit
496*dc3fe0ffSPedro F. Giffuni vector(const allocator_type& __a)
497f8a1b7d9SAlexander Kabaev : _Base(__a) { }
49800db7afdSDavid E. O'Brien
499f8a1b7d9SAlexander Kabaev explicit
500f8a1b7d9SAlexander Kabaev vector(size_type __n, const bool& __value = bool(),
50100db7afdSDavid E. O'Brien const allocator_type& __a = allocator_type())
502f8a1b7d9SAlexander Kabaev : _Base(__a)
50300db7afdSDavid E. O'Brien {
50400db7afdSDavid E. O'Brien _M_initialize(__n);
505ffeaf689SAlexander Kabaev std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage,
506ffeaf689SAlexander Kabaev __value ? ~0 : 0);
50700db7afdSDavid E. O'Brien }
50800db7afdSDavid E. O'Brien
509f8a1b7d9SAlexander Kabaev vector(const vector& __x)
510f8a1b7d9SAlexander Kabaev : _Base(__x._M_get_Bit_allocator())
511ffeaf689SAlexander Kabaev {
51200db7afdSDavid E. O'Brien _M_initialize(__x.size());
513f8a1b7d9SAlexander Kabaev _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
514f8a1b7d9SAlexander Kabaev }
515f8a1b7d9SAlexander Kabaev
516f8a1b7d9SAlexander Kabaev template<class _InputIterator>
517f8a1b7d9SAlexander Kabaev vector(_InputIterator __first, _InputIterator __last,
518f8a1b7d9SAlexander Kabaev const allocator_type& __a = allocator_type())
519f8a1b7d9SAlexander Kabaev : _Base(__a)
520f8a1b7d9SAlexander Kabaev {
521f8a1b7d9SAlexander Kabaev typedef typename std::__is_integer<_InputIterator>::__type _Integral;
522f8a1b7d9SAlexander Kabaev _M_initialize_dispatch(__first, __last, _Integral());
523f8a1b7d9SAlexander Kabaev }
524f8a1b7d9SAlexander Kabaev
525f8a1b7d9SAlexander Kabaev ~vector() { }
526f8a1b7d9SAlexander Kabaev
527f8a1b7d9SAlexander Kabaev vector&
528f8a1b7d9SAlexander Kabaev operator=(const vector& __x)
529f8a1b7d9SAlexander Kabaev {
530f8a1b7d9SAlexander Kabaev if (&__x == this)
531f8a1b7d9SAlexander Kabaev return *this;
532f8a1b7d9SAlexander Kabaev if (__x.size() > capacity())
533f8a1b7d9SAlexander Kabaev {
534f8a1b7d9SAlexander Kabaev this->_M_deallocate();
535f8a1b7d9SAlexander Kabaev _M_initialize(__x.size());
536f8a1b7d9SAlexander Kabaev }
537f8a1b7d9SAlexander Kabaev this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
538f8a1b7d9SAlexander Kabaev begin());
539f8a1b7d9SAlexander Kabaev return *this;
540f8a1b7d9SAlexander Kabaev }
541f8a1b7d9SAlexander Kabaev
542f8a1b7d9SAlexander Kabaev // assign(), a generalized assignment member function. Two
543f8a1b7d9SAlexander Kabaev // versions: one that takes a count, and one that takes a range.
544f8a1b7d9SAlexander Kabaev // The range version is a member template, so we dispatch on whether
545f8a1b7d9SAlexander Kabaev // or not the type is an integer.
546f8a1b7d9SAlexander Kabaev void
547f8a1b7d9SAlexander Kabaev assign(size_type __n, const bool& __x)
548f8a1b7d9SAlexander Kabaev { _M_fill_assign(__n, __x); }
549f8a1b7d9SAlexander Kabaev
550f8a1b7d9SAlexander Kabaev template<class _InputIterator>
551f8a1b7d9SAlexander Kabaev void
552f8a1b7d9SAlexander Kabaev assign(_InputIterator __first, _InputIterator __last)
553f8a1b7d9SAlexander Kabaev {
554f8a1b7d9SAlexander Kabaev typedef typename std::__is_integer<_InputIterator>::__type _Integral;
555f8a1b7d9SAlexander Kabaev _M_assign_dispatch(__first, __last, _Integral());
556f8a1b7d9SAlexander Kabaev }
557f8a1b7d9SAlexander Kabaev
558f8a1b7d9SAlexander Kabaev iterator
559f8a1b7d9SAlexander Kabaev begin()
560f8a1b7d9SAlexander Kabaev { return this->_M_impl._M_start; }
561f8a1b7d9SAlexander Kabaev
562f8a1b7d9SAlexander Kabaev const_iterator
563f8a1b7d9SAlexander Kabaev begin() const
564f8a1b7d9SAlexander Kabaev { return this->_M_impl._M_start; }
565f8a1b7d9SAlexander Kabaev
566f8a1b7d9SAlexander Kabaev iterator
567f8a1b7d9SAlexander Kabaev end()
568f8a1b7d9SAlexander Kabaev { return this->_M_impl._M_finish; }
569f8a1b7d9SAlexander Kabaev
570f8a1b7d9SAlexander Kabaev const_iterator
571f8a1b7d9SAlexander Kabaev end() const
572f8a1b7d9SAlexander Kabaev { return this->_M_impl._M_finish; }
573f8a1b7d9SAlexander Kabaev
574f8a1b7d9SAlexander Kabaev reverse_iterator
575f8a1b7d9SAlexander Kabaev rbegin()
576f8a1b7d9SAlexander Kabaev { return reverse_iterator(end()); }
577f8a1b7d9SAlexander Kabaev
578f8a1b7d9SAlexander Kabaev const_reverse_iterator
579f8a1b7d9SAlexander Kabaev rbegin() const
580f8a1b7d9SAlexander Kabaev { return const_reverse_iterator(end()); }
581f8a1b7d9SAlexander Kabaev
582f8a1b7d9SAlexander Kabaev reverse_iterator
583f8a1b7d9SAlexander Kabaev rend()
584f8a1b7d9SAlexander Kabaev { return reverse_iterator(begin()); }
585f8a1b7d9SAlexander Kabaev
586f8a1b7d9SAlexander Kabaev const_reverse_iterator
587f8a1b7d9SAlexander Kabaev rend() const
588f8a1b7d9SAlexander Kabaev { return const_reverse_iterator(begin()); }
589f8a1b7d9SAlexander Kabaev
590f8a1b7d9SAlexander Kabaev size_type
591f8a1b7d9SAlexander Kabaev size() const
592f8a1b7d9SAlexander Kabaev { return size_type(end() - begin()); }
593f8a1b7d9SAlexander Kabaev
594f8a1b7d9SAlexander Kabaev size_type
595f8a1b7d9SAlexander Kabaev max_size() const
596f8a1b7d9SAlexander Kabaev {
597f8a1b7d9SAlexander Kabaev const size_type __asize = _M_get_Bit_allocator().max_size();
598f8a1b7d9SAlexander Kabaev return (__asize <= size_type(-1) / int(_S_word_bit) ?
599f8a1b7d9SAlexander Kabaev __asize * int(_S_word_bit) : size_type(-1));
600f8a1b7d9SAlexander Kabaev }
601f8a1b7d9SAlexander Kabaev
602f8a1b7d9SAlexander Kabaev size_type
603f8a1b7d9SAlexander Kabaev capacity() const
604f8a1b7d9SAlexander Kabaev { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0)
605f8a1b7d9SAlexander Kabaev - begin()); }
606f8a1b7d9SAlexander Kabaev
607f8a1b7d9SAlexander Kabaev bool
608f8a1b7d9SAlexander Kabaev empty() const
609f8a1b7d9SAlexander Kabaev { return begin() == end(); }
610f8a1b7d9SAlexander Kabaev
611f8a1b7d9SAlexander Kabaev reference
612f8a1b7d9SAlexander Kabaev operator[](size_type __n)
613f8a1b7d9SAlexander Kabaev {
614f8a1b7d9SAlexander Kabaev return *iterator(this->_M_impl._M_start._M_p
615f8a1b7d9SAlexander Kabaev + __n / int(_S_word_bit), __n % int(_S_word_bit));
616f8a1b7d9SAlexander Kabaev }
617f8a1b7d9SAlexander Kabaev
618f8a1b7d9SAlexander Kabaev const_reference
619f8a1b7d9SAlexander Kabaev operator[](size_type __n) const
620f8a1b7d9SAlexander Kabaev {
621f8a1b7d9SAlexander Kabaev return *const_iterator(this->_M_impl._M_start._M_p
622f8a1b7d9SAlexander Kabaev + __n / int(_S_word_bit), __n % int(_S_word_bit));
623f8a1b7d9SAlexander Kabaev }
624f8a1b7d9SAlexander Kabaev
625f8a1b7d9SAlexander Kabaev protected:
626f8a1b7d9SAlexander Kabaev void
627f8a1b7d9SAlexander Kabaev _M_range_check(size_type __n) const
628f8a1b7d9SAlexander Kabaev {
629f8a1b7d9SAlexander Kabaev if (__n >= this->size())
630f8a1b7d9SAlexander Kabaev __throw_out_of_range(__N("vector<bool>::_M_range_check"));
631f8a1b7d9SAlexander Kabaev }
632f8a1b7d9SAlexander Kabaev
633f8a1b7d9SAlexander Kabaev public:
634f8a1b7d9SAlexander Kabaev reference
635f8a1b7d9SAlexander Kabaev at(size_type __n)
636f8a1b7d9SAlexander Kabaev { _M_range_check(__n); return (*this)[__n]; }
637f8a1b7d9SAlexander Kabaev
638f8a1b7d9SAlexander Kabaev const_reference
639f8a1b7d9SAlexander Kabaev at(size_type __n) const
640f8a1b7d9SAlexander Kabaev { _M_range_check(__n); return (*this)[__n]; }
641f8a1b7d9SAlexander Kabaev
642f8a1b7d9SAlexander Kabaev void
643f8a1b7d9SAlexander Kabaev reserve(size_type __n)
644f8a1b7d9SAlexander Kabaev {
645f8a1b7d9SAlexander Kabaev if (__n > this->max_size())
646f8a1b7d9SAlexander Kabaev __throw_length_error(__N("vector::reserve"));
647f8a1b7d9SAlexander Kabaev if (this->capacity() < __n)
648f8a1b7d9SAlexander Kabaev {
649f8a1b7d9SAlexander Kabaev _Bit_type* __q = this->_M_allocate(__n);
650f8a1b7d9SAlexander Kabaev this->_M_impl._M_finish = _M_copy_aligned(begin(), end(),
651f8a1b7d9SAlexander Kabaev iterator(__q, 0));
652f8a1b7d9SAlexander Kabaev this->_M_deallocate();
653f8a1b7d9SAlexander Kabaev this->_M_impl._M_start = iterator(__q, 0);
654f8a1b7d9SAlexander Kabaev this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1)
655f8a1b7d9SAlexander Kabaev / int(_S_word_bit));
656f8a1b7d9SAlexander Kabaev }
657f8a1b7d9SAlexander Kabaev }
658f8a1b7d9SAlexander Kabaev
659f8a1b7d9SAlexander Kabaev reference
660f8a1b7d9SAlexander Kabaev front()
661f8a1b7d9SAlexander Kabaev { return *begin(); }
662f8a1b7d9SAlexander Kabaev
663f8a1b7d9SAlexander Kabaev const_reference
664f8a1b7d9SAlexander Kabaev front() const
665f8a1b7d9SAlexander Kabaev { return *begin(); }
666f8a1b7d9SAlexander Kabaev
667f8a1b7d9SAlexander Kabaev reference
668f8a1b7d9SAlexander Kabaev back()
669f8a1b7d9SAlexander Kabaev { return *(end() - 1); }
670f8a1b7d9SAlexander Kabaev
671f8a1b7d9SAlexander Kabaev const_reference
672f8a1b7d9SAlexander Kabaev back() const
673f8a1b7d9SAlexander Kabaev { return *(end() - 1); }
674f8a1b7d9SAlexander Kabaev
675f8a1b7d9SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS
676f8a1b7d9SAlexander Kabaev // DR 464. Suggestion for new member functions in standard containers.
677f8a1b7d9SAlexander Kabaev // N.B. DR 464 says nothing about vector<bool> but we need something
678f8a1b7d9SAlexander Kabaev // here due to the way we are implementing DR 464 in the debug-mode
679f8a1b7d9SAlexander Kabaev // vector class.
680f8a1b7d9SAlexander Kabaev void
681f8a1b7d9SAlexander Kabaev data() { }
682f8a1b7d9SAlexander Kabaev
683f8a1b7d9SAlexander Kabaev void
684f8a1b7d9SAlexander Kabaev push_back(bool __x)
685f8a1b7d9SAlexander Kabaev {
686f8a1b7d9SAlexander Kabaev if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
687f8a1b7d9SAlexander Kabaev *this->_M_impl._M_finish++ = __x;
688f8a1b7d9SAlexander Kabaev else
689f8a1b7d9SAlexander Kabaev _M_insert_aux(end(), __x);
690f8a1b7d9SAlexander Kabaev }
691f8a1b7d9SAlexander Kabaev
692f8a1b7d9SAlexander Kabaev void
693*dc3fe0ffSPedro F. Giffuni swap(vector& __x)
694f8a1b7d9SAlexander Kabaev {
695f8a1b7d9SAlexander Kabaev std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
696f8a1b7d9SAlexander Kabaev std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
697f8a1b7d9SAlexander Kabaev std::swap(this->_M_impl._M_end_of_storage,
698f8a1b7d9SAlexander Kabaev __x._M_impl._M_end_of_storage);
699f8a1b7d9SAlexander Kabaev
700f8a1b7d9SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS
701f8a1b7d9SAlexander Kabaev // 431. Swapping containers with unequal allocators.
702f8a1b7d9SAlexander Kabaev std::__alloc_swap<typename _Base::_Bit_alloc_type>::
703f8a1b7d9SAlexander Kabaev _S_do_it(_M_get_Bit_allocator(), __x._M_get_Bit_allocator());
704f8a1b7d9SAlexander Kabaev }
705f8a1b7d9SAlexander Kabaev
706f8a1b7d9SAlexander Kabaev // [23.2.5]/1, third-to-last entry in synopsis listing
707f8a1b7d9SAlexander Kabaev static void
708f8a1b7d9SAlexander Kabaev swap(reference __x, reference __y)
709f8a1b7d9SAlexander Kabaev {
710f8a1b7d9SAlexander Kabaev bool __tmp = __x;
711f8a1b7d9SAlexander Kabaev __x = __y;
712f8a1b7d9SAlexander Kabaev __y = __tmp;
713f8a1b7d9SAlexander Kabaev }
714f8a1b7d9SAlexander Kabaev
715f8a1b7d9SAlexander Kabaev iterator
716f8a1b7d9SAlexander Kabaev insert(iterator __position, const bool& __x = bool())
717f8a1b7d9SAlexander Kabaev {
718f8a1b7d9SAlexander Kabaev const difference_type __n = __position - begin();
719f8a1b7d9SAlexander Kabaev if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage
720f8a1b7d9SAlexander Kabaev && __position == end())
721f8a1b7d9SAlexander Kabaev *this->_M_impl._M_finish++ = __x;
722f8a1b7d9SAlexander Kabaev else
723f8a1b7d9SAlexander Kabaev _M_insert_aux(__position, __x);
724f8a1b7d9SAlexander Kabaev return begin() + __n;
725f8a1b7d9SAlexander Kabaev }
726f8a1b7d9SAlexander Kabaev
727f8a1b7d9SAlexander Kabaev template<class _InputIterator>
728f8a1b7d9SAlexander Kabaev void
729f8a1b7d9SAlexander Kabaev insert(iterator __position,
730f8a1b7d9SAlexander Kabaev _InputIterator __first, _InputIterator __last)
731f8a1b7d9SAlexander Kabaev {
732f8a1b7d9SAlexander Kabaev typedef typename std::__is_integer<_InputIterator>::__type _Integral;
733f8a1b7d9SAlexander Kabaev _M_insert_dispatch(__position, __first, __last, _Integral());
734f8a1b7d9SAlexander Kabaev }
735f8a1b7d9SAlexander Kabaev
736f8a1b7d9SAlexander Kabaev void
737f8a1b7d9SAlexander Kabaev insert(iterator __position, size_type __n, const bool& __x)
738f8a1b7d9SAlexander Kabaev { _M_fill_insert(__position, __n, __x); }
739f8a1b7d9SAlexander Kabaev
740f8a1b7d9SAlexander Kabaev void
741f8a1b7d9SAlexander Kabaev pop_back()
742f8a1b7d9SAlexander Kabaev { --this->_M_impl._M_finish; }
743f8a1b7d9SAlexander Kabaev
744f8a1b7d9SAlexander Kabaev iterator
745f8a1b7d9SAlexander Kabaev erase(iterator __position)
746f8a1b7d9SAlexander Kabaev {
747f8a1b7d9SAlexander Kabaev if (__position + 1 != end())
748f8a1b7d9SAlexander Kabaev std::copy(__position + 1, end(), __position);
749f8a1b7d9SAlexander Kabaev --this->_M_impl._M_finish;
750f8a1b7d9SAlexander Kabaev return __position;
751f8a1b7d9SAlexander Kabaev }
752f8a1b7d9SAlexander Kabaev
753f8a1b7d9SAlexander Kabaev iterator
754f8a1b7d9SAlexander Kabaev erase(iterator __first, iterator __last)
755f8a1b7d9SAlexander Kabaev {
756f8a1b7d9SAlexander Kabaev _M_erase_at_end(std::copy(__last, end(), __first));
757f8a1b7d9SAlexander Kabaev return __first;
758f8a1b7d9SAlexander Kabaev }
759f8a1b7d9SAlexander Kabaev
760f8a1b7d9SAlexander Kabaev void
761f8a1b7d9SAlexander Kabaev resize(size_type __new_size, bool __x = bool())
762f8a1b7d9SAlexander Kabaev {
763f8a1b7d9SAlexander Kabaev if (__new_size < size())
764f8a1b7d9SAlexander Kabaev _M_erase_at_end(begin() + difference_type(__new_size));
765f8a1b7d9SAlexander Kabaev else
766f8a1b7d9SAlexander Kabaev insert(end(), __new_size - size(), __x);
767f8a1b7d9SAlexander Kabaev }
768f8a1b7d9SAlexander Kabaev
769f8a1b7d9SAlexander Kabaev void
770f8a1b7d9SAlexander Kabaev flip()
771f8a1b7d9SAlexander Kabaev {
772f8a1b7d9SAlexander Kabaev for (_Bit_type * __p = this->_M_impl._M_start._M_p;
773f8a1b7d9SAlexander Kabaev __p != this->_M_impl._M_end_of_storage; ++__p)
774f8a1b7d9SAlexander Kabaev *__p = ~*__p;
775f8a1b7d9SAlexander Kabaev }
776f8a1b7d9SAlexander Kabaev
777f8a1b7d9SAlexander Kabaev void
778f8a1b7d9SAlexander Kabaev clear()
779f8a1b7d9SAlexander Kabaev { _M_erase_at_end(begin()); }
780f8a1b7d9SAlexander Kabaev
781f8a1b7d9SAlexander Kabaev
782f8a1b7d9SAlexander Kabaev protected:
783f8a1b7d9SAlexander Kabaev // Precondition: __first._M_offset == 0 && __result._M_offset == 0.
784f8a1b7d9SAlexander Kabaev iterator
785f8a1b7d9SAlexander Kabaev _M_copy_aligned(const_iterator __first, const_iterator __last,
786f8a1b7d9SAlexander Kabaev iterator __result)
787f8a1b7d9SAlexander Kabaev {
788f8a1b7d9SAlexander Kabaev _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p);
789f8a1b7d9SAlexander Kabaev return std::copy(const_iterator(__last._M_p, 0), __last,
790f8a1b7d9SAlexander Kabaev iterator(__q, 0));
791f8a1b7d9SAlexander Kabaev }
792f8a1b7d9SAlexander Kabaev
793f8a1b7d9SAlexander Kabaev void
794f8a1b7d9SAlexander Kabaev _M_initialize(size_type __n)
795f8a1b7d9SAlexander Kabaev {
796f8a1b7d9SAlexander Kabaev _Bit_type* __q = this->_M_allocate(__n);
797f8a1b7d9SAlexander Kabaev this->_M_impl._M_end_of_storage = (__q
798f8a1b7d9SAlexander Kabaev + ((__n + int(_S_word_bit) - 1)
799f8a1b7d9SAlexander Kabaev / int(_S_word_bit)));
800f8a1b7d9SAlexander Kabaev this->_M_impl._M_start = iterator(__q, 0);
801f8a1b7d9SAlexander Kabaev this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
80200db7afdSDavid E. O'Brien }
80300db7afdSDavid E. O'Brien
80400db7afdSDavid E. O'Brien // Check whether it's an integral type. If so, it's not an iterator.
80500db7afdSDavid E. O'Brien template<class _Integer>
806f8a1b7d9SAlexander Kabaev void
807f8a1b7d9SAlexander Kabaev _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
808ffeaf689SAlexander Kabaev {
80900db7afdSDavid E. O'Brien _M_initialize(__n);
810ffeaf689SAlexander Kabaev std::fill(this->_M_impl._M_start._M_p,
811ffeaf689SAlexander Kabaev this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
81200db7afdSDavid E. O'Brien }
81300db7afdSDavid E. O'Brien
81400db7afdSDavid E. O'Brien template<class _InputIterator>
815ffeaf689SAlexander Kabaev void
816ffeaf689SAlexander Kabaev _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
817ffeaf689SAlexander Kabaev __false_type)
818ffeaf689SAlexander Kabaev { _M_initialize_range(__first, __last,
819ffeaf689SAlexander Kabaev std::__iterator_category(__first)); }
82000db7afdSDavid E. O'Brien
82100db7afdSDavid E. O'Brien template<class _InputIterator>
822f8a1b7d9SAlexander Kabaev void
823f8a1b7d9SAlexander Kabaev _M_initialize_range(_InputIterator __first, _InputIterator __last,
824f8a1b7d9SAlexander Kabaev std::input_iterator_tag)
82500db7afdSDavid E. O'Brien {
826f8a1b7d9SAlexander Kabaev for (; __first != __last; ++__first)
827f8a1b7d9SAlexander Kabaev push_back(*__first);
82800db7afdSDavid E. O'Brien }
82900db7afdSDavid E. O'Brien
830f8a1b7d9SAlexander Kabaev template<class _ForwardIterator>
831f8a1b7d9SAlexander Kabaev void
832f8a1b7d9SAlexander Kabaev _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last,
833f8a1b7d9SAlexander Kabaev std::forward_iterator_tag)
834ffeaf689SAlexander Kabaev {
835f8a1b7d9SAlexander Kabaev const size_type __n = std::distance(__first, __last);
836f8a1b7d9SAlexander Kabaev _M_initialize(__n);
837f8a1b7d9SAlexander Kabaev std::copy(__first, __last, this->_M_impl._M_start);
83800db7afdSDavid E. O'Brien }
83900db7afdSDavid E. O'Brien
840f8a1b7d9SAlexander Kabaev template<class _Integer>
841f8a1b7d9SAlexander Kabaev void
842f8a1b7d9SAlexander Kabaev _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
843f8a1b7d9SAlexander Kabaev { _M_fill_assign((size_t) __n, (bool) __val); }
84400db7afdSDavid E. O'Brien
845f8a1b7d9SAlexander Kabaev template<class _InputIterator>
846f8a1b7d9SAlexander Kabaev void
847f8a1b7d9SAlexander Kabaev _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
848f8a1b7d9SAlexander Kabaev __false_type)
849f8a1b7d9SAlexander Kabaev { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
850f8a1b7d9SAlexander Kabaev
851f8a1b7d9SAlexander Kabaev void
852f8a1b7d9SAlexander Kabaev _M_fill_assign(size_t __n, bool __x)
853ffeaf689SAlexander Kabaev {
854ffeaf689SAlexander Kabaev if (__n > size())
855ffeaf689SAlexander Kabaev {
856ffeaf689SAlexander Kabaev std::fill(this->_M_impl._M_start._M_p,
857ffeaf689SAlexander Kabaev this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
85800db7afdSDavid E. O'Brien insert(end(), __n - size(), __x);
85900db7afdSDavid E. O'Brien }
860ffeaf689SAlexander Kabaev else
861ffeaf689SAlexander Kabaev {
862f8a1b7d9SAlexander Kabaev _M_erase_at_end(begin() + __n);
863ffeaf689SAlexander Kabaev std::fill(this->_M_impl._M_start._M_p,
864ffeaf689SAlexander Kabaev this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
86500db7afdSDavid E. O'Brien }
86600db7afdSDavid E. O'Brien }
86700db7afdSDavid E. O'Brien
86800db7afdSDavid E. O'Brien template<class _InputIterator>
869f8a1b7d9SAlexander Kabaev void
870f8a1b7d9SAlexander Kabaev _M_assign_aux(_InputIterator __first, _InputIterator __last,
871f8a1b7d9SAlexander Kabaev std::input_iterator_tag)
872ffeaf689SAlexander Kabaev {
87300db7afdSDavid E. O'Brien iterator __cur = begin();
87400db7afdSDavid E. O'Brien for (; __first != __last && __cur != end(); ++__cur, ++__first)
87500db7afdSDavid E. O'Brien *__cur = *__first;
87600db7afdSDavid E. O'Brien if (__first == __last)
877f8a1b7d9SAlexander Kabaev _M_erase_at_end(__cur);
87800db7afdSDavid E. O'Brien else
87900db7afdSDavid E. O'Brien insert(end(), __first, __last);
88000db7afdSDavid E. O'Brien }
88100db7afdSDavid E. O'Brien
88200db7afdSDavid E. O'Brien template<class _ForwardIterator>
883f8a1b7d9SAlexander Kabaev void
884f8a1b7d9SAlexander Kabaev _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
885f8a1b7d9SAlexander Kabaev std::forward_iterator_tag)
886ffeaf689SAlexander Kabaev {
887ffeaf689SAlexander Kabaev const size_type __len = std::distance(__first, __last);
88800db7afdSDavid E. O'Brien if (__len < size())
889f8a1b7d9SAlexander Kabaev _M_erase_at_end(std::copy(__first, __last, begin()));
890ffeaf689SAlexander Kabaev else
891ffeaf689SAlexander Kabaev {
89200db7afdSDavid E. O'Brien _ForwardIterator __mid = __first;
893ffeaf689SAlexander Kabaev std::advance(__mid, size());
894ffeaf689SAlexander Kabaev std::copy(__first, __mid, begin());
89500db7afdSDavid E. O'Brien insert(end(), __mid, __last);
89600db7afdSDavid E. O'Brien }
89700db7afdSDavid E. O'Brien }
89800db7afdSDavid E. O'Brien
89900db7afdSDavid E. O'Brien // Check whether it's an integral type. If so, it's not an iterator.
90000db7afdSDavid E. O'Brien template<class _Integer>
901f8a1b7d9SAlexander Kabaev void
902f8a1b7d9SAlexander Kabaev _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
903ffeaf689SAlexander Kabaev __true_type)
904ffeaf689SAlexander Kabaev { _M_fill_insert(__pos, __n, __x); }
90500db7afdSDavid E. O'Brien
90600db7afdSDavid E. O'Brien template<class _InputIterator>
907f8a1b7d9SAlexander Kabaev void
908f8a1b7d9SAlexander Kabaev _M_insert_dispatch(iterator __pos,
90900db7afdSDavid E. O'Brien _InputIterator __first, _InputIterator __last,
910ffeaf689SAlexander Kabaev __false_type)
911ffeaf689SAlexander Kabaev { _M_insert_range(__pos, __first, __last,
912ffeaf689SAlexander Kabaev std::__iterator_category(__first)); }
91300db7afdSDavid E. O'Brien
914f8a1b7d9SAlexander Kabaev void
915f8a1b7d9SAlexander Kabaev _M_fill_insert(iterator __position, size_type __n, bool __x)
916ffeaf689SAlexander Kabaev {
917ffeaf689SAlexander Kabaev if (__n == 0)
918ffeaf689SAlexander Kabaev return;
919ffeaf689SAlexander Kabaev if (capacity() - size() >= __n)
920ffeaf689SAlexander Kabaev {
921ffeaf689SAlexander Kabaev std::copy_backward(__position, end(),
922ffeaf689SAlexander Kabaev this->_M_impl._M_finish + difference_type(__n));
923ffeaf689SAlexander Kabaev std::fill(__position, __position + difference_type(__n), __x);
924ffeaf689SAlexander Kabaev this->_M_impl._M_finish += difference_type(__n);
92500db7afdSDavid E. O'Brien }
926ffeaf689SAlexander Kabaev else
927ffeaf689SAlexander Kabaev {
928ffeaf689SAlexander Kabaev const size_type __len = size() + std::max(size(), __n);
929ffeaf689SAlexander Kabaev _Bit_type * __q = this->_M_allocate(__len);
930f8a1b7d9SAlexander Kabaev iterator __i = _M_copy_aligned(begin(), __position,
931f8a1b7d9SAlexander Kabaev iterator(__q, 0));
932f8a1b7d9SAlexander Kabaev std::fill(__i, __i + difference_type(__n), __x);
933ffeaf689SAlexander Kabaev this->_M_impl._M_finish = std::copy(__position, end(),
934ffeaf689SAlexander Kabaev __i + difference_type(__n));
935ffeaf689SAlexander Kabaev this->_M_deallocate();
936f8a1b7d9SAlexander Kabaev this->_M_impl._M_end_of_storage = (__q + ((__len
937f8a1b7d9SAlexander Kabaev + int(_S_word_bit) - 1)
938f8a1b7d9SAlexander Kabaev / int(_S_word_bit)));
939ffeaf689SAlexander Kabaev this->_M_impl._M_start = iterator(__q, 0);
94000db7afdSDavid E. O'Brien }
94100db7afdSDavid E. O'Brien }
94200db7afdSDavid E. O'Brien
943f8a1b7d9SAlexander Kabaev template<class _InputIterator>
944f8a1b7d9SAlexander Kabaev void
945f8a1b7d9SAlexander Kabaev _M_insert_range(iterator __pos, _InputIterator __first,
946f8a1b7d9SAlexander Kabaev _InputIterator __last, std::input_iterator_tag)
947ffeaf689SAlexander Kabaev {
948f8a1b7d9SAlexander Kabaev for (; __first != __last; ++__first)
949f8a1b7d9SAlexander Kabaev {
950f8a1b7d9SAlexander Kabaev __pos = insert(__pos, *__first);
951f8a1b7d9SAlexander Kabaev ++__pos;
952f8a1b7d9SAlexander Kabaev }
95300db7afdSDavid E. O'Brien }
954ffeaf689SAlexander Kabaev
955f8a1b7d9SAlexander Kabaev template<class _ForwardIterator>
956f8a1b7d9SAlexander Kabaev void
957f8a1b7d9SAlexander Kabaev _M_insert_range(iterator __position, _ForwardIterator __first,
958f8a1b7d9SAlexander Kabaev _ForwardIterator __last, std::forward_iterator_tag)
959ffeaf689SAlexander Kabaev {
960f8a1b7d9SAlexander Kabaev if (__first != __last)
961f8a1b7d9SAlexander Kabaev {
962f8a1b7d9SAlexander Kabaev size_type __n = std::distance(__first, __last);
963f8a1b7d9SAlexander Kabaev if (capacity() - size() >= __n)
964f8a1b7d9SAlexander Kabaev {
965f8a1b7d9SAlexander Kabaev std::copy_backward(__position, end(),
966f8a1b7d9SAlexander Kabaev this->_M_impl._M_finish
967f8a1b7d9SAlexander Kabaev + difference_type(__n));
968f8a1b7d9SAlexander Kabaev std::copy(__first, __last, __position);
969f8a1b7d9SAlexander Kabaev this->_M_impl._M_finish += difference_type(__n);
97000db7afdSDavid E. O'Brien }
97100db7afdSDavid E. O'Brien else
972ffeaf689SAlexander Kabaev {
973f8a1b7d9SAlexander Kabaev const size_type __len = size() + std::max(size(), __n);
974f8a1b7d9SAlexander Kabaev _Bit_type * __q = this->_M_allocate(__len);
975f8a1b7d9SAlexander Kabaev iterator __i = _M_copy_aligned(begin(), __position,
976f8a1b7d9SAlexander Kabaev iterator(__q, 0));
977f8a1b7d9SAlexander Kabaev __i = std::copy(__first, __last, __i);
978f8a1b7d9SAlexander Kabaev this->_M_impl._M_finish = std::copy(__position, end(), __i);
979f8a1b7d9SAlexander Kabaev this->_M_deallocate();
980f8a1b7d9SAlexander Kabaev this->_M_impl._M_end_of_storage = (__q
981f8a1b7d9SAlexander Kabaev + ((__len
982f8a1b7d9SAlexander Kabaev + int(_S_word_bit) - 1)
983f8a1b7d9SAlexander Kabaev / int(_S_word_bit)));
984f8a1b7d9SAlexander Kabaev this->_M_impl._M_start = iterator(__q, 0);
985f8a1b7d9SAlexander Kabaev }
986f8a1b7d9SAlexander Kabaev }
98700db7afdSDavid E. O'Brien }
98800db7afdSDavid E. O'Brien
989f8a1b7d9SAlexander Kabaev void
990f8a1b7d9SAlexander Kabaev _M_insert_aux(iterator __position, bool __x)
991f8a1b7d9SAlexander Kabaev {
992f8a1b7d9SAlexander Kabaev if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
993f8a1b7d9SAlexander Kabaev {
994f8a1b7d9SAlexander Kabaev std::copy_backward(__position, this->_M_impl._M_finish,
995f8a1b7d9SAlexander Kabaev this->_M_impl._M_finish + 1);
996f8a1b7d9SAlexander Kabaev *__position = __x;
997f8a1b7d9SAlexander Kabaev ++this->_M_impl._M_finish;
998f8a1b7d9SAlexander Kabaev }
999f8a1b7d9SAlexander Kabaev else
1000f8a1b7d9SAlexander Kabaev {
1001f8a1b7d9SAlexander Kabaev const size_type __len = size() ? 2 * size()
1002f8a1b7d9SAlexander Kabaev : static_cast<size_type>(_S_word_bit);
1003f8a1b7d9SAlexander Kabaev _Bit_type * __q = this->_M_allocate(__len);
1004f8a1b7d9SAlexander Kabaev iterator __i = _M_copy_aligned(begin(), __position,
1005f8a1b7d9SAlexander Kabaev iterator(__q, 0));
1006f8a1b7d9SAlexander Kabaev *__i++ = __x;
1007f8a1b7d9SAlexander Kabaev this->_M_impl._M_finish = std::copy(__position, end(), __i);
1008f8a1b7d9SAlexander Kabaev this->_M_deallocate();
1009f8a1b7d9SAlexander Kabaev this->_M_impl._M_end_of_storage = (__q + ((__len
1010f8a1b7d9SAlexander Kabaev + int(_S_word_bit) - 1)
1011f8a1b7d9SAlexander Kabaev / int(_S_word_bit)));
1012f8a1b7d9SAlexander Kabaev this->_M_impl._M_start = iterator(__q, 0);
1013f8a1b7d9SAlexander Kabaev }
1014f8a1b7d9SAlexander Kabaev }
1015f8a1b7d9SAlexander Kabaev
1016f8a1b7d9SAlexander Kabaev void
1017f8a1b7d9SAlexander Kabaev _M_erase_at_end(iterator __pos)
1018f8a1b7d9SAlexander Kabaev { this->_M_impl._M_finish = __pos; }
101900db7afdSDavid E. O'Brien };
1020f8a1b7d9SAlexander Kabaev
1021f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NESTED_NAMESPACE
102200db7afdSDavid E. O'Brien
1023ffeaf689SAlexander Kabaev #endif
1024