1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___VECTOR_VECTOR_BOOL_H
10 #define _LIBCPP___VECTOR_VECTOR_BOOL_H
12 #include <__algorithm/copy.h>
13 #include <__algorithm/copy_backward.h>
14 #include <__algorithm/fill_n.h>
15 #include <__algorithm/iterator_operations.h>
16 #include <__algorithm/max.h>
18 #include <__bit_reference>
20 #include <__functional/unary_function.h>
21 #include <__fwd/functional.h>
22 #include <__fwd/vector.h>
23 #include <__iterator/distance.h>
24 #include <__iterator/iterator_traits.h>
25 #include <__iterator/reverse_iterator.h>
26 #include <__memory/addressof.h>
27 #include <__memory/allocate_at_least.h>
28 #include <__memory/allocator.h>
29 #include <__memory/allocator_traits.h>
30 #include <__memory/compressed_pair.h>
31 #include <__memory/construct_at.h>
32 #include <__memory/noexcept_move_assign_container.h>
33 #include <__memory/pointer_traits.h>
34 #include <__memory/swap_allocator.h>
35 #include <__ranges/access.h>
36 #include <__ranges/concepts.h>
37 #include <__ranges/container_compatible_range.h>
38 #include <__ranges/from_range.h>
39 #include <__type_traits/enable_if.h>
40 #include <__type_traits/is_constant_evaluated.h>
41 #include <__type_traits/is_nothrow_assignable.h>
42 #include <__type_traits/is_nothrow_constructible.h>
43 #include <__type_traits/type_identity.h>
44 #include <__utility/exception_guard.h>
45 #include <__utility/forward.h>
46 #include <__utility/move.h>
47 #include <__utility/swap.h>
49 #include <initializer_list>
53 // These headers define parts of vectors definition, since they define ADL functions or class specializations.
54 #include <__vector/comparison.h>
55 #include <__vector/container_traits.h>
56 #include <__vector/swap.h>
58 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
59 # pragma GCC system_header
63 #include <__undef_macros>
65 _LIBCPP_BEGIN_NAMESPACE_STD
67 template <class _Allocator
>
68 struct hash
<vector
<bool, _Allocator
> >;
70 template <class _Allocator
>
71 struct __has_storage_type
<vector
<bool, _Allocator
> > {
72 static const bool value
= true;
75 template <class _Allocator
>
76 class _LIBCPP_TEMPLATE_VIS vector
<bool, _Allocator
> {
78 typedef vector __self
;
79 typedef bool value_type
;
80 typedef _Allocator allocator_type
;
81 typedef allocator_traits
<allocator_type
> __alloc_traits
;
82 typedef typename
__alloc_traits::size_type size_type
;
83 typedef typename
__alloc_traits::difference_type difference_type
;
84 typedef size_type __storage_type
;
85 typedef __bit_iterator
<vector
, false> pointer
;
86 typedef __bit_iterator
<vector
, true> const_pointer
;
87 typedef pointer iterator
;
88 typedef const_pointer const_iterator
;
89 typedef std::reverse_iterator
<iterator
> reverse_iterator
;
90 typedef std::reverse_iterator
<const_iterator
> const_reverse_iterator
;
93 typedef __rebind_alloc
<__alloc_traits
, __storage_type
> __storage_allocator
;
94 typedef allocator_traits
<__storage_allocator
> __storage_traits
;
95 typedef typename
__storage_traits::pointer __storage_pointer
;
96 typedef typename
__storage_traits::const_pointer __const_storage_pointer
;
98 __storage_pointer __begin_
;
100 _LIBCPP_COMPRESSED_PAIR(size_type
, __cap_
, __storage_allocator
, __alloc_
);
103 typedef __bit_reference
<vector
> reference
;
104 #ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
105 using const_reference
= bool;
107 typedef __bit_const_reference
<vector
> const_reference
;
111 static const unsigned __bits_per_word
= static_cast<unsigned>(sizeof(__storage_type
) * CHAR_BIT
);
113 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
static size_type
114 __internal_cap_to_external(size_type __n
) _NOEXCEPT
{
115 return __n
* __bits_per_word
;
117 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
static size_type
118 __external_cap_to_internal(size_type __n
) _NOEXCEPT
{
119 return __n
> 0 ? (__n
- 1) / __bits_per_word
+ 1 : size_type(0);
123 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
vector()
124 _NOEXCEPT_(is_nothrow_default_constructible
<allocator_type
>::value
);
126 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
explicit vector(const allocator_type
& __a
)
127 #if _LIBCPP_STD_VER <= 14
128 _NOEXCEPT_(is_nothrow_copy_constructible
<allocator_type
>::value
);
134 class __destroy_vector
{
136 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
__destroy_vector(vector
& __vec
) : __vec_(__vec
) {}
138 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
void operator()() {
139 if (__vec_
.__begin_
!= nullptr)
140 __storage_traits::deallocate(__vec_
.__alloc_
, __vec_
.__begin_
, __vec_
.__cap_
);
148 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
~vector() { __destroy_vector (*this)(); }
150 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
explicit vector(size_type __n
);
151 #if _LIBCPP_STD_VER >= 14
152 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
explicit vector(size_type __n
, const allocator_type
& __a
);
154 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
vector(size_type __n
, const value_type
& __v
);
155 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
156 vector(size_type __n
, const value_type
& __v
, const allocator_type
& __a
);
157 template <class _InputIterator
, __enable_if_t
<__has_exactly_input_iterator_category
<_InputIterator
>::value
, int> = 0>
158 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
vector(_InputIterator __first
, _InputIterator __last
);
159 template <class _InputIterator
, __enable_if_t
<__has_exactly_input_iterator_category
<_InputIterator
>::value
, int> = 0>
160 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
161 vector(_InputIterator __first
, _InputIterator __last
, const allocator_type
& __a
);
162 template <class _ForwardIterator
, __enable_if_t
<__has_forward_iterator_category
<_ForwardIterator
>::value
, int> = 0>
163 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
vector(_ForwardIterator __first
, _ForwardIterator __last
);
164 template <class _ForwardIterator
, __enable_if_t
<__has_forward_iterator_category
<_ForwardIterator
>::value
, int> = 0>
165 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
166 vector(_ForwardIterator __first
, _ForwardIterator __last
, const allocator_type
& __a
);
168 #if _LIBCPP_STD_VER >= 23
169 template <_ContainerCompatibleRange
<bool> _Range
>
170 _LIBCPP_HIDE_FROM_ABI
constexpr vector(from_range_t
, _Range
&& __range
, const allocator_type
& __a
= allocator_type())
171 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator
>(__a
)) {
172 if constexpr (ranges::forward_range
<_Range
> || ranges::sized_range
<_Range
>) {
173 auto __n
= static_cast<size_type
>(ranges::distance(__range
));
174 __init_with_size(ranges::begin(__range
), ranges::end(__range
), __n
);
177 __init_with_sentinel(ranges::begin(__range
), ranges::end(__range
));
182 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
vector(const vector
& __v
);
183 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
vector(const vector
& __v
, const allocator_type
& __a
);
184 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
& operator=(const vector
& __v
);
186 #ifndef _LIBCPP_CXX03_LANG
187 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
vector(initializer_list
<value_type
> __il
);
188 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
189 vector(initializer_list
<value_type
> __il
, const allocator_type
& __a
);
191 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
& operator=(initializer_list
<value_type
> __il
) {
192 assign(__il
.begin(), __il
.end());
196 #endif // !_LIBCPP_CXX03_LANG
198 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
vector(vector
&& __v
)
199 #if _LIBCPP_STD_VER >= 17
202 _NOEXCEPT_(is_nothrow_move_constructible
<allocator_type
>::value
);
204 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
205 vector(vector
&& __v
, const __type_identity_t
<allocator_type
>& __a
);
206 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
& operator=(vector
&& __v
)
207 _NOEXCEPT_(__noexcept_move_assign_container
<_Allocator
, __alloc_traits
>::value
);
209 template <class _InputIterator
, __enable_if_t
<__has_exactly_input_iterator_category
<_InputIterator
>::value
, int> = 0>
210 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
assign(_InputIterator __first
, _InputIterator __last
);
211 template <class _ForwardIterator
, __enable_if_t
<__has_forward_iterator_category
<_ForwardIterator
>::value
, int> = 0>
212 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
assign(_ForwardIterator __first
, _ForwardIterator __last
);
214 #if _LIBCPP_STD_VER >= 23
215 template <_ContainerCompatibleRange
<bool> _Range
>
216 _LIBCPP_HIDE_FROM_ABI
constexpr void assign_range(_Range
&& __range
) {
217 if constexpr (ranges::forward_range
<_Range
> || ranges::sized_range
<_Range
>) {
218 auto __n
= static_cast<size_type
>(ranges::distance(__range
));
219 __assign_with_size(ranges::begin(__range
), ranges::end(__range
), __n
);
222 __assign_with_sentinel(ranges::begin(__range
), ranges::end(__range
));
227 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void assign(size_type __n
, const value_type
& __x
);
229 #ifndef _LIBCPP_CXX03_LANG
230 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void assign(initializer_list
<value_type
> __il
) {
231 assign(__il
.begin(), __il
.end());
235 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type
get_allocator() const _NOEXCEPT
{
236 return allocator_type(this->__alloc_
);
239 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
max_size() const _NOEXCEPT
;
240 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
capacity() const _NOEXCEPT
{
241 return __internal_cap_to_external(__cap_
);
243 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
size() const _NOEXCEPT
{ return __size_
; }
244 [[__nodiscard__
]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
bool empty() const _NOEXCEPT
{
247 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void reserve(size_type __n
);
248 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void shrink_to_fit() _NOEXCEPT
;
250 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
begin() _NOEXCEPT
{ return __make_iter(0); }
251 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator
begin() const _NOEXCEPT
{ return __make_iter(0); }
252 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
end() _NOEXCEPT
{ return __make_iter(__size_
); }
253 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator
end() const _NOEXCEPT
{
254 return __make_iter(__size_
);
257 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator
rbegin() _NOEXCEPT
{
258 return reverse_iterator(end());
260 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
rbegin() const _NOEXCEPT
{
261 return const_reverse_iterator(end());
263 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator
rend() _NOEXCEPT
{
264 return reverse_iterator(begin());
266 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
rend() const _NOEXCEPT
{
267 return const_reverse_iterator(begin());
270 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator
cbegin() const _NOEXCEPT
{ return __make_iter(0); }
271 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator
cend() const _NOEXCEPT
{
272 return __make_iter(__size_
);
274 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
crbegin() const _NOEXCEPT
{
277 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator
crend() const _NOEXCEPT
{ return rend(); }
279 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference
operator[](size_type __n
) {
280 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n
< size(), "vector<bool>::operator[] index out of bounds");
281 return __make_ref(__n
);
283 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference
operator[](size_type __n
) const {
284 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n
< size(), "vector<bool>::operator[] index out of bounds");
285 return __make_ref(__n
);
287 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference
at(size_type __n
);
288 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference
at(size_type __n
) const;
290 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference
front() {
291 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector");
292 return __make_ref(0);
294 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference
front() const {
295 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector");
296 return __make_ref(0);
298 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference
back() {
299 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector");
300 return __make_ref(__size_
- 1);
302 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference
back() const {
303 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector");
304 return __make_ref(__size_
- 1);
307 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void push_back(const value_type
& __x
);
308 #if _LIBCPP_STD_VER >= 14
309 template <class... _Args
>
310 # if _LIBCPP_STD_VER >= 17
311 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference
emplace_back(_Args
&&... __args
)
313 _LIBCPP_HIDE_FROM_ABI
void emplace_back(_Args
&&... __args
)
316 push_back(value_type(std::forward
<_Args
>(__args
)...));
317 # if _LIBCPP_STD_VER >= 17
323 #if _LIBCPP_STD_VER >= 23
324 template <_ContainerCompatibleRange
<bool> _Range
>
325 _LIBCPP_HIDE_FROM_ABI
constexpr void append_range(_Range
&& __range
) {
326 insert_range(end(), std::forward
<_Range
>(__range
));
330 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void pop_back() {
331 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::pop_back called on an empty vector");
335 #if _LIBCPP_STD_VER >= 14
336 template <class... _Args
>
337 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
emplace(const_iterator __position
, _Args
&&... __args
) {
338 return insert(__position
, value_type(std::forward
<_Args
>(__args
)...));
342 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
insert(const_iterator __position
, const value_type
& __x
);
343 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
344 insert(const_iterator __position
, size_type __n
, const value_type
& __x
);
345 template <class _InputIterator
, __enable_if_t
<__has_exactly_input_iterator_category
<_InputIterator
>::value
, int> = 0>
346 iterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
347 insert(const_iterator __position
, _InputIterator __first
, _InputIterator __last
);
348 template <class _ForwardIterator
, __enable_if_t
<__has_forward_iterator_category
<_ForwardIterator
>::value
, int> = 0>
349 iterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
350 insert(const_iterator __position
, _ForwardIterator __first
, _ForwardIterator __last
);
352 #if _LIBCPP_STD_VER >= 23
353 template <_ContainerCompatibleRange
<bool> _Range
>
354 _LIBCPP_HIDE_FROM_ABI
constexpr iterator
insert_range(const_iterator __position
, _Range
&& __range
) {
355 if constexpr (ranges::forward_range
<_Range
> || ranges::sized_range
<_Range
>) {
356 auto __n
= static_cast<size_type
>(ranges::distance(__range
));
357 return __insert_with_size(__position
, ranges::begin(__range
), ranges::end(__range
), __n
);
360 return __insert_with_sentinel(__position
, ranges::begin(__range
), ranges::end(__range
));
365 #ifndef _LIBCPP_CXX03_LANG
366 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
367 insert(const_iterator __position
, initializer_list
<value_type
> __il
) {
368 return insert(__position
, __il
.begin(), __il
.end());
372 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
erase(const_iterator __position
);
373 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
erase(const_iterator __first
, const_iterator __last
);
375 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void clear() _NOEXCEPT
{ __size_
= 0; }
377 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void swap(vector
&)
378 #if _LIBCPP_STD_VER >= 14
381 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value
|| __is_nothrow_swappable_v
<allocator_type
>);
383 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
static void swap(reference __x
, reference __y
) _NOEXCEPT
{
387 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void resize(size_type __sz
, value_type __x
= false);
388 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void flip() _NOEXCEPT
;
390 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
bool __invariants() const;
393 [[__noreturn__
]] _LIBCPP_HIDE_FROM_ABI
static void __throw_length_error() { std::__throw_length_error("vector"); }
395 [[__noreturn__
]] _LIBCPP_HIDE_FROM_ABI
static void __throw_out_of_range() { std::__throw_out_of_range("vector"); }
397 template <class _InputIterator
, class _Sentinel
>
398 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
399 __init_with_size(_InputIterator __first
, _Sentinel __last
, size_type __n
) {
400 auto __guard
= std::__make_exception_guard(__destroy_vector(*this));
404 __construct_at_end(std::move(__first
), std::move(__last
), __n
);
407 __guard
.__complete();
410 template <class _InputIterator
, class _Sentinel
>
411 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
412 __init_with_sentinel(_InputIterator __first
, _Sentinel __last
) {
413 auto __guard
= std::__make_exception_guard(__destroy_vector(*this));
415 for (; __first
!= __last
; ++__first
)
418 __guard
.__complete();
421 template <class _Iterator
, class _Sentinel
>
422 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
void __assign_with_sentinel(_Iterator __first
, _Sentinel __last
);
424 // The `_Iterator` in `*_with_size` functions can be input-only only if called from `*_range` (since C++23).
425 // Otherwise, `_Iterator` is a forward iterator.
427 template <class _Iterator
, class _Sentinel
>
428 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
void
429 __assign_with_size(_Iterator __first
, _Sentinel __last
, difference_type __ns
);
431 template <class _InputIterator
, class _Sentinel
>
432 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
433 __insert_with_sentinel(const_iterator __position
, _InputIterator __first
, _Sentinel __last
);
435 template <class _Iterator
, class _Sentinel
>
436 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
437 __insert_with_size(const_iterator __position
, _Iterator __first
, _Sentinel __last
, difference_type __n
);
439 // Allocate space for __n objects
440 // throws length_error if __n > max_size()
441 // throws (probably bad_alloc) if memory run out
442 // Precondition: __begin_ == __end_ == __cap_ == nullptr
443 // Precondition: __n > 0
444 // Postcondition: capacity() >= __n
445 // Postcondition: size() == 0
446 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __vallocate(size_type __n
) {
447 if (__n
> max_size())
448 __throw_length_error();
449 auto __allocation
= std::__allocate_at_least(__alloc_
, __external_cap_to_internal(__n
));
450 __begin_
= __allocation
.ptr
;
452 __cap_
= __allocation
.count
;
453 if (__libcpp_is_constant_evaluated()) {
454 for (size_type __i
= 0; __i
!= __cap_
; ++__i
)
455 std::__construct_at(std::__to_address(__begin_
) + __i
);
459 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __vdeallocate() _NOEXCEPT
;
460 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
static size_type
__align_it(size_type __new_size
) _NOEXCEPT
{
461 return (__new_size
+ (__bits_per_word
- 1)) & ~((size_type
)__bits_per_word
- 1);
463 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
__recommend(size_type __new_size
) const;
464 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __construct_at_end(size_type __n
, bool __x
);
465 template <class _InputIterator
, class _Sentinel
>
466 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
467 __construct_at_end(_InputIterator __first
, _Sentinel __last
, size_type __n
);
468 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference
__make_ref(size_type __pos
) _NOEXCEPT
{
469 return reference(__begin_
+ __pos
/ __bits_per_word
, __storage_type(1) << __pos
% __bits_per_word
);
471 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference
__make_ref(size_type __pos
) const _NOEXCEPT
{
472 return __bit_const_reference
<vector
>(
473 __begin_
+ __pos
/ __bits_per_word
, __storage_type(1) << __pos
% __bits_per_word
);
475 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
__make_iter(size_type __pos
) _NOEXCEPT
{
476 return iterator(__begin_
+ __pos
/ __bits_per_word
, static_cast<unsigned>(__pos
% __bits_per_word
));
478 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator
__make_iter(size_type __pos
) const _NOEXCEPT
{
479 return const_iterator(__begin_
+ __pos
/ __bits_per_word
, static_cast<unsigned>(__pos
% __bits_per_word
));
481 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
__const_iterator_cast(const_iterator __p
) _NOEXCEPT
{
482 return begin() + (__p
- cbegin());
485 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __copy_assign_alloc(const vector
& __v
) {
487 __v
, integral_constant
<bool, __storage_traits::propagate_on_container_copy_assignment::value
>());
489 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __copy_assign_alloc(const vector
& __c
, true_type
) {
490 if (__alloc_
!= __c
.__alloc_
)
492 __alloc_
= __c
.__alloc_
;
495 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __copy_assign_alloc(const vector
&, false_type
) {}
497 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __move_assign(vector
& __c
, false_type
);
498 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __move_assign(vector
& __c
, true_type
)
499 _NOEXCEPT_(is_nothrow_move_assignable
<allocator_type
>::value
);
500 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __move_assign_alloc(vector
& __c
)
501 _NOEXCEPT_(!__storage_traits::propagate_on_container_move_assignment::value
||
502 is_nothrow_move_assignable
<allocator_type
>::value
) {
504 __c
, integral_constant
<bool, __storage_traits::propagate_on_container_move_assignment::value
>());
506 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __move_assign_alloc(vector
& __c
, true_type
)
507 _NOEXCEPT_(is_nothrow_move_assignable
<allocator_type
>::value
) {
508 __alloc_
= std::move(__c
.__alloc_
);
511 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __move_assign_alloc(vector
&, false_type
) _NOEXCEPT
{}
513 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
size_t __hash_code() const _NOEXCEPT
;
515 friend class __bit_reference
<vector
>;
516 friend class __bit_const_reference
<vector
>;
517 friend class __bit_iterator
<vector
, false>;
518 friend class __bit_iterator
<vector
, true>;
519 friend struct __bit_array
<vector
>;
520 friend struct _LIBCPP_TEMPLATE_VIS hash
<vector
>;
523 template <class _Allocator
>
524 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::__vdeallocate() _NOEXCEPT
{
525 if (this->__begin_
!= nullptr) {
526 __storage_traits::deallocate(this->__alloc_
, this->__begin_
, __cap_
);
527 this->__begin_
= nullptr;
528 this->__size_
= this->__cap_
= 0;
532 template <class _Allocator
>
533 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::size_type
534 vector
<bool, _Allocator
>::max_size() const _NOEXCEPT
{
535 size_type __amax
= __storage_traits::max_size(__alloc_
);
536 size_type __nmax
= numeric_limits
<size_type
>::max() / 2; // end() >= begin(), always
537 if (__nmax
/ __bits_per_word
<= __amax
)
539 return __internal_cap_to_external(__amax
);
542 // Precondition: __new_size > capacity()
543 template <class _Allocator
>
544 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::size_type
545 vector
<bool, _Allocator
>::__recommend(size_type __new_size
) const {
546 const size_type __ms
= max_size();
547 if (__new_size
> __ms
)
548 this->__throw_length_error();
549 const size_type __cap
= capacity();
550 if (__cap
>= __ms
/ 2)
552 return std::max(2 * __cap
, __align_it(__new_size
));
555 // Default constructs __n objects starting at __end_
556 // Precondition: size() + __n <= capacity()
557 // Postcondition: size() == size() + __n
558 template <class _Allocator
>
559 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
560 vector
<bool, _Allocator
>::__construct_at_end(size_type __n
, bool __x
) {
561 _LIBCPP_ASSERT_INTERNAL(
562 capacity() >= size() + __n
, "vector<bool>::__construct_at_end called with insufficient capacity");
563 std::fill_n(end(), __n
, __x
);
564 this->__size_
+= __n
;
565 if (end().__ctz_
!= 0) // Ensure uninitialized leading bits in the last word are set to zero
566 std::fill_n(end(), __bits_per_word
- end().__ctz_
, 0);
569 template <class _Allocator
>
570 template <class _InputIterator
, class _Sentinel
>
571 _LIBCPP_CONSTEXPR_SINCE_CXX20
void
572 vector
<bool, _Allocator
>::__construct_at_end(_InputIterator __first
, _Sentinel __last
, size_type __n
) {
573 _LIBCPP_ASSERT_INTERNAL(
574 capacity() >= size() + __n
, "vector<bool>::__construct_at_end called with insufficient capacity");
575 std::__copy(std::move(__first
), std::move(__last
), end());
576 this->__size_
+= __n
;
577 if (end().__ctz_
!= 0) // Ensure uninitialized leading bits in the last word are set to zero
578 std::fill_n(end(), __bits_per_word
- end().__ctz_
, 0);
581 template <class _Allocator
>
582 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector()
583 _NOEXCEPT_(is_nothrow_default_constructible
<allocator_type
>::value
)
584 : __begin_(nullptr), __size_(0), __cap_(0) {}
586 template <class _Allocator
>
587 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(const allocator_type
& __a
)
588 #if _LIBCPP_STD_VER <= 14
589 _NOEXCEPT_(is_nothrow_copy_constructible
<allocator_type
>::value
)
593 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator
>(__a
)) {
596 template <class _Allocator
>
597 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(size_type __n
)
598 : __begin_(nullptr), __size_(0), __cap_(0) {
601 __construct_at_end(__n
, false);
605 #if _LIBCPP_STD_VER >= 14
606 template <class _Allocator
>
607 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(size_type __n
, const allocator_type
& __a
)
608 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator
>(__a
)) {
611 __construct_at_end(__n
, false);
616 template <class _Allocator
>
617 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(size_type __n
, const value_type
& __x
)
618 : __begin_(nullptr), __size_(0), __cap_(0) {
621 __construct_at_end(__n
, __x
);
625 template <class _Allocator
>
626 _LIBCPP_CONSTEXPR_SINCE_CXX20
627 vector
<bool, _Allocator
>::vector(size_type __n
, const value_type
& __x
, const allocator_type
& __a
)
628 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator
>(__a
)) {
631 __construct_at_end(__n
, __x
);
635 template <class _Allocator
>
636 template <class _InputIterator
, __enable_if_t
<__has_exactly_input_iterator_category
<_InputIterator
>::value
, int> >
637 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(_InputIterator __first
, _InputIterator __last
)
638 : __begin_(nullptr), __size_(0), __cap_(0) {
639 __init_with_sentinel(__first
, __last
);
642 template <class _Allocator
>
643 template <class _InputIterator
, __enable_if_t
<__has_exactly_input_iterator_category
<_InputIterator
>::value
, int> >
644 _LIBCPP_CONSTEXPR_SINCE_CXX20
645 vector
<bool, _Allocator
>::vector(_InputIterator __first
, _InputIterator __last
, const allocator_type
& __a
)
646 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator
>(__a
)) {
647 __init_with_sentinel(__first
, __last
);
650 template <class _Allocator
>
651 template <class _ForwardIterator
, __enable_if_t
<__has_forward_iterator_category
<_ForwardIterator
>::value
, int> >
652 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(_ForwardIterator __first
, _ForwardIterator __last
)
653 : __begin_(nullptr), __size_(0), __cap_(0) {
654 auto __n
= static_cast<size_type
>(std::distance(__first
, __last
));
655 __init_with_size(__first
, __last
, __n
);
658 template <class _Allocator
>
659 template <class _ForwardIterator
, __enable_if_t
<__has_forward_iterator_category
<_ForwardIterator
>::value
, int> >
660 _LIBCPP_CONSTEXPR_SINCE_CXX20
661 vector
<bool, _Allocator
>::vector(_ForwardIterator __first
, _ForwardIterator __last
, const allocator_type
& __a
)
662 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator
>(__a
)) {
663 auto __n
= static_cast<size_type
>(std::distance(__first
, __last
));
664 __init_with_size(__first
, __last
, __n
);
667 #ifndef _LIBCPP_CXX03_LANG
669 template <class _Allocator
>
670 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(initializer_list
<value_type
> __il
)
671 : __begin_(nullptr), __size_(0), __cap_(0) {
672 size_type __n
= static_cast<size_type
>(__il
.size());
675 __construct_at_end(__il
.begin(), __il
.end(), __n
);
679 template <class _Allocator
>
680 _LIBCPP_CONSTEXPR_SINCE_CXX20
681 vector
<bool, _Allocator
>::vector(initializer_list
<value_type
> __il
, const allocator_type
& __a
)
682 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator
>(__a
)) {
683 size_type __n
= static_cast<size_type
>(__il
.size());
686 __construct_at_end(__il
.begin(), __il
.end(), __n
);
690 #endif // _LIBCPP_CXX03_LANG
692 template <class _Allocator
>
693 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(const vector
& __v
)
697 __alloc_(__storage_traits::select_on_container_copy_construction(__v
.__alloc_
)) {
698 if (__v
.size() > 0) {
699 __vallocate(__v
.size());
700 __construct_at_end(__v
.begin(), __v
.end(), __v
.size());
704 template <class _Allocator
>
705 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(const vector
& __v
, const allocator_type
& __a
)
706 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(__a
) {
707 if (__v
.size() > 0) {
708 __vallocate(__v
.size());
709 __construct_at_end(__v
.begin(), __v
.end(), __v
.size());
713 template <class _Allocator
>
714 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>& vector
<bool, _Allocator
>::operator=(const vector
& __v
) {
715 if (this != std::addressof(__v
)) {
716 __copy_assign_alloc(__v
);
718 if (__v
.__size_
> capacity()) {
720 __vallocate(__v
.__size_
);
722 std::copy(__v
.__begin_
, __v
.__begin_
+ __external_cap_to_internal(__v
.__size_
), __begin_
);
724 __size_
= __v
.__size_
;
729 template <class _Allocator
>
730 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>::vector(vector
&& __v
)
731 #if _LIBCPP_STD_VER >= 17
734 _NOEXCEPT_(is_nothrow_move_constructible
<allocator_type
>::value
)
736 : __begin_(__v
.__begin_
),
737 __size_(__v
.__size_
),
739 __alloc_(std::move(__v
.__alloc_
)) {
740 __v
.__begin_
= nullptr;
745 template <class _Allocator
>
746 _LIBCPP_CONSTEXPR_SINCE_CXX20
747 vector
<bool, _Allocator
>::vector(vector
&& __v
, const __type_identity_t
<allocator_type
>& __a
)
748 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(__a
) {
749 if (__a
== allocator_type(__v
.__alloc_
)) {
750 this->__begin_
= __v
.__begin_
;
751 this->__size_
= __v
.__size_
;
752 this->__cap_
= __v
.__cap_
;
753 __v
.__begin_
= nullptr;
754 __v
.__cap_
= __v
.__size_
= 0;
755 } else if (__v
.size() > 0) {
756 __vallocate(__v
.size());
757 __construct_at_end(__v
.begin(), __v
.end(), __v
.size());
761 template <class _Allocator
>
762 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector
<bool, _Allocator
>&
763 vector
<bool, _Allocator
>::operator=(vector
&& __v
)
764 _NOEXCEPT_(__noexcept_move_assign_container
<_Allocator
, __alloc_traits
>::value
) {
765 __move_assign(__v
, integral_constant
<bool, __storage_traits::propagate_on_container_move_assignment::value
>());
769 template <class _Allocator
>
770 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::__move_assign(vector
& __c
, false_type
) {
771 if (__alloc_
!= __c
.__alloc_
)
772 assign(__c
.begin(), __c
.end());
774 __move_assign(__c
, true_type());
777 template <class _Allocator
>
778 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::__move_assign(vector
& __c
, true_type
)
779 _NOEXCEPT_(is_nothrow_move_assignable
<allocator_type
>::value
) {
781 __move_assign_alloc(__c
);
782 this->__begin_
= __c
.__begin_
;
783 this->__size_
= __c
.__size_
;
784 this->__cap_
= __c
.__cap_
;
785 __c
.__begin_
= nullptr;
786 __c
.__cap_
= __c
.__size_
= 0;
789 template <class _Allocator
>
790 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::assign(size_type __n
, const value_type
& __x
) {
793 size_type __c
= capacity();
797 vector
__v(get_allocator());
798 __v
.reserve(__recommend(__n
));
802 std::fill_n(begin(), __n
, __x
);
806 template <class _Allocator
>
807 template <class _InputIterator
, __enable_if_t
<__has_exactly_input_iterator_category
<_InputIterator
>::value
, int> >
808 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::assign(_InputIterator __first
, _InputIterator __last
) {
809 __assign_with_sentinel(__first
, __last
);
812 template <class _Allocator
>
813 template <class _Iterator
, class _Sentinel
>
814 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
void
815 vector
<bool, _Allocator
>::__assign_with_sentinel(_Iterator __first
, _Sentinel __last
) {
817 for (; __first
!= __last
; ++__first
)
821 template <class _Allocator
>
822 template <class _ForwardIterator
, __enable_if_t
<__has_forward_iterator_category
<_ForwardIterator
>::value
, int> >
823 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::assign(_ForwardIterator __first
, _ForwardIterator __last
) {
824 __assign_with_size(__first
, __last
, std::distance(__first
, __last
));
827 template <class _Allocator
>
828 template <class _Iterator
, class _Sentinel
>
829 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
void
830 vector
<bool, _Allocator
>::__assign_with_size(_Iterator __first
, _Sentinel __last
, difference_type __ns
) {
831 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__ns
>= 0, "invalid range specified");
835 const size_t __n
= static_cast<size_type
>(__ns
);
837 if (__n
> capacity()) {
841 __construct_at_end(std::move(__first
), std::move(__last
), __n
);
845 template <class _Allocator
>
846 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::reserve(size_type __n
) {
847 if (__n
> capacity()) {
848 if (__n
> max_size())
849 this->__throw_length_error();
850 vector
__v(this->get_allocator());
851 __v
.__vallocate(__n
);
852 __v
.__construct_at_end(this->begin(), this->end(), this->size());
857 template <class _Allocator
>
858 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::shrink_to_fit() _NOEXCEPT
{
859 if (__external_cap_to_internal(size()) < __cap_
) {
860 #if _LIBCPP_HAS_EXCEPTIONS
862 #endif // _LIBCPP_HAS_EXCEPTIONS
863 vector
__v(*this, allocator_type(__alloc_
));
864 if (__v
.__cap_
< __cap_
)
866 #if _LIBCPP_HAS_EXCEPTIONS
869 #endif // _LIBCPP_HAS_EXCEPTIONS
873 template <class _Allocator
>
874 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::reference vector
<bool, _Allocator
>::at(size_type __n
) {
876 this->__throw_out_of_range();
880 template <class _Allocator
>
881 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::const_reference
882 vector
<bool, _Allocator
>::at(size_type __n
) const {
884 this->__throw_out_of_range();
888 template <class _Allocator
>
889 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::push_back(const value_type
& __x
) {
890 if (this->__size_
== this->capacity())
891 reserve(__recommend(this->__size_
+ 1));
896 template <class _Allocator
>
897 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::iterator
898 vector
<bool, _Allocator
>::insert(const_iterator __position
, const value_type
& __x
) {
900 if (size() < capacity()) {
901 const_iterator __old_end
= end();
903 std::copy_backward(__position
, __old_end
, end());
904 __r
= __const_iterator_cast(__position
);
906 vector
__v(get_allocator());
907 __v
.reserve(__recommend(__size_
+ 1));
908 __v
.__size_
= __size_
+ 1;
909 __r
= std::copy(cbegin(), __position
, __v
.begin());
910 std::copy_backward(__position
, cend(), __v
.end());
917 template <class _Allocator
>
918 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::iterator
919 vector
<bool, _Allocator
>::insert(const_iterator __position
, size_type __n
, const value_type
& __x
) {
921 size_type __c
= capacity();
922 if (__n
<= __c
&& size() <= __c
- __n
) {
923 const_iterator __old_end
= end();
925 std::copy_backward(__position
, __old_end
, end());
926 __r
= __const_iterator_cast(__position
);
928 vector
__v(get_allocator());
929 __v
.reserve(__recommend(__size_
+ __n
));
930 __v
.__size_
= __size_
+ __n
;
931 __r
= std::copy(cbegin(), __position
, __v
.begin());
932 std::copy_backward(__position
, cend(), __v
.end());
935 std::fill_n(__r
, __n
, __x
);
939 template <class _Allocator
>
940 template <class _InputIterator
, __enable_if_t
<__has_exactly_input_iterator_category
<_InputIterator
>::value
, int> >
941 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::iterator
942 vector
<bool, _Allocator
>::insert(const_iterator __position
, _InputIterator __first
, _InputIterator __last
) {
943 return __insert_with_sentinel(__position
, __first
, __last
);
946 template <class _Allocator
>
947 template <class _InputIterator
, class _Sentinel
>
948 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector
<bool, _Allocator
>::iterator
949 vector
<bool, _Allocator
>::__insert_with_sentinel(const_iterator __position
, _InputIterator __first
, _Sentinel __last
) {
950 difference_type __off
= __position
- begin();
951 iterator __p
= __const_iterator_cast(__position
);
952 iterator __old_end
= end();
953 for (; size() != capacity() && __first
!= __last
; ++__first
) {
957 vector
__v(get_allocator());
958 if (__first
!= __last
) {
959 #if _LIBCPP_HAS_EXCEPTIONS
961 #endif // _LIBCPP_HAS_EXCEPTIONS
962 __v
.__assign_with_sentinel(std::move(__first
), std::move(__last
));
963 difference_type __old_size
= static_cast<difference_type
>(__old_end
- begin());
964 difference_type __old_p
= __p
- begin();
965 reserve(__recommend(size() + __v
.size()));
966 __p
= begin() + __old_p
;
967 __old_end
= begin() + __old_size
;
968 #if _LIBCPP_HAS_EXCEPTIONS
970 erase(__old_end
, end());
973 #endif // _LIBCPP_HAS_EXCEPTIONS
975 __p
= std::rotate(__p
, __old_end
, end());
976 insert(__p
, __v
.begin(), __v
.end());
977 return begin() + __off
;
980 template <class _Allocator
>
981 template <class _ForwardIterator
, __enable_if_t
<__has_forward_iterator_category
<_ForwardIterator
>::value
, int> >
982 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::iterator
983 vector
<bool, _Allocator
>::insert(const_iterator __position
, _ForwardIterator __first
, _ForwardIterator __last
) {
984 return __insert_with_size(__position
, __first
, __last
, std::distance(__first
, __last
));
987 template <class _Allocator
>
988 template <class _Iterator
, class _Sentinel
>
989 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector
<bool, _Allocator
>::iterator
990 vector
<bool, _Allocator
>::__insert_with_size(
991 const_iterator __position
, _Iterator __first
, _Sentinel __last
, difference_type __n_signed
) {
992 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__n_signed
>= 0, "invalid range specified");
993 const size_type __n
= static_cast<size_type
>(__n_signed
);
995 size_type __c
= capacity();
996 if (__n
<= __c
&& size() <= __c
- __n
) {
997 const_iterator __old_end
= end();
999 std::copy_backward(__position
, __old_end
, end());
1000 __r
= __const_iterator_cast(__position
);
1002 vector
__v(get_allocator());
1003 __v
.reserve(__recommend(__size_
+ __n
));
1004 __v
.__size_
= __size_
+ __n
;
1005 __r
= std::copy(cbegin(), __position
, __v
.begin());
1006 std::copy_backward(__position
, cend(), __v
.end());
1009 std::__copy(std::move(__first
), std::move(__last
), __r
);
1013 template <class _Allocator
>
1014 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::iterator
1015 vector
<bool, _Allocator
>::erase(const_iterator __position
) {
1016 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1017 __position
!= end(), "vector<bool>::erase(iterator) called with a non-dereferenceable iterator");
1018 iterator __r
= __const_iterator_cast(__position
);
1019 std::copy(__position
+ 1, this->cend(), __r
);
1024 template <class _Allocator
>
1025 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector
<bool, _Allocator
>::iterator
1026 vector
<bool, _Allocator
>::erase(const_iterator __first
, const_iterator __last
) {
1027 _LIBCPP_ASSERT_VALID_INPUT_RANGE(
1028 __first
<= __last
, "vector<bool>::erase(iterator, iterator) called with an invalid range");
1029 iterator __r
= __const_iterator_cast(__first
);
1030 difference_type __d
= __last
- __first
;
1031 std::copy(__last
, this->cend(), __r
);
1036 template <class _Allocator
>
1037 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::swap(vector
& __x
)
1038 #if _LIBCPP_STD_VER >= 14
1041 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value
|| __is_nothrow_swappable_v
<allocator_type
>)
1044 std::swap(this->__begin_
, __x
.__begin_
);
1045 std::swap(this->__size_
, __x
.__size_
);
1046 std::swap(this->__cap_
, __x
.__cap_
);
1047 std::__swap_allocator(this->__alloc_
, __x
.__alloc_
);
1050 template <class _Allocator
>
1051 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::resize(size_type __sz
, value_type __x
) {
1052 size_type __cs
= size();
1055 size_type __c
= capacity();
1056 size_type __n
= __sz
- __cs
;
1057 if (__n
<= __c
&& __cs
<= __c
- __n
) {
1061 vector
__v(get_allocator());
1062 __v
.reserve(__recommend(__size_
+ __n
));
1063 __v
.__size_
= __size_
+ __n
;
1064 __r
= std::copy(cbegin(), cend(), __v
.begin());
1067 std::fill_n(__r
, __n
, __x
);
1072 template <class _Allocator
>
1073 _LIBCPP_CONSTEXPR_SINCE_CXX20
void vector
<bool, _Allocator
>::flip() _NOEXCEPT
{
1074 // Flip each storage word entirely, including the last potentially partial word.
1075 // The unused bits in the last word are safe to flip as they won't be accessed.
1076 __storage_pointer __p
= __begin_
;
1077 for (size_type __n
= __external_cap_to_internal(size()); __n
!= 0; ++__p
, --__n
)
1081 template <class _Allocator
>
1082 _LIBCPP_CONSTEXPR_SINCE_CXX20
bool vector
<bool, _Allocator
>::__invariants() const {
1083 if (this->__begin_
== nullptr) {
1084 if (this->__size_
!= 0 || this->__cap_
!= 0)
1087 if (this->__cap_
== 0)
1089 if (this->__size_
> this->capacity())
1095 template <class _Allocator
>
1096 _LIBCPP_CONSTEXPR_SINCE_CXX20
size_t vector
<bool, _Allocator
>::__hash_code() const _NOEXCEPT
{
1098 // do middle whole words
1099 size_type __n
= __size_
;
1100 __storage_pointer __p
= __begin_
;
1101 for (; __n
>= __bits_per_word
; ++__p
, __n
-= __bits_per_word
)
1103 // do last partial word
1105 const __storage_type __m
= ~__storage_type(0) >> (__bits_per_word
- __n
);
1111 template <class _Allocator
>
1112 struct _LIBCPP_TEMPLATE_VIS hash
<vector
<bool, _Allocator
> >
1113 : public __unary_function
<vector
<bool, _Allocator
>, size_t> {
1114 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
size_t
1115 operator()(const vector
<bool, _Allocator
>& __vec
) const _NOEXCEPT
{
1116 return __vec
.__hash_code();
1120 _LIBCPP_END_NAMESPACE_STD
1124 #endif // _LIBCPP___VECTOR_VECTOR_BOOL_H