libstdc++
stl_bvector.h
Go to the documentation of this file.
1// vector<bool> specialization -*- C++ -*-
2
3// Copyright (C) 2001-2021 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1996-1999
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 */
50
51/** @file bits/stl_bvector.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{vector}
54 */
55
56#ifndef _STL_BVECTOR_H
57#define _STL_BVECTOR_H 1
58
59#if __cplusplus >= 201103L
60#include <initializer_list>
62#endif
63
64namespace std _GLIBCXX_VISIBILITY(default)
65{
66_GLIBCXX_BEGIN_NAMESPACE_VERSION
67_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
68
69 typedef unsigned long _Bit_type;
70 enum { _S_word_bit = int(__CHAR_BIT__ * sizeof(_Bit_type)) };
71
72 struct _Bit_reference
73 {
74 _Bit_type * _M_p;
75 _Bit_type _M_mask;
76
77 _Bit_reference(_Bit_type * __x, _Bit_type __y)
78 : _M_p(__x), _M_mask(__y) { }
79
80 _Bit_reference() _GLIBCXX_NOEXCEPT : _M_p(0), _M_mask(0) { }
81
82#if __cplusplus >= 201103L
83 _Bit_reference(const _Bit_reference&) = default;
84#endif
85
86 operator bool() const _GLIBCXX_NOEXCEPT
87 { return !!(*_M_p & _M_mask); }
88
89 _Bit_reference&
90 operator=(bool __x) _GLIBCXX_NOEXCEPT
91 {
92 if (__x)
93 *_M_p |= _M_mask;
94 else
95 *_M_p &= ~_M_mask;
96 return *this;
97 }
98
99 _Bit_reference&
100 operator=(const _Bit_reference& __x) _GLIBCXX_NOEXCEPT
101 { return *this = bool(__x); }
102
103 bool
104 operator==(const _Bit_reference& __x) const
105 { return bool(*this) == bool(__x); }
106
107 bool
108 operator<(const _Bit_reference& __x) const
109 { return !bool(*this) && bool(__x); }
110
111 void
112 flip() _GLIBCXX_NOEXCEPT
113 { *_M_p ^= _M_mask; }
114 };
115
116#if __cplusplus >= 201103L
117 inline void
118 swap(_Bit_reference __x, _Bit_reference __y) noexcept
119 {
120 bool __tmp = __x;
121 __x = __y;
122 __y = __tmp;
123 }
124
125 inline void
126 swap(_Bit_reference __x, bool& __y) noexcept
127 {
128 bool __tmp = __x;
129 __x = __y;
130 __y = __tmp;
131 }
132
133 inline void
134 swap(bool& __x, _Bit_reference __y) noexcept
135 {
136 bool __tmp = __x;
137 __x = __y;
138 __y = __tmp;
139 }
140#endif
141
142 struct _Bit_iterator_base
143 : public std::iterator<std::random_access_iterator_tag, bool>
144 {
145 _Bit_type * _M_p;
146 unsigned int _M_offset;
147
148 _Bit_iterator_base(_Bit_type * __x, unsigned int __y)
149 : _M_p(__x), _M_offset(__y) { }
150
151 void
152 _M_bump_up()
153 {
154 if (_M_offset++ == int(_S_word_bit) - 1)
155 {
156 _M_offset = 0;
157 ++_M_p;
158 }
159 }
160
161 void
162 _M_bump_down()
163 {
164 if (_M_offset-- == 0)
165 {
166 _M_offset = int(_S_word_bit) - 1;
167 --_M_p;
168 }
169 }
170
171 void
172 _M_incr(ptrdiff_t __i)
173 {
174 difference_type __n = __i + _M_offset;
175 _M_p += __n / int(_S_word_bit);
176 __n = __n % int(_S_word_bit);
177 if (__n < 0)
178 {
179 __n += int(_S_word_bit);
180 --_M_p;
181 }
182 _M_offset = static_cast<unsigned int>(__n);
183 }
184
185 friend _GLIBCXX20_CONSTEXPR bool
186 operator==(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
187 { return __x._M_p == __y._M_p && __x._M_offset == __y._M_offset; }
188
189#if __cpp_lib_three_way_comparison
190 friend constexpr strong_ordering
191 operator<=>(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
192 noexcept
193 {
194 if (const auto __cmp = __x._M_p <=> __y._M_p; __cmp != 0)
195 return __cmp;
196 return __x._M_offset <=> __y._M_offset;
197 }
198#else
199 friend bool
200 operator<(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
201 {
202 return __x._M_p < __y._M_p
203 || (__x._M_p == __y._M_p && __x._M_offset < __y._M_offset);
204 }
205
206 friend bool
207 operator!=(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
208 { return !(__x == __y); }
209
210 friend bool
211 operator>(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
212 { return __y < __x; }
213
214 friend bool
215 operator<=(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
216 { return !(__y < __x); }
217
218 friend bool
219 operator>=(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
220 { return !(__x < __y); }
221#endif // three-way comparison
222
223 friend ptrdiff_t
224 operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
225 {
226 return (int(_S_word_bit) * (__x._M_p - __y._M_p)
227 + __x._M_offset - __y._M_offset);
228 }
229 };
230
231 struct _Bit_iterator : public _Bit_iterator_base
232 {
233 typedef _Bit_reference reference;
234#if __cplusplus > 201703L
235 typedef void pointer;
236#else
237 typedef _Bit_reference* pointer;
238#endif
239 typedef _Bit_iterator iterator;
240
241 _Bit_iterator() : _Bit_iterator_base(0, 0) { }
242
243 _Bit_iterator(_Bit_type * __x, unsigned int __y)
244 : _Bit_iterator_base(__x, __y) { }
245
246 iterator
247 _M_const_cast() const
248 { return *this; }
249
250 reference
251 operator*() const
252 { return reference(_M_p, 1UL << _M_offset); }
253
254 iterator&
255 operator++()
256 {
257 _M_bump_up();
258 return *this;
259 }
260
261 iterator
262 operator++(int)
263 {
264 iterator __tmp = *this;
265 _M_bump_up();
266 return __tmp;
267 }
268
269 iterator&
270 operator--()
271 {
272 _M_bump_down();
273 return *this;
274 }
275
276 iterator
277 operator--(int)
278 {
279 iterator __tmp = *this;
280 _M_bump_down();
281 return __tmp;
282 }
283
284 iterator&
285 operator+=(difference_type __i)
286 {
287 _M_incr(__i);
288 return *this;
289 }
290
291 iterator&
292 operator-=(difference_type __i)
293 {
294 *this += -__i;
295 return *this;
296 }
297
298 reference
299 operator[](difference_type __i) const
300 { return *(*this + __i); }
301
302 friend iterator
303 operator+(const iterator& __x, difference_type __n)
304 {
305 iterator __tmp = __x;
306 __tmp += __n;
307 return __tmp;
308 }
309
310 friend iterator
311 operator+(difference_type __n, const iterator& __x)
312 { return __x + __n; }
313
314 friend iterator
315 operator-(const iterator& __x, difference_type __n)
316 {
317 iterator __tmp = __x;
318 __tmp -= __n;
319 return __tmp;
320 }
321 };
322
323 struct _Bit_const_iterator : public _Bit_iterator_base
324 {
325 typedef bool reference;
326 typedef bool const_reference;
327#if __cplusplus > 201703L
328 typedef void pointer;
329#else
330 typedef const bool* pointer;
331#endif
332 typedef _Bit_const_iterator const_iterator;
333
334 _Bit_const_iterator() : _Bit_iterator_base(0, 0) { }
335
336 _Bit_const_iterator(_Bit_type * __x, unsigned int __y)
337 : _Bit_iterator_base(__x, __y) { }
338
339 _Bit_const_iterator(const _Bit_iterator& __x)
340 : _Bit_iterator_base(__x._M_p, __x._M_offset) { }
341
342 _Bit_iterator
343 _M_const_cast() const
344 { return _Bit_iterator(_M_p, _M_offset); }
345
346 const_reference
347 operator*() const
348 { return _Bit_reference(_M_p, 1UL << _M_offset); }
349
350 const_iterator&
351 operator++()
352 {
353 _M_bump_up();
354 return *this;
355 }
356
357 const_iterator
358 operator++(int)
359 {
360 const_iterator __tmp = *this;
361 _M_bump_up();
362 return __tmp;
363 }
364
365 const_iterator&
366 operator--()
367 {
368 _M_bump_down();
369 return *this;
370 }
371
372 const_iterator
373 operator--(int)
374 {
375 const_iterator __tmp = *this;
376 _M_bump_down();
377 return __tmp;
378 }
379
380 const_iterator&
381 operator+=(difference_type __i)
382 {
383 _M_incr(__i);
384 return *this;
385 }
386
387 const_iterator&
388 operator-=(difference_type __i)
389 {
390 *this += -__i;
391 return *this;
392 }
393
394 const_reference
395 operator[](difference_type __i) const
396 { return *(*this + __i); }
397
398 friend const_iterator
399 operator+(const const_iterator& __x, difference_type __n)
400 {
401 const_iterator __tmp = __x;
402 __tmp += __n;
403 return __tmp;
404 }
405
406 friend const_iterator
407 operator-(const const_iterator& __x, difference_type __n)
408 {
409 const_iterator __tmp = __x;
410 __tmp -= __n;
411 return __tmp;
412 }
413
414 friend const_iterator
415 operator+(difference_type __n, const const_iterator& __x)
416 { return __x + __n; }
417 };
418
419 template<typename _Alloc>
420 struct _Bvector_base
421 {
422 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
423 rebind<_Bit_type>::other _Bit_alloc_type;
424 typedef typename __gnu_cxx::__alloc_traits<_Bit_alloc_type>
425 _Bit_alloc_traits;
426 typedef typename _Bit_alloc_traits::pointer _Bit_pointer;
427
428 struct _Bvector_impl_data
429 {
430#if !_GLIBCXX_INLINE_VERSION
431 _Bit_iterator _M_start;
432#else
433 // We don't need the offset field for the start, it's always zero.
434 struct {
435 _Bit_type* _M_p;
436 // Allow assignment from iterators (assume offset is zero):
437 void operator=(_Bit_iterator __it) { _M_p = __it._M_p; }
438 } _M_start;
439#endif
440 _Bit_iterator _M_finish;
441 _Bit_pointer _M_end_of_storage;
442
443 _Bvector_impl_data() _GLIBCXX_NOEXCEPT
444 : _M_start(), _M_finish(), _M_end_of_storage()
445 { }
446
447#if __cplusplus >= 201103L
448 _Bvector_impl_data(const _Bvector_impl_data&) = default;
449 _Bvector_impl_data&
450 operator=(const _Bvector_impl_data&) = default;
451
452 _Bvector_impl_data(_Bvector_impl_data&& __x) noexcept
453 : _Bvector_impl_data(__x)
454 { __x._M_reset(); }
455
456 void
457 _M_move_data(_Bvector_impl_data&& __x) noexcept
458 {
459 *this = __x;
460 __x._M_reset();
461 }
462#endif
463
464 void
465 _M_reset() _GLIBCXX_NOEXCEPT
466 { *this = _Bvector_impl_data(); }
467
468 void
469 _M_swap_data(_Bvector_impl_data& __x) _GLIBCXX_NOEXCEPT
470 {
471 // Do not use std::swap(_M_start, __x._M_start), etc as it loses
472 // information used by TBAA.
473 std::swap(*this, __x);
474 }
475 };
476
477 struct _Bvector_impl
478 : public _Bit_alloc_type, public _Bvector_impl_data
479 {
480 _Bvector_impl() _GLIBCXX_NOEXCEPT_IF(
481 is_nothrow_default_constructible<_Bit_alloc_type>::value)
482 : _Bit_alloc_type()
483 { }
484
485 _Bvector_impl(const _Bit_alloc_type& __a) _GLIBCXX_NOEXCEPT
486 : _Bit_alloc_type(__a)
487 { }
488
489#if __cplusplus >= 201103L
490 // Not defaulted, to enforce noexcept(true) even when
491 // !is_nothrow_move_constructible<_Bit_alloc_type>.
492 _Bvector_impl(_Bvector_impl&& __x) noexcept
493 : _Bit_alloc_type(std::move(__x)), _Bvector_impl_data(std::move(__x))
494 { }
495
496 _Bvector_impl(_Bit_alloc_type&& __a, _Bvector_impl&& __x) noexcept
497 : _Bit_alloc_type(std::move(__a)), _Bvector_impl_data(std::move(__x))
498 { }
499#endif
500
501 _Bit_type*
502 _M_end_addr() const _GLIBCXX_NOEXCEPT
503 {
504 if (this->_M_end_of_storage)
505 return std::__addressof(this->_M_end_of_storage[-1]) + 1;
506 return 0;
507 }
508 };
509
510 public:
511 typedef _Alloc allocator_type;
512
513 _Bit_alloc_type&
514 _M_get_Bit_allocator() _GLIBCXX_NOEXCEPT
515 { return this->_M_impl; }
516
517 const _Bit_alloc_type&
518 _M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT
519 { return this->_M_impl; }
520
521 allocator_type
522 get_allocator() const _GLIBCXX_NOEXCEPT
523 { return allocator_type(_M_get_Bit_allocator()); }
524
525#if __cplusplus >= 201103L
526 _Bvector_base() = default;
527#else
528 _Bvector_base() { }
529#endif
530
531 _Bvector_base(const allocator_type& __a)
532 : _M_impl(__a) { }
533
534#if __cplusplus >= 201103L
535 _Bvector_base(_Bvector_base&&) = default;
536
537 _Bvector_base(_Bvector_base&& __x, const allocator_type& __a) noexcept
538 : _M_impl(_Bit_alloc_type(__a), std::move(__x._M_impl))
539 { }
540#endif
541
542 ~_Bvector_base()
543 { this->_M_deallocate(); }
544
545 protected:
546 _Bvector_impl _M_impl;
547
548 _Bit_pointer
549 _M_allocate(size_t __n)
550 { return _Bit_alloc_traits::allocate(_M_impl, _S_nword(__n)); }
551
552 void
553 _M_deallocate()
554 {
555 if (_M_impl._M_start._M_p)
556 {
557 const size_t __n = _M_impl._M_end_addr() - _M_impl._M_start._M_p;
559 _M_impl._M_end_of_storage - __n,
560 __n);
561 _M_impl._M_reset();
562 }
563 }
564
565#if __cplusplus >= 201103L
566 void
567 _M_move_data(_Bvector_base&& __x) noexcept
568 { _M_impl._M_move_data(std::move(__x._M_impl)); }
569#endif
570
571 // Caller must ensure the addition won't overflow.
572 static size_t
573 _S_nword(size_t __n)
574 { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); }
575 };
576
577 /**
578 * @brief A specialization of vector for booleans which offers fixed time
579 * access to individual elements in any order.
580 *
581 * @ingroup sequences
582 *
583 * @tparam _Alloc Allocator type.
584 *
585 * Note that vector<bool> does not actually meet the requirements for being
586 * a container. This is because the reference and pointer types are not
587 * really references and pointers to bool. See DR96 for details. @see
588 * vector for function documentation.
589 *
590 * In some terminology a %vector can be described as a dynamic
591 * C-style array, it offers fast and efficient access to individual
592 * elements in any order and saves the user from worrying about
593 * memory and size allocation. Subscripting ( @c [] ) access is
594 * also provided as with C-style arrays.
595 */
596 template<typename _Alloc>
597 class vector<bool, _Alloc> : protected _Bvector_base<_Alloc>
598 {
599 typedef _Bvector_base<_Alloc> _Base;
600 typedef typename _Base::_Bit_pointer _Bit_pointer;
601 typedef typename _Base::_Bit_alloc_traits _Bit_alloc_traits;
602
603#if __cplusplus >= 201103L
604 friend struct std::hash<vector>;
605#endif
606
607 public:
608 typedef bool value_type;
609 typedef size_t size_type;
610 typedef ptrdiff_t difference_type;
611 typedef _Bit_reference reference;
612 typedef bool const_reference;
613 typedef _Bit_reference* pointer;
614 typedef const bool* const_pointer;
615 typedef _Bit_iterator iterator;
616 typedef _Bit_const_iterator const_iterator;
617 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
618 typedef std::reverse_iterator<iterator> reverse_iterator;
619 typedef _Alloc allocator_type;
620
621 allocator_type
622 get_allocator() const
623 { return _Base::get_allocator(); }
624
625 protected:
626 using _Base::_M_allocate;
627 using _Base::_M_deallocate;
628 using _Base::_S_nword;
629 using _Base::_M_get_Bit_allocator;
630
631 public:
632#if __cplusplus >= 201103L
633 vector() = default;
634#else
635 vector() { }
636#endif
637
638 explicit
639 vector(const allocator_type& __a)
640 : _Base(__a) { }
641
642#if __cplusplus >= 201103L
643 explicit
644 vector(size_type __n, const allocator_type& __a = allocator_type())
645 : vector(__n, false, __a)
646 { }
647
648 vector(size_type __n, const bool& __value,
649 const allocator_type& __a = allocator_type())
650#else
651 explicit
652 vector(size_type __n, const bool& __value = bool(),
653 const allocator_type& __a = allocator_type())
654#endif
655 : _Base(__a)
656 {
657 _M_check_and_initialize(__n);
658 _M_initialize_value(__value);
659 }
660
661 vector(const vector& __x)
662 : _Base(_Bit_alloc_traits::_S_select_on_copy(__x._M_get_Bit_allocator()))
663 {
664 _M_initialize(__x.size());
665 _M_copy_aligned(__x.begin(), __x.end(), begin());
666 }
667
668#if __cplusplus >= 201103L
669 vector(vector&&) = default;
670
671 private:
672 vector(vector&& __x, const allocator_type& __a, true_type) noexcept
673 : _Base(std::move(__x), __a)
674 { }
675
676 vector(vector&& __x, const allocator_type& __a, false_type)
677 : _Base(__a)
678 {
679 if (__x.get_allocator() == __a)
680 this->_M_move_data(std::move(__x));
681 else
682 {
683 _M_initialize(__x.size());
684 _M_copy_aligned(__x.begin(), __x.end(), begin());
685 __x.clear();
686 }
687 }
688
689 public:
690 vector(vector&& __x, const allocator_type& __a)
691 noexcept(_Bit_alloc_traits::_S_always_equal())
692 : vector(std::move(__x), __a,
694 { }
695
696 vector(const vector& __x, const allocator_type& __a)
697 : _Base(__a)
698 {
699 _M_initialize(__x.size());
700 _M_copy_aligned(__x.begin(), __x.end(), begin());
701 }
702
704 const allocator_type& __a = allocator_type())
705 : _Base(__a)
706 {
707 _M_initialize_range(__l.begin(), __l.end(),
709 }
710#endif
711
712#if __cplusplus >= 201103L
713 template<typename _InputIterator,
714 typename = std::_RequireInputIter<_InputIterator>>
715 vector(_InputIterator __first, _InputIterator __last,
716 const allocator_type& __a = allocator_type())
717 : _Base(__a)
718 {
719 _M_initialize_range(__first, __last,
720 std::__iterator_category(__first));
721 }
722#else
723 template<typename _InputIterator>
724 vector(_InputIterator __first, _InputIterator __last,
725 const allocator_type& __a = allocator_type())
726 : _Base(__a)
727 {
728 // Check whether it's an integral type. If so, it's not an iterator.
729 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
730 _M_initialize_dispatch(__first, __last, _Integral());
731 }
732#endif
733
734 ~vector() _GLIBCXX_NOEXCEPT { }
735
736 vector&
737 operator=(const vector& __x)
738 {
739 if (&__x == this)
740 return *this;
741#if __cplusplus >= 201103L
742 if (_Bit_alloc_traits::_S_propagate_on_copy_assign())
743 {
744 if (this->_M_get_Bit_allocator() != __x._M_get_Bit_allocator())
745 {
746 this->_M_deallocate();
747 std::__alloc_on_copy(_M_get_Bit_allocator(),
748 __x._M_get_Bit_allocator());
749 _M_initialize(__x.size());
750 }
751 else
752 std::__alloc_on_copy(_M_get_Bit_allocator(),
753 __x._M_get_Bit_allocator());
754 }
755#endif
756 if (__x.size() > capacity())
757 {
758 this->_M_deallocate();
759 _M_initialize(__x.size());
760 }
761 this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
762 begin());
763 return *this;
764 }
765
766#if __cplusplus >= 201103L
767 vector&
768 operator=(vector&& __x) noexcept(_Bit_alloc_traits::_S_nothrow_move())
769 {
770 if (_Bit_alloc_traits::_S_propagate_on_move_assign()
771 || this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator())
772 {
773 this->_M_deallocate();
774 this->_M_move_data(std::move(__x));
775 std::__alloc_on_move(_M_get_Bit_allocator(),
776 __x._M_get_Bit_allocator());
777 }
778 else
779 {
780 if (__x.size() > capacity())
781 {
782 this->_M_deallocate();
783 _M_initialize(__x.size());
784 }
785 this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(),
786 begin());
787 __x.clear();
788 }
789 return *this;
790 }
791
792 vector&
794 {
795 this->assign(__l.begin(), __l.end());
796 return *this;
797 }
798#endif
799
800 // assign(), a generalized assignment member function. Two
801 // versions: one that takes a count, and one that takes a range.
802 // The range version is a member template, so we dispatch on whether
803 // or not the type is an integer.
804 void
805 assign(size_type __n, const bool& __x)
806 { _M_fill_assign(__n, __x); }
807
808#if __cplusplus >= 201103L
809 template<typename _InputIterator,
810 typename = std::_RequireInputIter<_InputIterator>>
811 void
812 assign(_InputIterator __first, _InputIterator __last)
813 { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
814#else
815 template<typename _InputIterator>
816 void
817 assign(_InputIterator __first, _InputIterator __last)
818 {
819 // Check whether it's an integral type. If so, it's not an iterator.
820 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
821 _M_assign_dispatch(__first, __last, _Integral());
822 }
823#endif
824
825#if __cplusplus >= 201103L
826 void
828 { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); }
829#endif
830
831 iterator
832 begin() _GLIBCXX_NOEXCEPT
833 { return iterator(this->_M_impl._M_start._M_p, 0); }
834
835 const_iterator
836 begin() const _GLIBCXX_NOEXCEPT
837 { return const_iterator(this->_M_impl._M_start._M_p, 0); }
838
839 iterator
840 end() _GLIBCXX_NOEXCEPT
841 { return this->_M_impl._M_finish; }
842
843 const_iterator
844 end() const _GLIBCXX_NOEXCEPT
845 { return this->_M_impl._M_finish; }
846
847 reverse_iterator
848 rbegin() _GLIBCXX_NOEXCEPT
849 { return reverse_iterator(end()); }
850
851 const_reverse_iterator
852 rbegin() const _GLIBCXX_NOEXCEPT
853 { return const_reverse_iterator(end()); }
854
855 reverse_iterator
856 rend() _GLIBCXX_NOEXCEPT
857 { return reverse_iterator(begin()); }
858
859 const_reverse_iterator
860 rend() const _GLIBCXX_NOEXCEPT
861 { return const_reverse_iterator(begin()); }
862
863#if __cplusplus >= 201103L
864 const_iterator
865 cbegin() const noexcept
866 { return const_iterator(this->_M_impl._M_start._M_p, 0); }
867
868 const_iterator
869 cend() const noexcept
870 { return this->_M_impl._M_finish; }
871
872 const_reverse_iterator
873 crbegin() const noexcept
874 { return const_reverse_iterator(end()); }
875
876 const_reverse_iterator
877 crend() const noexcept
878 { return const_reverse_iterator(begin()); }
879#endif
880
881 size_type
882 size() const _GLIBCXX_NOEXCEPT
883 { return size_type(end() - begin()); }
884
885 size_type
886 max_size() const _GLIBCXX_NOEXCEPT
887 {
888 const size_type __isize =
889 __gnu_cxx::__numeric_traits<difference_type>::__max
890 - int(_S_word_bit) + 1;
891 const size_type __asize
892 = _Bit_alloc_traits::max_size(_M_get_Bit_allocator());
893 return (__asize <= __isize / int(_S_word_bit)
894 ? __asize * int(_S_word_bit) : __isize);
895 }
896
897 size_type
898 capacity() const _GLIBCXX_NOEXCEPT
899 { return size_type(const_iterator(this->_M_impl._M_end_addr(), 0)
900 - begin()); }
901
902 _GLIBCXX_NODISCARD bool
903 empty() const _GLIBCXX_NOEXCEPT
904 { return begin() == end(); }
905
906 reference
907 operator[](size_type __n)
908 { return begin()[__n]; }
909
910 const_reference
911 operator[](size_type __n) const
912 { return begin()[__n]; }
913
914 protected:
915 void
916 _M_range_check(size_type __n) const
917 {
918 if (__n >= this->size())
919 __throw_out_of_range_fmt(__N("vector<bool>::_M_range_check: __n "
920 "(which is %zu) >= this->size() "
921 "(which is %zu)"),
922 __n, this->size());
923 }
924
925 public:
926 reference
927 at(size_type __n)
928 { _M_range_check(__n); return (*this)[__n]; }
929
930 const_reference
931 at(size_type __n) const
932 { _M_range_check(__n); return (*this)[__n]; }
933
934 void
935 reserve(size_type __n)
936 {
937 if (__n > max_size())
938 __throw_length_error(__N("vector::reserve"));
939 if (capacity() < __n)
940 _M_reallocate(__n);
941 }
942
943 reference
944 front()
945 { return *begin(); }
946
947 const_reference
948 front() const
949 { return *begin(); }
950
951 reference
952 back()
953 { return *(end() - 1); }
954
955 const_reference
956 back() const
957 { return *(end() - 1); }
958
959 // _GLIBCXX_RESOLVE_LIB_DEFECTS
960 // DR 464. Suggestion for new member functions in standard containers.
961 // N.B. DR 464 says nothing about vector<bool> but we need something
962 // here due to the way we are implementing DR 464 in the debug-mode
963 // vector class.
964 void
965 data() _GLIBCXX_NOEXCEPT { }
966
967 void
968 push_back(bool __x)
969 {
970 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr())
971 *this->_M_impl._M_finish++ = __x;
972 else
973 _M_insert_aux(end(), __x);
974 }
975
976 void
977 swap(vector& __x) _GLIBCXX_NOEXCEPT
978 {
979#if __cplusplus >= 201103L
980 __glibcxx_assert(_Bit_alloc_traits::propagate_on_container_swap::value
981 || _M_get_Bit_allocator() == __x._M_get_Bit_allocator());
982#endif
983 this->_M_impl._M_swap_data(__x._M_impl);
984 _Bit_alloc_traits::_S_on_swap(_M_get_Bit_allocator(),
985 __x._M_get_Bit_allocator());
986 }
987
988 // [23.2.5]/1, third-to-last entry in synopsis listing
989 static void
990 swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT
991 {
992 bool __tmp = __x;
993 __x = __y;
994 __y = __tmp;
995 }
996
997 iterator
998#if __cplusplus >= 201103L
999 insert(const_iterator __position, const bool& __x = bool())
1000#else
1001 insert(iterator __position, const bool& __x = bool())
1002#endif
1003 {
1004 const difference_type __n = __position - begin();
1005 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()
1006 && __position == end())
1007 *this->_M_impl._M_finish++ = __x;
1008 else
1009 _M_insert_aux(__position._M_const_cast(), __x);
1010 return begin() + __n;
1011 }
1012
1013#if __cplusplus >= 201103L
1014 template<typename _InputIterator,
1015 typename = std::_RequireInputIter<_InputIterator>>
1016 iterator
1017 insert(const_iterator __position,
1018 _InputIterator __first, _InputIterator __last)
1019 {
1020 difference_type __offset = __position - cbegin();
1021 _M_insert_range(__position._M_const_cast(),
1022 __first, __last,
1023 std::__iterator_category(__first));
1024 return begin() + __offset;
1025 }
1026#else
1027 template<typename _InputIterator>
1028 void
1029 insert(iterator __position,
1030 _InputIterator __first, _InputIterator __last)
1031 {
1032 // Check whether it's an integral type. If so, it's not an iterator.
1033 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
1034 _M_insert_dispatch(__position, __first, __last, _Integral());
1035 }
1036#endif
1037
1038#if __cplusplus >= 201103L
1039 iterator
1040 insert(const_iterator __position, size_type __n, const bool& __x)
1041 {
1042 difference_type __offset = __position - cbegin();
1043 _M_fill_insert(__position._M_const_cast(), __n, __x);
1044 return begin() + __offset;
1045 }
1046#else
1047 void
1048 insert(iterator __position, size_type __n, const bool& __x)
1049 { _M_fill_insert(__position, __n, __x); }
1050#endif
1051
1052#if __cplusplus >= 201103L
1053 iterator
1054 insert(const_iterator __p, initializer_list<bool> __l)
1055 { return this->insert(__p, __l.begin(), __l.end()); }
1056#endif
1057
1058 void
1059 pop_back()
1060 { --this->_M_impl._M_finish; }
1061
1062 iterator
1063#if __cplusplus >= 201103L
1064 erase(const_iterator __position)
1065#else
1066 erase(iterator __position)
1067#endif
1068 { return _M_erase(__position._M_const_cast()); }
1069
1070 iterator
1071#if __cplusplus >= 201103L
1072 erase(const_iterator __first, const_iterator __last)
1073#else
1074 erase(iterator __first, iterator __last)
1075#endif
1076 { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); }
1077
1078 void
1079 resize(size_type __new_size, bool __x = bool())
1080 {
1081 if (__new_size < size())
1082 _M_erase_at_end(begin() + difference_type(__new_size));
1083 else
1084 insert(end(), __new_size - size(), __x);
1085 }
1086
1087#if __cplusplus >= 201103L
1088 void
1090 { _M_shrink_to_fit(); }
1091#endif
1092
1093 void
1094 flip() _GLIBCXX_NOEXCEPT
1095 {
1096 _Bit_type * const __end = this->_M_impl._M_end_addr();
1097 for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != __end; ++__p)
1098 *__p = ~*__p;
1099 }
1100
1101 void
1102 clear() _GLIBCXX_NOEXCEPT
1103 { _M_erase_at_end(begin()); }
1104
1105#if __cplusplus >= 201103L
1106 template<typename... _Args>
1107#if __cplusplus > 201402L
1108 reference
1109#else
1110 void
1111#endif
1112 emplace_back(_Args&&... __args)
1113 {
1114 push_back(bool(__args...));
1115#if __cplusplus > 201402L
1116 return back();
1117#endif
1118 }
1119
1120 template<typename... _Args>
1121 iterator
1122 emplace(const_iterator __pos, _Args&&... __args)
1123 { return insert(__pos, bool(__args...)); }
1124#endif
1125
1126 protected:
1127 // Precondition: __first._M_offset == 0 && __result._M_offset == 0.
1128 iterator
1129 _M_copy_aligned(const_iterator __first, const_iterator __last,
1130 iterator __result)
1131 {
1132 _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p);
1133 return std::copy(const_iterator(__last._M_p, 0), __last,
1134 iterator(__q, 0));
1135 }
1136
1137 void
1138 _M_initialize(size_type __n)
1139 {
1140 // Caller must ensure this, to avoid overflow in _S_nword.
1141 _GLIBCXX_DEBUG_ASSERT(__n <= (size_t)-_S_word_bit);
1142
1143 if (__n)
1144 {
1145 _Bit_pointer __q = this->_M_allocate(__n);
1146 this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
1147 iterator __start = iterator(std::__addressof(*__q), 0);
1148 this->_M_impl._M_start = __start;
1149 this->_M_impl._M_finish = __start + difference_type(__n);
1150 }
1151 }
1152
1153 template<typename _SizeT>
1154 void
1155 _M_check_and_initialize(_SizeT __n)
1156 {
1157 if (__n > max_size() || __n < 0)
1158 __throw_length_error(
1159 __N("Cannot create std::vector<bool> larger than max_size()"));
1160 _M_initialize(static_cast<size_type>(__n));
1161 }
1162
1163 void
1164 _M_initialize_value(bool __x)
1165 {
1166 if (_Bit_type* __p = this->_M_impl._M_start._M_p)
1167 __builtin_memset(__p, __x ? ~0 : 0,
1168 (this->_M_impl._M_end_addr() - __p)
1169 * sizeof(_Bit_type));
1170 }
1171
1172 void
1173 _M_reallocate(size_type __n);
1174
1175#if __cplusplus >= 201103L
1176 bool
1177 _M_shrink_to_fit();
1178#endif
1179
1180#if __cplusplus < 201103L
1181 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1182 // 438. Ambiguity in the "do the right thing" clause
1183 template<typename _Integer>
1184 void
1185 _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
1186 {
1187 _M_check_and_initialize(static_cast<size_type>(__n));
1188 _M_initialize_value(__x);
1189 }
1190
1191 template<typename _InputIterator>
1192 void
1193 _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
1194 __false_type)
1195 { _M_initialize_range(__first, __last,
1196 std::__iterator_category(__first)); }
1197#endif
1198
1199 template<typename _InputIterator>
1200 void
1201 _M_initialize_range(_InputIterator __first, _InputIterator __last,
1203 {
1204 for (; __first != __last; ++__first)
1205 push_back(*__first);
1206 }
1207
1208 template<typename _ForwardIterator>
1209 void
1210 _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last,
1212 {
1213 _M_check_and_initialize(std::distance(__first, __last));
1214 std::copy(__first, __last, begin());
1215 }
1216
1217#if __cplusplus < 201103L
1218 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1219 // 438. Ambiguity in the "do the right thing" clause
1220 template<typename _Integer>
1221 void
1222 _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
1223 { _M_fill_assign(__n, __val); }
1224
1225 template<class _InputIterator>
1226 void
1227 _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
1228 __false_type)
1229 { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
1230#endif
1231
1232 void
1233 _M_fill_assign(size_t __n, bool __x)
1234 {
1235 if (__n > size())
1236 {
1237 _M_initialize_value(__x);
1238 insert(end(), __n - size(), __x);
1239 }
1240 else
1241 {
1242 _M_erase_at_end(begin() + __n);
1243 _M_initialize_value(__x);
1244 }
1245 }
1246
1247 template<typename _InputIterator>
1248 void
1249 _M_assign_aux(_InputIterator __first, _InputIterator __last,
1251 {
1252 iterator __cur = begin();
1253 for (; __first != __last && __cur != end(); ++__cur, (void)++__first)
1254 *__cur = *__first;
1255 if (__first == __last)
1256 _M_erase_at_end(__cur);
1257 else
1258 insert(end(), __first, __last);
1259 }
1260
1261 template<typename _ForwardIterator>
1262 void
1263 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
1265 {
1266 const size_type __len = std::distance(__first, __last);
1267 if (__len < size())
1268 _M_erase_at_end(std::copy(__first, __last, begin()));
1269 else
1270 {
1271 _ForwardIterator __mid = __first;
1272 std::advance(__mid, size());
1273 std::copy(__first, __mid, begin());
1274 insert(end(), __mid, __last);
1275 }
1276 }
1277
1278#if __cplusplus < 201103L
1279 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1280 // 438. Ambiguity in the "do the right thing" clause
1281 template<typename _Integer>
1282 void
1283 _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
1284 __true_type)
1285 { _M_fill_insert(__pos, __n, __x); }
1286
1287 template<typename _InputIterator>
1288 void
1289 _M_insert_dispatch(iterator __pos,
1290 _InputIterator __first, _InputIterator __last,
1291 __false_type)
1292 { _M_insert_range(__pos, __first, __last,
1293 std::__iterator_category(__first)); }
1294#endif
1295
1296 void
1297 _M_fill_insert(iterator __position, size_type __n, bool __x);
1298
1299 template<typename _InputIterator>
1300 void
1301 _M_insert_range(iterator __pos, _InputIterator __first,
1302 _InputIterator __last, std::input_iterator_tag)
1303 {
1304 for (; __first != __last; ++__first)
1305 {
1306 __pos = insert(__pos, *__first);
1307 ++__pos;
1308 }
1309 }
1310
1311 template<typename _ForwardIterator>
1312 void
1313 _M_insert_range(iterator __position, _ForwardIterator __first,
1314 _ForwardIterator __last, std::forward_iterator_tag);
1315
1316 void
1317 _M_insert_aux(iterator __position, bool __x);
1318
1319 size_type
1320 _M_check_len(size_type __n, const char* __s) const
1321 {
1322 if (max_size() - size() < __n)
1323 __throw_length_error(__N(__s));
1324
1325 const size_type __len = size() + std::max(size(), __n);
1326 return (__len < size() || __len > max_size()) ? max_size() : __len;
1327 }
1328
1329 void
1330 _M_erase_at_end(iterator __pos)
1331 { this->_M_impl._M_finish = __pos; }
1332
1333 iterator
1334 _M_erase(iterator __pos);
1335
1336 iterator
1337 _M_erase(iterator __first, iterator __last);
1338 };
1339
1340_GLIBCXX_END_NAMESPACE_CONTAINER
1341
1342 inline void
1343 __fill_bvector(_GLIBCXX_STD_C::_Bit_type * __v,
1344 unsigned int __first, unsigned int __last, bool __x)
1345 {
1346 using _GLIBCXX_STD_C::_Bit_type;
1347 using _GLIBCXX_STD_C::_S_word_bit;
1348 const _Bit_type __fmask = ~0ul << __first;
1349 const _Bit_type __lmask = ~0ul >> (_S_word_bit - __last);
1350 const _Bit_type __mask = __fmask & __lmask;
1351
1352 if (__x)
1353 *__v |= __mask;
1354 else
1355 *__v &= ~__mask;
1356 }
1357
1358 inline void
1359 __fill_a1(_GLIBCXX_STD_C::_Bit_iterator __first,
1360 _GLIBCXX_STD_C::_Bit_iterator __last, const bool& __x)
1361 {
1362 using _GLIBCXX_STD_C::_Bit_type;
1363 using _GLIBCXX_STD_C::_S_word_bit;
1364 if (__first._M_p != __last._M_p)
1365 {
1366 _Bit_type* __first_p = __first._M_p;
1367 if (__first._M_offset != 0)
1368 __fill_bvector(__first_p++, __first._M_offset, _S_word_bit, __x);
1369
1370 __builtin_memset(__first_p, __x ? ~0 : 0,
1371 (__last._M_p - __first_p) * sizeof(_Bit_type));
1372
1373 if (__last._M_offset != 0)
1374 __fill_bvector(__last._M_p, 0, __last._M_offset, __x);
1375 }
1376 else if (__first._M_offset != __last._M_offset)
1377 __fill_bvector(__first._M_p, __first._M_offset, __last._M_offset, __x);
1378 }
1379
1380#if __cplusplus >= 201103L
1381 // DR 1182.
1382 /// std::hash specialization for vector<bool>.
1383 template<typename _Alloc>
1384 struct hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>
1385 : public __hash_base<size_t, _GLIBCXX_STD_C::vector<bool, _Alloc>>
1386 {
1387 size_t
1388 operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>&) const noexcept;
1389 };
1390#endif // C++11
1391
1392_GLIBCXX_END_NAMESPACE_VERSION
1393} // namespace std
1394
1395#endif
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
Definition type_traits:83
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
Definition type_traits:86
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:104
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
Definition any:428
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:49
constexpr const _Tp & max(const _Tp &, const _Tp &)
This does what you think it does.
constexpr iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
ISO C++ entities toplevel namespace is std.
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
constexpr void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.
initializer_list
Primary class template hash.
__detected_or_t< typename is_empty< _Bit_alloc_type >::type, __equal, _Bit_alloc_type > is_always_equal
Marking input iterators.
Forward iterators support a superset of input iterator operations.
Random-access iterators support a superset of bidirectional iterator operations.
A standard container which offers fixed time access to individual elements in any order.
Definition stl_vector.h:390
void resize(size_type __new_size)
Resizes the vector to the specified number of elements.
Definition stl_vector.h:937
reference at(size_type __n)
Provides access to the data contained in the vector.
vector()=default
Creates a vector with no elements.
_Tp * data() noexcept
iterator erase(const_iterator __position)
Remove element at given position.
reverse_iterator rbegin() noexcept
Definition stl_vector.h:847
bool empty() const noexcept
const_reverse_iterator crbegin() const noexcept
Definition stl_vector.h:902
reference front() noexcept
allocator_type get_allocator() const noexcept
Get a copy of the memory allocation object.
Definition stl_vector.h:284
void shrink_to_fit()
Definition stl_vector.h:989
reverse_iterator rend() noexcept
Definition stl_vector.h:865
void clear() noexcept
void push_back(const value_type &__x)
Add data to the end of the vector.
~vector() noexcept
Definition stl_vector.h:678
size_type max_size() const noexcept
Definition stl_vector.h:923
const_reverse_iterator crend() const noexcept
Definition stl_vector.h:911
void _M_range_check(size_type __n) const
Safety check used only from at().
void reserve(size_type __n)
Attempt to preallocate enough memory for specified number of elements.
Definition vector.tcc:67
void assign(size_type __n, const value_type &__val)
Assigns a given value to a vector.
Definition stl_vector.h:749
void swap(vector &__x) noexcept
Swaps data with another vector.
void pop_back() noexcept
Removes last element.
vector & operator=(const vector &__x)
Vector assignment operator.
Definition vector.tcc:199
const_iterator cbegin() const noexcept
Definition stl_vector.h:884
const_iterator cend() const noexcept
Definition stl_vector.h:893
iterator emplace(const_iterator __position, _Args &&... __args)
Inserts an object in vector before specified iterator.
iterator begin() noexcept
Definition stl_vector.h:811
reference back() noexcept
iterator insert(const_iterator __position, const value_type &__x)
Inserts given value into vector before specified iterator.
Definition vector.tcc:132
iterator end() noexcept
Definition stl_vector.h:829
size_type size() const noexcept
Definition stl_vector.h:918
size_type capacity() const noexcept
Definition stl_vector.h:998
reference operator[](size_type __n) noexcept
Subscript access to the data contained in the vector.
static constexpr pointer allocate(_Bit_alloc_type &__a, size_type __n)
static constexpr void deallocate(_Bit_alloc_type &__a, pointer __p, size_type __n)
static constexpr size_type max_size(const _Bit_alloc_type &__a) noexcept