1 //===----------------------------------------------------------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___VECTOR_VECTOR_BOOL_H 10 #define _LIBCPP___VECTOR_VECTOR_BOOL_H 11 12 #include <__algorithm/copy.h> 13 #include <__algorithm/fill_n.h> 14 #include <__algorithm/iterator_operations.h> 15 #include <__algorithm/max.h> 16 #include <__assert> 17 #include <__bit_reference> 18 #include <__config> 19 #include <__functional/unary_function.h> 20 #include <__fwd/functional.h> 21 #include <__fwd/vector.h> 22 #include <__iterator/distance.h> 23 #include <__iterator/iterator_traits.h> 24 #include <__iterator/reverse_iterator.h> 25 #include <__memory/addressof.h> 26 #include <__memory/allocate_at_least.h> 27 #include <__memory/allocator.h> 28 #include <__memory/allocator_traits.h> 29 #include <__memory/compressed_pair.h> 30 #include <__memory/construct_at.h> 31 #include <__memory/noexcept_move_assign_container.h> 32 #include <__memory/pointer_traits.h> 33 #include <__memory/swap_allocator.h> 34 #include <__ranges/access.h> 35 #include <__ranges/concepts.h> 36 #include <__ranges/container_compatible_range.h> 37 #include <__ranges/from_range.h> 38 #include <__type_traits/enable_if.h> 39 #include <__type_traits/is_constant_evaluated.h> 40 #include <__type_traits/is_nothrow_assignable.h> 41 #include <__type_traits/is_nothrow_constructible.h> 42 #include <__type_traits/type_identity.h> 43 #include <__utility/exception_guard.h> 44 #include <__utility/forward.h> 45 #include <__utility/move.h> 46 #include <__utility/swap.h> 47 #include <climits> 48 #include <initializer_list> 49 #include <limits> 50 #include <stdexcept> 51 52 // These headers define parts of vectors definition, since they define ADL functions or class specializations. 53 #include <__vector/comparison.h> 54 #include <__vector/container_traits.h> 55 #include <__vector/swap.h> 56 57 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 58 # pragma GCC system_header 59 #endif 60 61 _LIBCPP_PUSH_MACROS 62 #include <__undef_macros> 63 64 _LIBCPP_BEGIN_NAMESPACE_STD 65 66 template <class _Allocator> 67 struct hash<vector<bool, _Allocator> >; 68 69 template <class _Allocator> 70 struct __has_storage_type<vector<bool, _Allocator> > { 71 static const bool value = true; 72 }; 73 74 template <class _Allocator> 75 class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator> { 76 public: 77 typedef vector __self; 78 typedef bool value_type; 79 typedef _Allocator allocator_type; 80 typedef allocator_traits<allocator_type> __alloc_traits; 81 typedef typename __alloc_traits::size_type size_type; 82 typedef typename __alloc_traits::difference_type difference_type; 83 typedef size_type __storage_type; 84 typedef __bit_iterator<vector, false> pointer; 85 typedef __bit_iterator<vector, true> const_pointer; 86 typedef pointer iterator; 87 typedef const_pointer const_iterator; 88 typedef std::reverse_iterator<iterator> reverse_iterator; 89 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 90 91 private: 92 typedef __rebind_alloc<__alloc_traits, __storage_type> __storage_allocator; 93 typedef allocator_traits<__storage_allocator> __storage_traits; 94 typedef typename __storage_traits::pointer __storage_pointer; 95 typedef typename __storage_traits::const_pointer __const_storage_pointer; 96 97 __storage_pointer __begin_; 98 size_type __size_; 99 _LIBCPP_COMPRESSED_PAIR(size_type, __cap_, __storage_allocator, __alloc_); 100 101 public: 102 typedef __bit_reference<vector> reference; 103 #ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL 104 using const_reference = bool; 105 #else 106 typedef __bit_const_reference<vector> const_reference; 107 #endif 108 109 private: 110 static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT); 111 112 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type 113 __internal_cap_to_external(size_type __n) _NOEXCEPT { 114 return __n * __bits_per_word; 115 } 116 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type 117 __external_cap_to_internal(size_type __n) _NOEXCEPT { 118 return __n > 0 ? (__n - 1) / __bits_per_word + 1 : size_type(0); 119 } 120 121 public: 122 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector() 123 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); 124 125 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(const allocator_type& __a) 126 #if _LIBCPP_STD_VER <= 14 127 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value); 128 #else 129 _NOEXCEPT; 130 #endif 131 132 private: 133 class __destroy_vector { 134 public: 135 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {} 136 137 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() { 138 if (__vec_.__begin_ != nullptr) 139 __storage_traits::deallocate(__vec_.__alloc_, __vec_.__begin_, __vec_.__cap_); 140 } 141 142 private: 143 vector& __vec_; 144 }; 145 146 public: 147 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector() { __destroy_vector (*this)(); } 148 149 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n); 150 #if _LIBCPP_STD_VER >= 14 151 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n, const allocator_type& __a); 152 #endif 153 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v); 154 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 155 vector(size_type __n, const value_type& __v, const allocator_type& __a); 156 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 157 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last); 158 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 159 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 160 vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a); 161 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 162 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last); 163 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 164 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 165 vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a); 166 167 #if _LIBCPP_STD_VER >= 23 168 template <_ContainerCompatibleRange<bool> _Range> 169 _LIBCPP_HIDE_FROM_ABI constexpr vector(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) 170 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { 171 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 172 auto __n = static_cast<size_type>(ranges::distance(__range)); 173 __init_with_size(ranges::begin(__range), ranges::end(__range), __n); 174 175 } else { 176 __init_with_sentinel(ranges::begin(__range), ranges::end(__range)); 177 } 178 } 179 #endif 180 181 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v); 182 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v, const allocator_type& __a); 183 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector& operator=(const vector& __v); 184 185 #ifndef _LIBCPP_CXX03_LANG 186 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(initializer_list<value_type> __il); 187 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 188 vector(initializer_list<value_type> __il, const allocator_type& __a); 189 190 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector& operator=(initializer_list<value_type> __il) { 191 assign(__il.begin(), __il.end()); 192 return *this; 193 } 194 195 #endif // !_LIBCPP_CXX03_LANG 196 197 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(vector&& __v) 198 #if _LIBCPP_STD_VER >= 17 199 noexcept; 200 #else 201 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); 202 #endif 203 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 204 vector(vector&& __v, const __type_identity_t<allocator_type>& __a); 205 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector& operator=(vector&& __v) 206 _NOEXCEPT_(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value); 207 208 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 209 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_InputIterator __first, _InputIterator __last); 210 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 211 void _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_ForwardIterator __first, _ForwardIterator __last); 212 213 #if _LIBCPP_STD_VER >= 23 214 template <_ContainerCompatibleRange<bool> _Range> 215 _LIBCPP_HIDE_FROM_ABI constexpr void assign_range(_Range&& __range) { 216 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 217 auto __n = static_cast<size_type>(ranges::distance(__range)); 218 __assign_with_size(ranges::begin(__range), ranges::end(__range), __n); 219 220 } else { 221 __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); 222 } 223 } 224 #endif 225 226 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void assign(size_type __n, const value_type& __x); 227 228 #ifndef _LIBCPP_CXX03_LANG 229 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void assign(initializer_list<value_type> __il) { 230 assign(__il.begin(), __il.end()); 231 } 232 #endif 233 234 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT { 235 return allocator_type(this->__alloc_); 236 } 237 238 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT; 239 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type capacity() const _NOEXCEPT { 240 return __internal_cap_to_external(__cap_); 241 } 242 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type size() const _NOEXCEPT { return __size_; } 243 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool empty() const _NOEXCEPT { 244 return __size_ == 0; 245 } 246 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __n); 247 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT; 248 249 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() _NOEXCEPT { return __make_iter(0); } 250 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator begin() const _NOEXCEPT { return __make_iter(0); } 251 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() _NOEXCEPT { return __make_iter(__size_); } 252 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator end() const _NOEXCEPT { 253 return __make_iter(__size_); 254 } 255 256 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rbegin() _NOEXCEPT { 257 return reverse_iterator(end()); 258 } 259 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rbegin() const _NOEXCEPT { 260 return const_reverse_iterator(end()); 261 } 262 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reverse_iterator rend() _NOEXCEPT { 263 return reverse_iterator(begin()); 264 } 265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator rend() const _NOEXCEPT { 266 return const_reverse_iterator(begin()); 267 } 268 269 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cbegin() const _NOEXCEPT { return __make_iter(0); } 270 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator cend() const _NOEXCEPT { 271 return __make_iter(__size_); 272 } 273 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crbegin() const _NOEXCEPT { 274 return rbegin(); 275 } 276 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } 277 278 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __n) { 279 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector<bool>::operator[] index out of bounds"); 280 return __make_ref(__n); 281 } 282 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __n) const { 283 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector<bool>::operator[] index out of bounds"); 284 return __make_ref(__n); 285 } 286 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); 287 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; 288 289 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() { 290 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector"); 291 return __make_ref(0); 292 } 293 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const { 294 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::front() called on an empty vector"); 295 return __make_ref(0); 296 } 297 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() { 298 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector"); 299 return __make_ref(__size_ - 1); 300 } 301 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const { 302 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::back() called on an empty vector"); 303 return __make_ref(__size_ - 1); 304 } 305 306 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(const value_type& __x); 307 #if _LIBCPP_STD_VER >= 14 308 template <class... _Args> 309 # if _LIBCPP_STD_VER >= 17 310 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference emplace_back(_Args&&... __args) 311 # else 312 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args) 313 # endif 314 { 315 push_back(value_type(std::forward<_Args>(__args)...)); 316 # if _LIBCPP_STD_VER >= 17 317 return this->back(); 318 # endif 319 } 320 #endif 321 322 #if _LIBCPP_STD_VER >= 23 323 template <_ContainerCompatibleRange<bool> _Range> 324 _LIBCPP_HIDE_FROM_ABI constexpr void append_range(_Range&& __range) { 325 insert_range(end(), std::forward<_Range>(__range)); 326 } 327 #endif 328 329 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back() { 330 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector<bool>::pop_back called on an empty vector"); 331 --__size_; 332 } 333 334 #if _LIBCPP_STD_VER >= 14 335 template <class... _Args> 336 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator emplace(const_iterator __position, _Args&&... __args) { 337 return insert(__position, value_type(std::forward<_Args>(__args)...)); 338 } 339 #endif 340 341 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, const value_type& __x); 342 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 343 insert(const_iterator __position, size_type __n, const value_type& __x); 344 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> 345 iterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 346 insert(const_iterator __position, _InputIterator __first, _InputIterator __last); 347 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> 348 iterator _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 349 insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last); 350 351 #if _LIBCPP_STD_VER >= 23 352 template <_ContainerCompatibleRange<bool> _Range> 353 _LIBCPP_HIDE_FROM_ABI constexpr iterator insert_range(const_iterator __position, _Range&& __range) { 354 if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { 355 auto __n = static_cast<size_type>(ranges::distance(__range)); 356 return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); 357 358 } else { 359 return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); 360 } 361 } 362 #endif 363 364 #ifndef _LIBCPP_CXX03_LANG 365 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator 366 insert(const_iterator __position, initializer_list<value_type> __il) { 367 return insert(__position, __il.begin(), __il.end()); 368 } 369 #endif 370 371 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __position); 372 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __first, const_iterator __last); 373 374 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT { __size_ = 0; } 375 376 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&) 377 #if _LIBCPP_STD_VER >= 14 378 _NOEXCEPT; 379 #else 380 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>); 381 #endif 382 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void swap(reference __x, reference __y) _NOEXCEPT { 383 std::swap(__x, __y); 384 } 385 386 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __sz, value_type __x = false); 387 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT; 388 389 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __invariants() const; 390 391 private: 392 [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_length_error() { std::__throw_length_error("vector"); } 393 394 [[__noreturn__]] _LIBCPP_HIDE_FROM_ABI static void __throw_out_of_range() { std::__throw_out_of_range("vector"); } 395 396 template <class _InputIterator, class _Sentinel> 397 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 398 __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) { 399 auto __guard = std::__make_exception_guard(__destroy_vector(*this)); 400 401 if (__n > 0) { 402 __vallocate(__n); 403 __construct_at_end(std::move(__first), std::move(__last), __n); 404 } 405 406 __guard.__complete(); 407 } 408 409 template <class _InputIterator, class _Sentinel> 410 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 411 __init_with_sentinel(_InputIterator __first, _Sentinel __last) { 412 auto __guard = std::__make_exception_guard(__destroy_vector(*this)); 413 414 for (; __first != __last; ++__first) 415 push_back(*__first); 416 417 __guard.__complete(); 418 } 419 420 template <class _Iterator, class _Sentinel> 421 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __first, _Sentinel __last); 422 423 // The `_Iterator` in `*_with_size` functions can be input-only only if called from `*_range` (since C++23). 424 // Otherwise, `_Iterator` is a forward iterator. 425 426 template <class _Iterator, class _Sentinel> 427 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 428 __assign_with_size(_Iterator __first, _Sentinel __last, difference_type __ns); 429 430 template <class _InputIterator, class _Sentinel> 431 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator 432 __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last); 433 434 template <class _Iterator, class _Sentinel> 435 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator 436 __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n); 437 438 // Allocate space for __n objects 439 // throws length_error if __n > max_size() 440 // throws (probably bad_alloc) if memory run out 441 // Precondition: __begin_ == __end_ == __cap_ == nullptr 442 // Precondition: __n > 0 443 // Postcondition: capacity() >= __n 444 // Postcondition: size() == 0 445 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __vallocate(size_type __n) { 446 if (__n > max_size()) 447 __throw_length_error(); 448 auto __allocation = std::__allocate_at_least(__alloc_, __external_cap_to_internal(__n)); 449 __begin_ = __allocation.ptr; 450 __size_ = 0; 451 __cap_ = __allocation.count; 452 if (__libcpp_is_constant_evaluated()) { 453 for (size_type __i = 0; __i != __cap_; ++__i) 454 std::__construct_at(std::__to_address(__begin_) + __i); 455 } 456 } 457 458 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __vdeallocate() _NOEXCEPT; 459 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type __align_it(size_type __new_size) _NOEXCEPT { 460 return (__new_size + (__bits_per_word - 1)) & ~((size_type)__bits_per_word - 1); 461 } 462 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __new_size) const; 463 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_at_end(size_type __n, bool __x); 464 template <class _InputIterator, class _Sentinel> 465 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 466 __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); 467 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference __make_ref(size_type __pos) _NOEXCEPT { 468 return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word); 469 } 470 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference __make_ref(size_type __pos) const _NOEXCEPT { 471 return __bit_const_reference<vector>( 472 __begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word); 473 } 474 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iter(size_type __pos) _NOEXCEPT { 475 return iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word)); 476 } 477 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_iter(size_type __pos) const _NOEXCEPT { 478 return const_iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word)); 479 } 480 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT { 481 return begin() + (__p - cbegin()); 482 } 483 484 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const vector& __v) { 485 __copy_assign_alloc( 486 __v, integral_constant<bool, __storage_traits::propagate_on_container_copy_assignment::value>()); 487 } 488 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const vector& __c, true_type) { 489 if (__alloc_ != __c.__alloc_) 490 __vdeallocate(); 491 __alloc_ = __c.__alloc_; 492 } 493 494 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __copy_assign_alloc(const vector&, false_type) {} 495 496 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(vector& __c, false_type); 497 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(vector& __c, true_type) 498 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); 499 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector& __c) 500 _NOEXCEPT_(!__storage_traits::propagate_on_container_move_assignment::value || 501 is_nothrow_move_assignable<allocator_type>::value) { 502 __move_assign_alloc( 503 __c, integral_constant<bool, __storage_traits::propagate_on_container_move_assignment::value>()); 504 } 505 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector& __c, true_type) 506 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 507 __alloc_ = std::move(__c.__alloc_); 508 } 509 510 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector&, false_type) _NOEXCEPT {} 511 512 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t __hash_code() const _NOEXCEPT; 513 514 friend class __bit_reference<vector>; 515 friend class __bit_const_reference<vector>; 516 friend class __bit_iterator<vector, false>; 517 friend class __bit_iterator<vector, true>; 518 friend struct __bit_array<vector>; 519 friend struct _LIBCPP_TEMPLATE_VIS hash<vector>; 520 }; 521 522 template <class _Allocator> 523 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::__vdeallocate() _NOEXCEPT { 524 if (this->__begin_ != nullptr) { 525 __storage_traits::deallocate(this->__alloc_, this->__begin_, __cap_); 526 this->__begin_ = nullptr; 527 this->__size_ = this->__cap_ = 0; 528 } 529 } 530 531 template <class _Allocator> 532 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::size_type 533 vector<bool, _Allocator>::max_size() const _NOEXCEPT { 534 size_type __amax = __storage_traits::max_size(__alloc_); 535 size_type __nmax = numeric_limits<size_type>::max() / 2; // end() >= begin(), always 536 if (__nmax / __bits_per_word <= __amax) 537 return __nmax; 538 return __internal_cap_to_external(__amax); 539 } 540 541 // Precondition: __new_size > capacity() 542 template <class _Allocator> 543 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::size_type 544 vector<bool, _Allocator>::__recommend(size_type __new_size) const { 545 const size_type __ms = max_size(); 546 if (__new_size > __ms) 547 this->__throw_length_error(); 548 const size_type __cap = capacity(); 549 if (__cap >= __ms / 2) 550 return __ms; 551 return std::max(2 * __cap, __align_it(__new_size)); 552 } 553 554 // Default constructs __n objects starting at __end_ 555 // Precondition: size() + __n <= capacity() 556 // Postcondition: size() == size() + __n 557 template <class _Allocator> 558 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 559 vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x) { 560 _LIBCPP_ASSERT_INTERNAL( 561 capacity() >= size() + __n, "vector<bool>::__construct_at_end called with insufficient capacity"); 562 std::fill_n(end(), __n, __x); 563 this->__size_ += __n; 564 if (end().__ctz_ != 0) // Ensure uninitialized leading bits in the last word are set to zero 565 std::fill_n(end(), __bits_per_word - end().__ctz_, 0); 566 } 567 568 template <class _Allocator> 569 template <class _InputIterator, class _Sentinel> 570 _LIBCPP_CONSTEXPR_SINCE_CXX20 void 571 vector<bool, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) { 572 _LIBCPP_ASSERT_INTERNAL( 573 capacity() >= size() + __n, "vector<bool>::__construct_at_end called with insufficient capacity"); 574 std::__copy(std::move(__first), std::move(__last), end()); 575 this->__size_ += __n; 576 if (end().__ctz_ != 0) // Ensure uninitialized leading bits in the last word are set to zero 577 std::fill_n(end(), __bits_per_word - end().__ctz_, 0); 578 } 579 580 template <class _Allocator> 581 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector() 582 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 583 : __begin_(nullptr), __size_(0), __cap_(0) {} 584 585 template <class _Allocator> 586 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(const allocator_type& __a) 587 #if _LIBCPP_STD_VER <= 14 588 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) 589 #else 590 _NOEXCEPT 591 #endif 592 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { 593 } 594 595 template <class _Allocator> 596 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(size_type __n) 597 : __begin_(nullptr), __size_(0), __cap_(0) { 598 if (__n > 0) { 599 __vallocate(__n); 600 __construct_at_end(__n, false); 601 } 602 } 603 604 #if _LIBCPP_STD_VER >= 14 605 template <class _Allocator> 606 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a) 607 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { 608 if (__n > 0) { 609 __vallocate(__n); 610 __construct_at_end(__n, false); 611 } 612 } 613 #endif 614 615 template <class _Allocator> 616 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(size_type __n, const value_type& __x) 617 : __begin_(nullptr), __size_(0), __cap_(0) { 618 if (__n > 0) { 619 __vallocate(__n); 620 __construct_at_end(__n, __x); 621 } 622 } 623 624 template <class _Allocator> 625 _LIBCPP_CONSTEXPR_SINCE_CXX20 626 vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a) 627 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { 628 if (__n > 0) { 629 __vallocate(__n); 630 __construct_at_end(__n, __x); 631 } 632 } 633 634 template <class _Allocator> 635 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 636 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last) 637 : __begin_(nullptr), __size_(0), __cap_(0) { 638 __init_with_sentinel(__first, __last); 639 } 640 641 template <class _Allocator> 642 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 643 _LIBCPP_CONSTEXPR_SINCE_CXX20 644 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a) 645 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { 646 __init_with_sentinel(__first, __last); 647 } 648 649 template <class _Allocator> 650 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 651 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last) 652 : __begin_(nullptr), __size_(0), __cap_(0) { 653 auto __n = static_cast<size_type>(std::distance(__first, __last)); 654 __init_with_size(__first, __last, __n); 655 } 656 657 template <class _Allocator> 658 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 659 _LIBCPP_CONSTEXPR_SINCE_CXX20 660 vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a) 661 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { 662 auto __n = static_cast<size_type>(std::distance(__first, __last)); 663 __init_with_size(__first, __last, __n); 664 } 665 666 #ifndef _LIBCPP_CXX03_LANG 667 668 template <class _Allocator> 669 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(initializer_list<value_type> __il) 670 : __begin_(nullptr), __size_(0), __cap_(0) { 671 size_type __n = static_cast<size_type>(__il.size()); 672 if (__n > 0) { 673 __vallocate(__n); 674 __construct_at_end(__il.begin(), __il.end(), __n); 675 } 676 } 677 678 template <class _Allocator> 679 _LIBCPP_CONSTEXPR_SINCE_CXX20 680 vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a) 681 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { 682 size_type __n = static_cast<size_type>(__il.size()); 683 if (__n > 0) { 684 __vallocate(__n); 685 __construct_at_end(__il.begin(), __il.end(), __n); 686 } 687 } 688 689 #endif // _LIBCPP_CXX03_LANG 690 691 template <class _Allocator> 692 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(const vector& __v) 693 : __begin_(nullptr), 694 __size_(0), 695 __cap_(0), 696 __alloc_(__storage_traits::select_on_container_copy_construction(__v.__alloc_)) { 697 if (__v.size() > 0) { 698 __vallocate(__v.size()); 699 __construct_at_end(__v.begin(), __v.end(), __v.size()); 700 } 701 } 702 703 template <class _Allocator> 704 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a) 705 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(__a) { 706 if (__v.size() > 0) { 707 __vallocate(__v.size()); 708 __construct_at_end(__v.begin(), __v.end(), __v.size()); 709 } 710 } 711 712 template <class _Allocator> 713 _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>& vector<bool, _Allocator>::operator=(const vector& __v) { 714 if (this != std::addressof(__v)) { 715 __copy_assign_alloc(__v); 716 if (__v.__size_) { 717 if (__v.__size_ > capacity()) { 718 __vdeallocate(); 719 __vallocate(__v.__size_); 720 } 721 std::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.__size_), __begin_); 722 } 723 __size_ = __v.__size_; 724 } 725 return *this; 726 } 727 728 template <class _Allocator> 729 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(vector&& __v) 730 #if _LIBCPP_STD_VER >= 17 731 _NOEXCEPT 732 #else 733 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 734 #endif 735 : __begin_(__v.__begin_), 736 __size_(__v.__size_), 737 __cap_(__v.__cap_), 738 __alloc_(std::move(__v.__alloc_)) { 739 __v.__begin_ = nullptr; 740 __v.__size_ = 0; 741 __v.__cap_ = 0; 742 } 743 744 template <class _Allocator> 745 _LIBCPP_CONSTEXPR_SINCE_CXX20 746 vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator_type>& __a) 747 : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(__a) { 748 if (__a == allocator_type(__v.__alloc_)) { 749 this->__begin_ = __v.__begin_; 750 this->__size_ = __v.__size_; 751 this->__cap_ = __v.__cap_; 752 __v.__begin_ = nullptr; 753 __v.__cap_ = __v.__size_ = 0; 754 } else if (__v.size() > 0) { 755 __vallocate(__v.size()); 756 __construct_at_end(__v.begin(), __v.end(), __v.size()); 757 } 758 } 759 760 template <class _Allocator> 761 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>& 762 vector<bool, _Allocator>::operator=(vector&& __v) 763 _NOEXCEPT_(__noexcept_move_assign_container<_Allocator, __alloc_traits>::value) { 764 __move_assign(__v, integral_constant<bool, __storage_traits::propagate_on_container_move_assignment::value>()); 765 return *this; 766 } 767 768 template <class _Allocator> 769 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::__move_assign(vector& __c, false_type) { 770 if (__alloc_ != __c.__alloc_) 771 assign(__c.begin(), __c.end()); 772 else 773 __move_assign(__c, true_type()); 774 } 775 776 template <class _Allocator> 777 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::__move_assign(vector& __c, true_type) 778 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { 779 __vdeallocate(); 780 __move_assign_alloc(__c); 781 this->__begin_ = __c.__begin_; 782 this->__size_ = __c.__size_; 783 this->__cap_ = __c.__cap_; 784 __c.__begin_ = nullptr; 785 __c.__cap_ = __c.__size_ = 0; 786 } 787 788 template <class _Allocator> 789 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::assign(size_type __n, const value_type& __x) { 790 __size_ = 0; 791 if (__n > 0) { 792 size_type __c = capacity(); 793 if (__n <= __c) 794 __size_ = __n; 795 else { 796 vector __v(get_allocator()); 797 __v.reserve(__recommend(__n)); 798 __v.__size_ = __n; 799 swap(__v); 800 } 801 std::fill_n(begin(), __n, __x); 802 } 803 } 804 805 template <class _Allocator> 806 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 807 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { 808 __assign_with_sentinel(__first, __last); 809 } 810 811 template <class _Allocator> 812 template <class _Iterator, class _Sentinel> 813 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 814 vector<bool, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) { 815 clear(); 816 for (; __first != __last; ++__first) 817 push_back(*__first); 818 } 819 820 template <class _Allocator> 821 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 822 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) { 823 __assign_with_size(__first, __last, std::distance(__first, __last)); 824 } 825 826 template <class _Allocator> 827 template <class _Iterator, class _Sentinel> 828 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 829 vector<bool, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __ns) { 830 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__ns >= 0, "invalid range specified"); 831 832 clear(); 833 834 const size_t __n = static_cast<size_type>(__ns); 835 if (__n) { 836 if (__n > capacity()) { 837 __vdeallocate(); 838 __vallocate(__n); 839 } 840 __construct_at_end(std::move(__first), std::move(__last), __n); 841 } 842 } 843 844 template <class _Allocator> 845 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type __n) { 846 if (__n > capacity()) { 847 if (__n > max_size()) 848 this->__throw_length_error(); 849 vector __v(this->get_allocator()); 850 __v.__vallocate(__n); 851 __v.__construct_at_end(this->begin(), this->end(), this->size()); 852 swap(__v); 853 } 854 } 855 856 template <class _Allocator> 857 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT { 858 if (__external_cap_to_internal(size()) < __cap_) { 859 #if _LIBCPP_HAS_EXCEPTIONS 860 try { 861 #endif // _LIBCPP_HAS_EXCEPTIONS 862 vector __v(*this, allocator_type(__alloc_)); 863 if (__v.__cap_ < __cap_) 864 __v.swap(*this); 865 #if _LIBCPP_HAS_EXCEPTIONS 866 } catch (...) { 867 } 868 #endif // _LIBCPP_HAS_EXCEPTIONS 869 } 870 } 871 872 template <class _Allocator> 873 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::reference vector<bool, _Allocator>::at(size_type __n) { 874 if (__n >= size()) 875 this->__throw_out_of_range(); 876 return (*this)[__n]; 877 } 878 879 template <class _Allocator> 880 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::const_reference 881 vector<bool, _Allocator>::at(size_type __n) const { 882 if (__n >= size()) 883 this->__throw_out_of_range(); 884 return (*this)[__n]; 885 } 886 887 template <class _Allocator> 888 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::push_back(const value_type& __x) { 889 if (this->__size_ == this->capacity()) 890 reserve(__recommend(this->__size_ + 1)); 891 ++this->__size_; 892 back() = __x; 893 } 894 895 template <class _Allocator> 896 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::iterator 897 vector<bool, _Allocator>::insert(const_iterator __position, const value_type& __x) { 898 iterator __r; 899 if (size() < capacity()) { 900 const_iterator __old_end = end(); 901 ++__size_; 902 std::copy_backward(__position, __old_end, end()); 903 __r = __const_iterator_cast(__position); 904 } else { 905 vector __v(get_allocator()); 906 __v.reserve(__recommend(__size_ + 1)); 907 __v.__size_ = __size_ + 1; 908 __r = std::copy(cbegin(), __position, __v.begin()); 909 std::copy_backward(__position, cend(), __v.end()); 910 swap(__v); 911 } 912 *__r = __x; 913 return __r; 914 } 915 916 template <class _Allocator> 917 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::iterator 918 vector<bool, _Allocator>::insert(const_iterator __position, size_type __n, const value_type& __x) { 919 iterator __r; 920 size_type __c = capacity(); 921 if (__n <= __c && size() <= __c - __n) { 922 const_iterator __old_end = end(); 923 __size_ += __n; 924 std::copy_backward(__position, __old_end, end()); 925 __r = __const_iterator_cast(__position); 926 } else { 927 vector __v(get_allocator()); 928 __v.reserve(__recommend(__size_ + __n)); 929 __v.__size_ = __size_ + __n; 930 __r = std::copy(cbegin(), __position, __v.begin()); 931 std::copy_backward(__position, cend(), __v.end()); 932 swap(__v); 933 } 934 std::fill_n(__r, __n, __x); 935 return __r; 936 } 937 938 template <class _Allocator> 939 template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > 940 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::iterator 941 vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { 942 return __insert_with_sentinel(__position, __first, __last); 943 } 944 945 template <class _Allocator> 946 template <class _InputIterator, class _Sentinel> 947 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<bool, _Allocator>::iterator 948 vector<bool, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) { 949 difference_type __off = __position - begin(); 950 iterator __p = __const_iterator_cast(__position); 951 iterator __old_end = end(); 952 for (; size() != capacity() && __first != __last; ++__first) { 953 ++this->__size_; 954 back() = *__first; 955 } 956 vector __v(get_allocator()); 957 if (__first != __last) { 958 #if _LIBCPP_HAS_EXCEPTIONS 959 try { 960 #endif // _LIBCPP_HAS_EXCEPTIONS 961 __v.__assign_with_sentinel(std::move(__first), std::move(__last)); 962 difference_type __old_size = static_cast<difference_type>(__old_end - begin()); 963 difference_type __old_p = __p - begin(); 964 reserve(__recommend(size() + __v.size())); 965 __p = begin() + __old_p; 966 __old_end = begin() + __old_size; 967 #if _LIBCPP_HAS_EXCEPTIONS 968 } catch (...) { 969 erase(__old_end, end()); 970 throw; 971 } 972 #endif // _LIBCPP_HAS_EXCEPTIONS 973 } 974 __p = std::rotate(__p, __old_end, end()); 975 insert(__p, __v.begin(), __v.end()); 976 return begin() + __off; 977 } 978 979 template <class _Allocator> 980 template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > 981 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::iterator 982 vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { 983 return __insert_with_size(__position, __first, __last, std::distance(__first, __last)); 984 } 985 986 template <class _Allocator> 987 template <class _Iterator, class _Sentinel> 988 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<bool, _Allocator>::iterator 989 vector<bool, _Allocator>::__insert_with_size( 990 const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n_signed) { 991 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__n_signed >= 0, "invalid range specified"); 992 const size_type __n = static_cast<size_type>(__n_signed); 993 iterator __r; 994 size_type __c = capacity(); 995 if (__n <= __c && size() <= __c - __n) { 996 const_iterator __old_end = end(); 997 __size_ += __n; 998 std::copy_backward(__position, __old_end, end()); 999 __r = __const_iterator_cast(__position); 1000 } else { 1001 vector __v(get_allocator()); 1002 __v.reserve(__recommend(__size_ + __n)); 1003 __v.__size_ = __size_ + __n; 1004 __r = std::copy(cbegin(), __position, __v.begin()); 1005 std::copy_backward(__position, cend(), __v.end()); 1006 swap(__v); 1007 } 1008 std::__copy(std::move(__first), std::move(__last), __r); 1009 return __r; 1010 } 1011 1012 template <class _Allocator> 1013 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::iterator 1014 vector<bool, _Allocator>::erase(const_iterator __position) { 1015 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 1016 __position != end(), "vector<bool>::erase(iterator) called with a non-dereferenceable iterator"); 1017 iterator __r = __const_iterator_cast(__position); 1018 std::copy(__position + 1, this->cend(), __r); 1019 --__size_; 1020 return __r; 1021 } 1022 1023 template <class _Allocator> 1024 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<bool, _Allocator>::iterator 1025 vector<bool, _Allocator>::erase(const_iterator __first, const_iterator __last) { 1026 _LIBCPP_ASSERT_VALID_INPUT_RANGE( 1027 __first <= __last, "vector<bool>::erase(iterator, iterator) called with an invalid range"); 1028 iterator __r = __const_iterator_cast(__first); 1029 difference_type __d = __last - __first; 1030 std::copy(__last, this->cend(), __r); 1031 __size_ -= __d; 1032 return __r; 1033 } 1034 1035 template <class _Allocator> 1036 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::swap(vector& __x) 1037 #if _LIBCPP_STD_VER >= 14 1038 _NOEXCEPT 1039 #else 1040 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>) 1041 #endif 1042 { 1043 std::swap(this->__begin_, __x.__begin_); 1044 std::swap(this->__size_, __x.__size_); 1045 std::swap(this->__cap_, __x.__cap_); 1046 std::__swap_allocator(this->__alloc_, __x.__alloc_); 1047 } 1048 1049 template <class _Allocator> 1050 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::resize(size_type __sz, value_type __x) { 1051 size_type __cs = size(); 1052 if (__cs < __sz) { 1053 iterator __r; 1054 size_type __c = capacity(); 1055 size_type __n = __sz - __cs; 1056 if (__n <= __c && __cs <= __c - __n) { 1057 __r = end(); 1058 __size_ += __n; 1059 } else { 1060 vector __v(get_allocator()); 1061 __v.reserve(__recommend(__size_ + __n)); 1062 __v.__size_ = __size_ + __n; 1063 __r = std::copy(cbegin(), cend(), __v.begin()); 1064 swap(__v); 1065 } 1066 std::fill_n(__r, __n, __x); 1067 } else 1068 __size_ = __sz; 1069 } 1070 1071 template <class _Allocator> 1072 _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::flip() _NOEXCEPT { 1073 // Flip each storage word entirely, including the last potentially partial word. 1074 // The unused bits in the last word are safe to flip as they won't be accessed. 1075 __storage_pointer __p = __begin_; 1076 for (size_type __n = __external_cap_to_internal(size()); __n != 0; ++__p, --__n) 1077 *__p = ~*__p; 1078 } 1079 1080 template <class _Allocator> 1081 _LIBCPP_CONSTEXPR_SINCE_CXX20 bool vector<bool, _Allocator>::__invariants() const { 1082 if (this->__begin_ == nullptr) { 1083 if (this->__size_ != 0 || this->__cap_ != 0) 1084 return false; 1085 } else { 1086 if (this->__cap_ == 0) 1087 return false; 1088 if (this->__size_ > this->capacity()) 1089 return false; 1090 } 1091 return true; 1092 } 1093 1094 template <class _Allocator> 1095 _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t vector<bool, _Allocator>::__hash_code() const _NOEXCEPT { 1096 size_t __h = 0; 1097 // do middle whole words 1098 size_type __n = __size_; 1099 __storage_pointer __p = __begin_; 1100 for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) 1101 __h ^= *__p; 1102 // do last partial word 1103 if (__n > 0) { 1104 const __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 1105 __h ^= *__p & __m; 1106 } 1107 return __h; 1108 } 1109 1110 template <class _Allocator> 1111 struct _LIBCPP_TEMPLATE_VIS hash<vector<bool, _Allocator> > 1112 : public __unary_function<vector<bool, _Allocator>, size_t> { 1113 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t 1114 operator()(const vector<bool, _Allocator>& __vec) const _NOEXCEPT { 1115 return __vec.__hash_code(); 1116 } 1117 }; 1118 1119 _LIBCPP_END_NAMESPACE_STD 1120 1121 _LIBCPP_POP_MACROS 1122 1123 #endif // _LIBCPP___VECTOR_VECTOR_BOOL_H 1124