2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___BIT_REFERENCE
11 #define _LIBCPP___BIT_REFERENCE
13 #include <__algorithm/copy_n.h>
14 #include <__algorithm/fill_n.h>
15 #include <__algorithm/min.h>
16 #include <__bit/countr.h>
17 #include <__bit/invert_if.h>
18 #include <__bit/popcount.h>
20 #include <__fwd/bit_reference.h>
21 #include <__iterator/iterator_traits.h>
22 #include <__memory/construct_at.h>
23 #include <__memory/pointer_traits.h>
24 #include <__type_traits/conditional.h>
25 #include <__utility/swap.h>
28 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29 # pragma GCC system_header
33 #include <__undef_macros>
35 _LIBCPP_BEGIN_NAMESPACE_STD
38 class __bit_const_reference;
41 struct __has_storage_type {
42 static const bool value = false;
45 template <class _Cp, bool = __has_storage_type<_Cp>::value>
46 class __bit_reference {
47 using __storage_type = typename _Cp::__storage_type;
48 using __storage_pointer = typename _Cp::__storage_pointer;
50 __storage_pointer __seg_;
51 __storage_type __mask_;
53 friend typename _Cp::__self;
55 friend class __bit_const_reference<_Cp>;
56 friend class __bit_iterator<_Cp, false>;
59 using __container = typename _Cp::__self;
61 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference(const __bit_reference&) = default;
63 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT {
64 return static_cast<bool>(*__seg_ & __mask_);
66 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
67 return !static_cast<bool>(*this);
70 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(bool __x) _NOEXCEPT {
78 #if _LIBCPP_STD_VER >= 23
79 _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept {
88 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT {
89 return operator=(static_cast<bool>(__x));
92 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT { *__seg_ ^= __mask_; }
93 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT {
94 return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));
98 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_reference(
99 __storage_pointer __s, __storage_type __m) _NOEXCEPT
105 class __bit_reference<_Cp, false> {};
108 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
109 swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT {
115 template <class _Cp, class _Dp>
116 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
117 swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT {
124 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT {
131 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT {
138 class __bit_const_reference {
139 using __storage_type = typename _Cp::__storage_type;
140 using __storage_pointer = typename _Cp::__const_storage_pointer;
142 __storage_pointer __seg_;
143 __storage_type __mask_;
145 friend typename _Cp::__self;
146 friend class __bit_iterator<_Cp, true>;
149 using __container = typename _Cp::__self;
151 _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_const_reference&) = default;
153 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
154 : __seg_(__x.__seg_),
155 __mask_(__x.__mask_) {}
157 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT {
158 return static_cast<bool>(*__seg_ & __mask_);
161 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT {
162 return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));
166 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __bit_const_reference(
167 __storage_pointer __s, __storage_type __m) _NOEXCEPT
171 __bit_const_reference& operator=(const __bit_const_reference&) = delete;
176 template <bool _FillValue, class _Cp>
177 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
178 __fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) {
179 using _It = __bit_iterator<_Cp, false>;
180 using __storage_type = typename _It::__storage_type;
182 const int __bits_per_word = _It::__bits_per_word;
183 // do first partial word
184 if (__first.__ctz_ != 0) {
185 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
186 __storage_type __dn = std::min(__clz_f, __n);
187 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
189 *__first.__seg_ |= __m;
191 *__first.__seg_ &= ~__m;
195 // do middle whole words
196 __storage_type __nw = __n / __bits_per_word;
197 std::fill_n(std::__to_address(__first.__seg_), __nw, _FillValue ? static_cast<__storage_type>(-1) : 0);
198 __n -= __nw * __bits_per_word;
199 // do last partial word
201 __first.__seg_ += __nw;
202 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
204 *__first.__seg_ |= __m;
206 *__first.__seg_ &= ~__m;
211 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
212 fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value) {
215 std::__fill_n<true>(__first, __n);
217 std::__fill_n<false>(__first, __n);
224 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
225 fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value) {
226 std::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value);
231 template <class _Cp, bool _IsConst>
232 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned(
233 __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
234 using _In = __bit_iterator<_Cp, _IsConst>;
235 using difference_type = typename _In::difference_type;
236 using __storage_type = typename _In::__storage_type;
238 const int __bits_per_word = _In::__bits_per_word;
239 difference_type __n = __last - __first;
242 if (__first.__ctz_ != 0) {
243 unsigned __clz = __bits_per_word - __first.__ctz_;
244 difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
246 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
247 __storage_type __b = *__first.__seg_ & __m;
248 *__result.__seg_ &= ~__m;
249 *__result.__seg_ |= __b;
250 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
251 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
253 // __first.__ctz_ = 0;
255 // __first.__ctz_ == 0;
257 __storage_type __nw = __n / __bits_per_word;
258 std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_));
259 __n -= __nw * __bits_per_word;
260 __result.__seg_ += __nw;
263 __first.__seg_ += __nw;
264 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
265 __storage_type __b = *__first.__seg_ & __m;
266 *__result.__seg_ &= ~__m;
267 *__result.__seg_ |= __b;
268 __result.__ctz_ = static_cast<unsigned>(__n);
274 template <class _Cp, bool _IsConst>
275 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned(
276 __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
277 using _In = __bit_iterator<_Cp, _IsConst>;
278 using difference_type = typename _In::difference_type;
279 using __storage_type = typename _In::__storage_type;
281 const int __bits_per_word = _In::__bits_per_word;
282 difference_type __n = __last - __first;
285 if (__first.__ctz_ != 0) {
286 unsigned __clz_f = __bits_per_word - __first.__ctz_;
287 difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
289 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
290 __storage_type __b = *__first.__seg_ & __m;
291 unsigned __clz_r = __bits_per_word - __result.__ctz_;
292 __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
293 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
294 *__result.__seg_ &= ~__m;
295 if (__result.__ctz_ > __first.__ctz_)
296 *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
298 *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
299 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
300 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
303 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
304 *__result.__seg_ &= ~__m;
305 *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
306 __result.__ctz_ = static_cast<unsigned>(__dn);
309 // __first.__ctz_ = 0;
311 // __first.__ctz_ == 0;
313 unsigned __clz_r = __bits_per_word - __result.__ctz_;
314 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
315 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
316 __storage_type __b = *__first.__seg_;
317 *__result.__seg_ &= ~__m;
318 *__result.__seg_ |= __b << __result.__ctz_;
320 *__result.__seg_ &= __m;
321 *__result.__seg_ |= __b >> __clz_r;
325 __m = ~__storage_type(0) >> (__bits_per_word - __n);
326 __storage_type __b = *__first.__seg_ & __m;
327 __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
328 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
329 *__result.__seg_ &= ~__m;
330 *__result.__seg_ |= __b << __result.__ctz_;
331 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
332 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
335 __m = ~__storage_type(0) >> (__bits_per_word - __n);
336 *__result.__seg_ &= ~__m;
337 *__result.__seg_ |= __b >> __dn;
338 __result.__ctz_ = static_cast<unsigned>(__n);
345 template <class _Cp, bool _IsConst>
346 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false>
347 copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
348 if (__first.__ctz_ == __result.__ctz_)
349 return std::__copy_aligned(__first, __last, __result);
350 return std::__copy_unaligned(__first, __last, __result);
355 template <class _Cp, bool _IsConst>
356 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned(
357 __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
358 using _In = __bit_iterator<_Cp, _IsConst>;
359 using difference_type = typename _In::difference_type;
360 using __storage_type = typename _In::__storage_type;
362 const int __bits_per_word = _In::__bits_per_word;
363 difference_type __n = __last - __first;
366 if (__last.__ctz_ != 0) {
367 difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n);
369 unsigned __clz = __bits_per_word - __last.__ctz_;
370 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
371 __storage_type __b = *__last.__seg_ & __m;
372 *__result.__seg_ &= ~__m;
373 *__result.__seg_ |= __b;
374 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
377 // __last.__ctz_ == 0 || __n == 0
378 // __result.__ctz_ == 0 || __n == 0
380 __storage_type __nw = __n / __bits_per_word;
381 __result.__seg_ -= __nw;
382 __last.__seg_ -= __nw;
383 std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_));
384 __n -= __nw * __bits_per_word;
387 __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
388 __storage_type __b = *--__last.__seg_ & __m;
389 *--__result.__seg_ &= ~__m;
390 *__result.__seg_ |= __b;
391 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
397 template <class _Cp, bool _IsConst>
398 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned(
399 __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
400 using _In = __bit_iterator<_Cp, _IsConst>;
401 using difference_type = typename _In::difference_type;
402 using __storage_type = typename _In::__storage_type;
404 const int __bits_per_word = _In::__bits_per_word;
405 difference_type __n = __last - __first;
408 if (__last.__ctz_ != 0) {
409 difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n);
411 unsigned __clz_l = __bits_per_word - __last.__ctz_;
412 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
413 __storage_type __b = *__last.__seg_ & __m;
414 unsigned __clz_r = __bits_per_word - __result.__ctz_;
415 __storage_type __ddn = std::min(__dn, static_cast<difference_type>(__result.__ctz_));
417 __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
418 *__result.__seg_ &= ~__m;
419 if (__result.__ctz_ > __last.__ctz_)
420 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
422 *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
423 __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
427 // __result.__ctz_ == 0
429 __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
430 __m = ~__storage_type(0) << __result.__ctz_;
431 *__result.__seg_ &= ~__m;
432 __last.__ctz_ -= __dn + __ddn;
433 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
437 // __last.__ctz_ == 0 || __n == 0
438 // __result.__ctz_ != 0 || __n == 0
440 unsigned __clz_r = __bits_per_word - __result.__ctz_;
441 __storage_type __m = ~__storage_type(0) >> __clz_r;
442 for (; __n >= __bits_per_word; __n -= __bits_per_word) {
443 __storage_type __b = *--__last.__seg_;
444 *__result.__seg_ &= ~__m;
445 *__result.__seg_ |= __b >> __clz_r;
446 *--__result.__seg_ &= __m;
447 *__result.__seg_ |= __b << __result.__ctz_;
451 __m = ~__storage_type(0) << (__bits_per_word - __n);
452 __storage_type __b = *--__last.__seg_ & __m;
453 __clz_r = __bits_per_word - __result.__ctz_;
454 __storage_type __dn = std::min(__n, static_cast<difference_type>(__result.__ctz_));
455 __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
456 *__result.__seg_ &= ~__m;
457 *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
458 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
461 // __result.__ctz_ == 0
463 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
464 __m = ~__storage_type(0) << __result.__ctz_;
465 *__result.__seg_ &= ~__m;
466 *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
473 template <class _Cp, bool _IsConst>
474 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy_backward(
475 __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
476 if (__last.__ctz_ == __result.__ctz_)
477 return std::__copy_backward_aligned(__first, __last, __result);
478 return std::__copy_backward_unaligned(__first, __last, __result);
483 template <class _Cp, bool _IsConst>
484 inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
485 move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
486 return std::copy(__first, __last, __result);
491 template <class _Cp, bool _IsConst>
492 inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward(
493 __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
494 return std::copy_backward(__first, __last, __result);
499 template <class _Cl, class _Cr>
500 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned(
501 __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) {
502 using _I1 = __bit_iterator<_Cl, false>;
503 using difference_type = typename _I1::difference_type;
504 using __storage_type = typename _I1::__storage_type;
506 const int __bits_per_word = _I1::__bits_per_word;
507 difference_type __n = __last - __first;
510 if (__first.__ctz_ != 0) {
511 unsigned __clz = __bits_per_word - __first.__ctz_;
512 difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
514 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
515 __storage_type __b1 = *__first.__seg_ & __m;
516 *__first.__seg_ &= ~__m;
517 __storage_type __b2 = *__result.__seg_ & __m;
518 *__result.__seg_ &= ~__m;
519 *__result.__seg_ |= __b1;
520 *__first.__seg_ |= __b2;
521 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
522 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
524 // __first.__ctz_ = 0;
526 // __first.__ctz_ == 0;
528 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
529 swap(*__first.__seg_, *__result.__seg_);
532 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
533 __storage_type __b1 = *__first.__seg_ & __m;
534 *__first.__seg_ &= ~__m;
535 __storage_type __b2 = *__result.__seg_ & __m;
536 *__result.__seg_ &= ~__m;
537 *__result.__seg_ |= __b1;
538 *__first.__seg_ |= __b2;
539 __result.__ctz_ = static_cast<unsigned>(__n);
545 template <class _Cl, class _Cr>
546 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned(
547 __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) {
548 using _I1 = __bit_iterator<_Cl, false>;
549 using difference_type = typename _I1::difference_type;
550 using __storage_type = typename _I1::__storage_type;
552 const int __bits_per_word = _I1::__bits_per_word;
553 difference_type __n = __last - __first;
556 if (__first.__ctz_ != 0) {
557 unsigned __clz_f = __bits_per_word - __first.__ctz_;
558 difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
560 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
561 __storage_type __b1 = *__first.__seg_ & __m;
562 *__first.__seg_ &= ~__m;
563 unsigned __clz_r = __bits_per_word - __result.__ctz_;
564 __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
565 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
566 __storage_type __b2 = *__result.__seg_ & __m;
567 *__result.__seg_ &= ~__m;
568 if (__result.__ctz_ > __first.__ctz_) {
569 unsigned __s = __result.__ctz_ - __first.__ctz_;
570 *__result.__seg_ |= __b1 << __s;
571 *__first.__seg_ |= __b2 >> __s;
573 unsigned __s = __first.__ctz_ - __result.__ctz_;
574 *__result.__seg_ |= __b1 >> __s;
575 *__first.__seg_ |= __b2 << __s;
577 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
578 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
581 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
582 __b2 = *__result.__seg_ & __m;
583 *__result.__seg_ &= ~__m;
584 unsigned __s = __first.__ctz_ + __ddn;
585 *__result.__seg_ |= __b1 >> __s;
586 *__first.__seg_ |= __b2 << __s;
587 __result.__ctz_ = static_cast<unsigned>(__dn);
590 // __first.__ctz_ = 0;
592 // __first.__ctz_ == 0;
594 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
595 unsigned __clz_r = __bits_per_word - __result.__ctz_;
596 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
597 __storage_type __b1 = *__first.__seg_;
598 __storage_type __b2 = *__result.__seg_ & __m;
599 *__result.__seg_ &= ~__m;
600 *__result.__seg_ |= __b1 << __result.__ctz_;
601 *__first.__seg_ = __b2 >> __result.__ctz_;
603 __b2 = *__result.__seg_ & ~__m;
604 *__result.__seg_ &= __m;
605 *__result.__seg_ |= __b1 >> __clz_r;
606 *__first.__seg_ |= __b2 << __clz_r;
610 __m = ~__storage_type(0) >> (__bits_per_word - __n);
611 __storage_type __b1 = *__first.__seg_ & __m;
612 *__first.__seg_ &= ~__m;
613 __storage_type __dn = std::min<__storage_type>(__n, __clz_r);
614 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
615 __storage_type __b2 = *__result.__seg_ & __m;
616 *__result.__seg_ &= ~__m;
617 *__result.__seg_ |= __b1 << __result.__ctz_;
618 *__first.__seg_ |= __b2 >> __result.__ctz_;
619 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
620 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
623 __m = ~__storage_type(0) >> (__bits_per_word - __n);
624 __b2 = *__result.__seg_ & __m;
625 *__result.__seg_ &= ~__m;
626 *__result.__seg_ |= __b1 >> __dn;
627 *__first.__seg_ |= __b2 << __dn;
628 __result.__ctz_ = static_cast<unsigned>(__n);
635 template <class _Cl, class _Cr>
636 inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges(
637 __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) {
638 if (__first1.__ctz_ == __first2.__ctz_)
639 return std::__swap_ranges_aligned(__first1, __last1, __first2);
640 return std::__swap_ranges_unaligned(__first1, __last1, __first2);
647 using difference_type = typename _Cp::difference_type;
648 using __storage_type = typename _Cp::__storage_type;
649 using __storage_pointer = typename _Cp::__storage_pointer;
650 using iterator = typename _Cp::iterator;
652 static const unsigned __bits_per_word = _Cp::__bits_per_word;
653 static const unsigned _Np = 4;
655 difference_type __size_;
656 __storage_type __word_[_Np];
658 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() {
659 return static_cast<difference_type>(_Np * __bits_per_word);
661 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) {
662 if (__libcpp_is_constant_evaluated()) {
663 for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i)
664 std::__construct_at(__word_ + __i, 0);
667 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() {
668 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
670 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() {
671 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
672 static_cast<unsigned>(__size_ % __bits_per_word));
677 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
678 rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) {
679 using _I1 = __bit_iterator<_Cp, false>;
680 using difference_type = typename _I1::difference_type;
682 difference_type __d1 = __middle - __first;
683 difference_type __d2 = __last - __middle;
684 _I1 __r = __first + __d2;
685 while (__d1 != 0 && __d2 != 0) {
687 if (__d1 <= __bit_array<_Cp>::capacity()) {
688 __bit_array<_Cp> __b(__d1);
689 std::copy(__first, __middle, __b.begin());
690 std::copy(__b.begin(), __b.end(), std::copy(__middle, __last, __first));
693 __bit_iterator<_Cp, false> __mp = std::swap_ranges(__first, __middle, __middle);
699 if (__d2 <= __bit_array<_Cp>::capacity()) {
700 __bit_array<_Cp> __b(__d2);
701 std::copy(__middle, __last, __b.begin());
702 std::copy_backward(__b.begin(), __b.end(), std::copy_backward(__first, __middle, __last));
705 __bit_iterator<_Cp, false> __mp = __first + __d2;
706 std::swap_ranges(__first, __mp, __middle);
717 template <class _Cp, bool _IC1, bool _IC2>
718 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_unaligned(
719 __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
720 using _It = __bit_iterator<_Cp, _IC1>;
721 using difference_type = typename _It::difference_type;
722 using __storage_type = typename _It::__storage_type;
724 const int __bits_per_word = _It::__bits_per_word;
725 difference_type __n = __last1 - __first1;
728 if (__first1.__ctz_ != 0) {
729 unsigned __clz_f = __bits_per_word - __first1.__ctz_;
730 difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
732 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
733 __storage_type __b = *__first1.__seg_ & __m;
734 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
735 __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
736 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
737 if (__first2.__ctz_ > __first1.__ctz_) {
738 if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
741 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
744 __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
745 __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word);
748 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
749 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
751 __first2.__ctz_ = static_cast<unsigned>(__dn);
754 // __first1.__ctz_ = 0;
756 // __first1.__ctz_ == 0;
758 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
759 __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
760 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) {
761 __storage_type __b = *__first1.__seg_;
762 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
765 if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
770 __m = ~__storage_type(0) >> (__bits_per_word - __n);
771 __storage_type __b = *__first1.__seg_ & __m;
772 __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
773 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
774 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
776 __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
777 __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word);
780 __m = ~__storage_type(0) >> (__bits_per_word - __n);
781 if ((*__first2.__seg_ & __m) != (__b >> __dn))
789 template <class _Cp, bool _IC1, bool _IC2>
790 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_aligned(
791 __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
792 using _It = __bit_iterator<_Cp, _IC1>;
793 using difference_type = typename _It::difference_type;
794 using __storage_type = typename _It::__storage_type;
796 const int __bits_per_word = _It::__bits_per_word;
797 difference_type __n = __last1 - __first1;
800 if (__first1.__ctz_ != 0) {
801 unsigned __clz = __bits_per_word - __first1.__ctz_;
802 difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
804 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
805 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
809 // __first1.__ctz_ = 0;
810 // __first2.__ctz_ = 0;
812 // __first1.__ctz_ == 0;
813 // __first2.__ctz_ == 0;
815 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
816 if (*__first2.__seg_ != *__first1.__seg_)
820 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
821 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
828 template <class _Cp, bool _IC1, bool _IC2>
829 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
830 equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
831 if (__first1.__ctz_ == __first2.__ctz_)
832 return std::__equal_aligned(__first1, __last1, __first2);
833 return std::__equal_unaligned(__first1, __last1, __first2);
836 template <class _Cp, bool _IsConst, typename _Cp::__storage_type>
837 class __bit_iterator {
839 using difference_type = typename _Cp::difference_type;
840 using value_type = bool;
841 using pointer = __bit_iterator;
842 #ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
843 using reference = __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >;
845 using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >;
847 using iterator_category = random_access_iterator_tag;
850 using __storage_type = typename _Cp::__storage_type;
851 using __storage_pointer =
852 __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>;
854 static const unsigned __bits_per_word = _Cp::__bits_per_word;
856 __storage_pointer __seg_;
860 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT
861 #if _LIBCPP_STD_VER >= 14
868 // When _IsConst=false, this is the copy constructor.
869 // It is non-trivial. Making it trivial would break ABI.
870 // When _IsConst=true, this is a converting constructor;
871 // the copy and move constructors are implicitly generated
873 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
874 : __seg_(__it.__seg_),
875 __ctz_(__it.__ctz_) {}
877 // When _IsConst=false, we have a user-provided copy constructor,
878 // so we must also provide a copy assignment operator because
879 // the implicit generation of a defaulted one is deprecated.
880 // When _IsConst=true, the assignment operators are
881 // implicitly generated and trivial.
882 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator&
883 operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
884 __seg_ = __it.__seg_;
885 __ctz_ = __it.__ctz_;
889 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
890 return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >(
891 __seg_, __storage_type(1) << __ctz_);
894 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() {
895 if (__ctz_ != __bits_per_word - 1)
904 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) {
905 __bit_iterator __tmp = *this;
910 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() {
914 __ctz_ = __bits_per_word - 1;
920 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) {
921 __bit_iterator __tmp = *this;
926 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) {
928 __seg_ += (__n + __ctz_) / __bits_per_word;
930 __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) /
931 static_cast<difference_type>(__bits_per_word);
932 __n &= (__bits_per_word - 1);
933 __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word);
937 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) {
938 return *this += -__n;
941 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const {
942 __bit_iterator __t(*this);
947 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const {
948 __bit_iterator __t(*this);
953 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator
954 operator+(difference_type __n, const __bit_iterator& __it) {
958 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend difference_type
959 operator-(const __bit_iterator& __x, const __bit_iterator& __y) {
960 return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;
963 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const {
964 return *(*this + __n);
967 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
968 operator==(const __bit_iterator& __x, const __bit_iterator& __y) {
969 return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;
972 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
973 operator!=(const __bit_iterator& __x, const __bit_iterator& __y) {
974 return !(__x == __y);
977 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
978 operator<(const __bit_iterator& __x, const __bit_iterator& __y) {
979 return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);
982 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
983 operator>(const __bit_iterator& __x, const __bit_iterator& __y) {
987 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
988 operator<=(const __bit_iterator& __x, const __bit_iterator& __y) {
992 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
993 operator>=(const __bit_iterator& __x, const __bit_iterator& __y) {
998 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_iterator(
999 __storage_pointer __s, unsigned __ctz) _NOEXCEPT
1003 friend typename _Cp::__self;
1005 friend class __bit_reference<_Cp>;
1006 friend class __bit_const_reference<_Cp>;
1007 friend class __bit_iterator<_Cp, true>;
1008 template <class _Dp>
1009 friend struct __bit_array;
1010 template <bool _FillValue, class _Dp>
1011 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void __fill_n(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1013 template <class _Dp, bool _IC>
1014 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned(
1015 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
1016 template <class _Dp, bool _IC>
1017 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_unaligned(
1018 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
1019 template <class _Dp, bool _IC>
1020 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
1021 copy(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
1022 template <class _Dp, bool _IC>
1023 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned(
1024 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
1025 template <class _Dp, bool _IC>
1026 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_unaligned(
1027 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
1028 template <class _Dp, bool _IC>
1029 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
1030 copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
1031 template <class _Cl, class _Cr>
1032 friend __bit_iterator<_Cr, false>
1033 __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
1034 template <class _Cl, class _Cr>
1035 friend __bit_iterator<_Cr, false>
1036 __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
1037 template <class _Cl, class _Cr>
1038 friend __bit_iterator<_Cr, false>
1039 swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
1040 template <class _Dp>
1041 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
1042 rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>);
1043 template <class _Dp, bool _IC1, bool _IC2>
1044 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
1045 __equal_aligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
1046 template <class _Dp, bool _IC1, bool _IC2>
1047 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
1048 __equal_unaligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
1049 template <class _Dp, bool _IC1, bool _IC2>
1050 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
1051 equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
1052 template <bool _ToFind, class _Dp, bool _IC>
1053 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC>
1054 __find_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1055 template <bool _ToCount, class _Dp, bool _IC>
1056 friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1057 __count_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1060 _LIBCPP_END_NAMESPACE_STD
1064 #endif // _LIBCPP___BIT_REFERENCE