4 * Hewlett-Packard Company
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Hewlett-Packard Company makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
16 * Silicon Graphics Computer Systems, Inc.
18 * Permission to use, copy, modify, distribute and sell this software
19 * and its documentation for any purpose is hereby granted without fee,
20 * provided that the above copyright notice appear in all copies and
21 * that both that copyright notice and this permission notice appear
22 * in supporting documentation. Silicon Graphics makes no
23 * representations about the suitability of this software for any
24 * purpose. It is provided "as is" without express or implied warranty.
27 // vector<bool> is replaced by bit_vector at present because partial
28 // specialization is not yet implemented.
30 #ifndef __SGI_STL_BVECTOR_H
31 #define __SGI_STL_BVECTOR_H
38 #define __WORD_BIT (int(CHAR_BIT*sizeof(unsigned int)))
42 typedef bool value_type
;
43 typedef size_t size_type
;
44 typedef ptrdiff_t difference_type
;
50 friend class iterator
;
51 friend class const_iterator
;
55 reference(unsigned int* x
, unsigned int y
) : p(x
), mask(y
) {}
57 reference() : p(0), mask(0) {}
58 operator bool() const { return !(!(*p
& mask
)); }
59 reference
& operator=(bool x
) {
66 reference
& operator=(const reference
& x
) { return *this = bool(x
); }
67 bool operator==(const reference
& x
) const {
68 return bool(*this) == bool(x
);
70 bool operator<(const reference
& x
) const {
71 return bool(*this) < bool(x
);
73 void flip() { *p
^= mask
; }
76 typedef bool const_reference
;
78 typedef reference bit_reference
;
79 typedef const_reference bit_const_reference
;
81 class iterator
: public random_access_iterator
<bool, difference_type
> {
82 friend class bit_vector
;
83 friend class const_iterator
;
85 typedef bit_reference reference
;
90 if (offset
++ == __WORD_BIT
- 1) {
97 offset
= __WORD_BIT
- 1;
102 iterator() : p(0), offset(0) {}
103 iterator(unsigned int* x
, unsigned int y
) : p(x
), offset(y
) {}
104 reference
operator*() const { return reference(p
, 1U << offset
); }
105 iterator
& operator++() {
109 iterator
operator++(int) {
110 iterator tmp
= *this;
114 iterator
& operator--() {
118 iterator
operator--(int) {
119 iterator tmp
= *this;
123 iterator
& operator+=(difference_type i
) {
124 difference_type n
= i
+ offset
;
128 offset
= n
+ __WORD_BIT
;
134 iterator
& operator-=(difference_type i
) {
138 iterator
operator+(difference_type i
) const {
139 iterator tmp
= *this;
142 iterator
operator-(difference_type i
) const {
143 iterator tmp
= *this;
146 difference_type
operator-(iterator x
) const {
147 return __WORD_BIT
* (p
- x
.p
) + offset
- x
.offset
;
149 reference
operator[](difference_type i
) { return *(*this + i
); }
150 bool operator==(const iterator
& x
) const {
151 return p
== x
.p
&& offset
== x
.offset
;
153 bool operator!=(const iterator
& x
) const {
154 return p
!= x
.p
|| offset
!= x
.offset
;
156 bool operator<(iterator x
) const {
157 return p
< x
.p
|| (p
== x
.p
&& offset
< x
.offset
);
161 class const_iterator
: public random_access_iterator
<bool, difference_type
>
163 friend class bit_vector
;
165 typedef bit_const_reference reference
;
170 if (offset
++ == __WORD_BIT
- 1) {
177 offset
= __WORD_BIT
- 1;
182 const_iterator() : p(0), offset(0) {}
183 const_iterator(unsigned int* x
, unsigned int y
) : p(x
), offset(y
) {}
184 const_iterator(const iterator
& x
) : p(x
.p
), offset(x
.offset
) {}
185 const_reference
operator*() const {
186 return bit_vector::reference(p
, 1U << offset
);
188 const_iterator
& operator++() {
192 const_iterator
operator++(int) {
193 const_iterator tmp
= *this;
197 const_iterator
& operator--() {
201 const_iterator
operator--(int) {
202 const_iterator tmp
= *this;
206 const_iterator
& operator+=(difference_type i
) {
207 difference_type n
= i
+ offset
;
211 offset
= n
+ __WORD_BIT
;
217 const_iterator
& operator-=(difference_type i
) {
221 const_iterator
operator+(difference_type i
) const {
222 const_iterator tmp
= *this;
225 const_iterator
operator-(difference_type i
) const {
226 const_iterator tmp
= *this;
229 difference_type
operator-(const_iterator x
) const {
230 return __WORD_BIT
* (p
- x
.p
) + offset
- x
.offset
;
232 const_reference
operator[](difference_type i
) {
235 bool operator==(const const_iterator
& x
) const {
236 return p
== x
.p
&& offset
== x
.offset
;
238 bool operator!=(const const_iterator
& x
) const {
239 return p
!= x
.p
|| offset
!= x
.offset
;
241 bool operator<(const_iterator x
) const {
242 return p
< x
.p
|| (p
== x
.p
&& offset
< x
.offset
);
246 typedef reverse_iterator
<const_iterator
, value_type
, const_reference
,
247 difference_type
> const_reverse_iterator
;
248 typedef reverse_iterator
<iterator
, value_type
, reference
, difference_type
>
252 typedef simple_alloc
<unsigned int, alloc
> data_allocator
;
255 unsigned int* end_of_storage
;
256 unsigned int* bit_alloc(size_type n
) {
257 return data_allocator::allocate((n
+ __WORD_BIT
- 1)/__WORD_BIT
);
261 data_allocator::deallocate(start
.p
, end_of_storage
- start
.p
);
263 void initialize(size_type n
) {
264 unsigned int* q
= bit_alloc(n
);
265 end_of_storage
= q
+ (n
+ __WORD_BIT
- 1)/__WORD_BIT
;
266 start
= iterator(q
, 0);
269 void insert_aux(iterator position
, bool x
) {
270 if (finish
.p
!= end_of_storage
) {
271 copy_backward(position
, finish
, finish
+ 1);
275 size_type len
= size() ? 2 * size() : __WORD_BIT
;
276 unsigned int* q
= bit_alloc(len
);
277 iterator i
= copy(begin(), position
, iterator(q
, 0));
279 finish
= copy(position
, end(), i
);
281 end_of_storage
= q
+ (len
+ __WORD_BIT
- 1)/__WORD_BIT
;
282 start
= iterator(q
, 0);
286 #ifdef __STL_MEMBER_TEMPLATES
287 template <class InputIterator
>
288 void initialize_range(InputIterator first
, InputIterator last
,
289 input_iterator_tag
) {
293 for ( ; first
!= last
; ++first
)
297 template <class ForwardIterator
>
298 void initialize_range(ForwardIterator first
, ForwardIterator last
,
299 forward_iterator_tag
) {
301 distance(first
, last
, n
);
303 copy(first
, last
, start
);
306 template <class BidirectionalIterator
>
307 void initialize_range(BidirectionalIterator first
,
308 BidirectionalIterator last
,
309 bidirectional_iterator_tag
) {
310 initialize_range(first
, last
, forward_iterator_tag());
313 template <class RandomAccessIterator
>
314 void initialize_range(RandomAccessIterator first
,
315 RandomAccessIterator last
,
316 random_access_iterator_tag
) {
317 initialize_range(first
, last
, forward_iterator_tag());
320 template <class InputIterator
>
321 void insert_range(iterator pos
,
322 InputIterator first
, InputIterator last
,
323 input_iterator_tag
) {
324 for ( ; first
!= last
; ++first
) {
325 pos
= insert(pos
, *first
);
330 template <class ForwardIterator
>
331 void insert_range(iterator position
,
332 ForwardIterator first
, ForwardIterator last
,
333 forward_iterator_tag
) {
336 distance(first
, last
, n
);
337 if (capacity() - size() >= n
) {
338 copy_backward(position
, end(), finish
+ n
);
339 copy(first
, last
, position
);
343 size_type len
= size() + max(size(), n
);
344 unsigned int* q
= bit_alloc(len
);
345 iterator i
= copy(begin(), position
, iterator(q
, 0));
346 i
= copy(first
, last
, i
);
347 finish
= copy(position
, end(), i
);
349 end_of_storage
= q
+ (len
+ __WORD_BIT
- 1)/__WORD_BIT
;
350 start
= iterator(q
, 0);
355 template <class BidirectionalIterator
>
356 void insert_range(iterator pos
,
357 BidirectionalIterator first
, BidirectionalIterator last
,
358 bidirectional_iterator_tag
) {
359 insert_range(pos
, first
, last
, forward_iterator_tag());
362 template <class RandomAccessIterator
>
363 void insert_range(iterator pos
,
364 RandomAccessIterator first
, RandomAccessIterator last
,
365 random_access_iterator_tag
) {
366 insert_range(pos
, first
, last
, forward_iterator_tag());
369 #endif /* __STL_MEMBER_TEMPLATES */
371 typedef bit_vector self
;
373 iterator
begin() { return start
; }
374 const_iterator
begin() const { return start
; }
375 iterator
end() { return finish
; }
376 const_iterator
end() const { return finish
; }
378 reverse_iterator
rbegin() { return reverse_iterator(end()); }
379 const_reverse_iterator
rbegin() const {
380 return const_reverse_iterator(end());
382 reverse_iterator
rend() { return reverse_iterator(begin()); }
383 const_reverse_iterator
rend() const {
384 return const_reverse_iterator(begin());
387 size_type
size() const { return size_type(end() - begin()); }
388 size_type
max_size() const { return size_type(-1); }
389 size_type
capacity() const {
390 return size_type(const_iterator(end_of_storage
, 0) - begin());
392 bool empty() const { return begin() == end(); }
393 reference
operator[](size_type n
) { return *(begin() + n
); }
394 const_reference
operator[](size_type n
) const { return *(begin() + n
); }
395 bit_vector() : start(iterator()), finish(iterator()), end_of_storage(0) {}
396 bit_vector(size_type n
, bool value
) {
398 fill(start
.p
, end_of_storage
, value
? ~0 : 0);
400 bit_vector(int n
, bool value
) {
402 fill(start
.p
, end_of_storage
, value
? ~0 : 0);
404 bit_vector(long n
, bool value
) {
406 fill(start
.p
, end_of_storage
, value
? ~0 : 0);
408 explicit bit_vector(size_type n
) {
410 fill(start
.p
, end_of_storage
, 0);
412 bit_vector(const self
& x
) {
413 initialize(x
.size());
414 copy(x
.begin(), x
.end(), start
);
417 #ifdef __STL_MEMBER_TEMPLATES
418 template <class InputIterator
>
419 bit_vector(InputIterator first
, InputIterator last
) {
420 initialize_range(first
, last
, iterator_category(first
));
422 #else /* __STL_MEMBER_TEMPLATES */
423 bit_vector(const_iterator first
, const_iterator last
) {
425 distance(first
, last
, n
);
427 copy(first
, last
, start
);
429 bit_vector(const bool* first
, const bool* last
) {
431 distance(first
, last
, n
);
433 copy(first
, last
, start
);
435 #endif /* __STL_MEMBER_TEMPLATES */
437 ~bit_vector() { deallocate(); }
438 self
& operator=(const self
& x
) {
439 if (&x
== this) return *this;
440 if (x
.size() > capacity()) {
442 initialize(x
.size());
444 copy(x
.begin(), x
.end(), begin());
445 finish
= begin() + x
.size();
448 void reserve(size_type n
) {
449 if (capacity() < n
) {
450 unsigned int* q
= bit_alloc(n
);
451 finish
= copy(begin(), end(), iterator(q
, 0));
453 start
= iterator(q
, 0);
454 end_of_storage
= q
+ (n
+ __WORD_BIT
- 1)/__WORD_BIT
;
457 reference
front() { return *begin(); }
458 const_reference
front() const { return *begin(); }
459 reference
back() { return *(end() - 1); }
460 const_reference
back() const { return *(end() - 1); }
461 void push_back(bool x
) {
462 if (finish
.p
!= end_of_storage
)
465 insert_aux(end(), x
);
467 void swap(bit_vector
& x
) {
468 ::swap(start
, x
.start
);
469 ::swap(finish
, x
.finish
);
470 ::swap(end_of_storage
, x
.end_of_storage
);
472 iterator
insert(iterator position
, bool x
= bool()) {
473 size_type n
= position
- begin();
474 if (finish
.p
!= end_of_storage
&& position
== end())
477 insert_aux(position
, x
);
481 #ifdef __STL_MEMBER_TEMPLATES
482 template <class InputIterator
> void insert(iterator position
,
484 InputIterator last
) {
485 insert_range(position
, first
, last
, iterator_category(first
));
487 #else /* __STL_MEMBER_TEMPLATES */
488 void insert(iterator position
, const_iterator first
,
489 const_iterator last
) {
490 if (first
== last
) return;
492 distance(first
, last
, n
);
493 if (capacity() - size() >= n
) {
494 copy_backward(position
, end(), finish
+ n
);
495 copy(first
, last
, position
);
498 size_type len
= size() + max(size(), n
);
499 unsigned int* q
= bit_alloc(len
);
500 iterator i
= copy(begin(), position
, iterator(q
, 0));
501 i
= copy(first
, last
, i
);
502 finish
= copy(position
, end(), i
);
504 end_of_storage
= q
+ (len
+ __WORD_BIT
- 1)/__WORD_BIT
;
505 start
= iterator(q
, 0);
509 void insert(iterator position
, const bool* first
, const bool* last
) {
510 if (first
== last
) return;
512 distance(first
, last
, n
);
513 if (capacity() - size() >= n
) {
514 copy_backward(position
, end(), finish
+ n
);
515 copy(first
, last
, position
);
518 size_type len
= size() + max(size(), n
);
519 unsigned int* q
= bit_alloc(len
);
520 iterator i
= copy(begin(), position
, iterator(q
, 0));
521 i
= copy(first
, last
, i
);
522 finish
= copy(position
, end(), i
);
524 end_of_storage
= q
+ (len
+ __WORD_BIT
- 1)/__WORD_BIT
;
525 start
= iterator(q
, 0);
528 #endif /* __STL_MEMBER_TEMPLATES */
530 void insert(iterator position
, size_type n
, bool x
) {
532 if (capacity() - size() >= n
) {
533 copy_backward(position
, end(), finish
+ n
);
534 fill(position
, position
+ n
, x
);
537 size_type len
= size() + max(size(), n
);
538 unsigned int* q
= bit_alloc(len
);
539 iterator i
= copy(begin(), position
, iterator(q
, 0));
541 finish
= copy(position
, end(), i
+ n
);
543 end_of_storage
= q
+ (len
+ __WORD_BIT
- 1)/__WORD_BIT
;
544 start
= iterator(q
, 0);
548 void insert(iterator pos
, int n
, bool x
) { insert(pos
, (size_type
)n
, x
); }
549 void insert(iterator pos
, long n
, bool x
) { insert(pos
, (size_type
)n
, x
); }
551 void pop_back() { --finish
; }
552 void erase(iterator position
) {
553 if (position
+ 1 != end())
554 copy(position
+ 1, end(), position
);
557 void erase(iterator first
, iterator last
) {
558 finish
= copy(last
, end(), first
);
560 void resize(size_type new_size
, bool x
= bool()) {
561 if (new_size
< size())
562 erase(begin() + new_size
, end());
564 insert(end(), new_size
- size(), x
);
566 void clear() { erase(begin(), end()); }
569 inline bool operator==(const bit_vector
& x
, const bit_vector
& y
) {
570 return x
.size() == y
.size() && equal(x
.begin(), x
.end(), y
.begin());
573 inline bool operator<(const bit_vector
& x
, const bit_vector
& y
) {
574 return lexicographical_compare(x
.begin(), x
.end(), y
.begin(), y
.end());
577 inline void swap(bit_vector::reference x
, bit_vector::reference y
) {
585 #endif /* __SGI_STL_BVECTOR_H */