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