146035553Spatrick// -*- C++ -*- 246035553Spatrick//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick#ifndef _LIBCPP___BIT_REFERENCE 1146035553Spatrick#define _LIBCPP___BIT_REFERENCE 1246035553Spatrick 13*4bdff4beSrobert#include <__algorithm/copy_n.h> 14*4bdff4beSrobert#include <__algorithm/fill_n.h> 15*4bdff4beSrobert#include <__algorithm/min.h> 16*4bdff4beSrobert#include <__bit/countr.h> 17*4bdff4beSrobert#include <__bit/popcount.h> 1846035553Spatrick#include <__config> 19*4bdff4beSrobert#include <__iterator/iterator_traits.h> 20*4bdff4beSrobert#include <__memory/construct_at.h> 21*4bdff4beSrobert#include <__memory/pointer_traits.h> 22*4bdff4beSrobert#include <cstring> 23*4bdff4beSrobert#include <type_traits> 2446035553Spatrick 2546035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2646035553Spatrick# pragma GCC system_header 2746035553Spatrick#endif 2846035553Spatrick 2946035553Spatrick_LIBCPP_PUSH_MACROS 3046035553Spatrick#include <__undef_macros> 3146035553Spatrick 3246035553Spatrick 3346035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD 3446035553Spatrick 3546035553Spatricktemplate <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator; 3646035553Spatricktemplate <class _Cp> class __bit_const_reference; 3746035553Spatrick 3846035553Spatricktemplate <class _Tp> 3946035553Spatrickstruct __has_storage_type 4046035553Spatrick{ 4146035553Spatrick static const bool value = false; 4246035553Spatrick}; 4346035553Spatrick 4446035553Spatricktemplate <class _Cp, bool = __has_storage_type<_Cp>::value> 4546035553Spatrickclass __bit_reference 4646035553Spatrick{ 4746035553Spatrick typedef typename _Cp::__storage_type __storage_type; 4846035553Spatrick typedef typename _Cp::__storage_pointer __storage_pointer; 4946035553Spatrick 5046035553Spatrick __storage_pointer __seg_; 5146035553Spatrick __storage_type __mask_; 5246035553Spatrick 5346035553Spatrick friend typename _Cp::__self; 5446035553Spatrick 5546035553Spatrick friend class __bit_const_reference<_Cp>; 5646035553Spatrick friend class __bit_iterator<_Cp, false>; 5746035553Spatrickpublic: 58*4bdff4beSrobert using __container = typename _Cp::__self; 59*4bdff4beSrobert 60*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 6146035553Spatrick __bit_reference(const __bit_reference&) = default; 6246035553Spatrick 63*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT 6446035553Spatrick {return static_cast<bool>(*__seg_ & __mask_);} 65*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator ~() const _NOEXCEPT 6646035553Spatrick {return !static_cast<bool>(*this);} 6746035553Spatrick 68*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 6946035553Spatrick __bit_reference& operator=(bool __x) _NOEXCEPT 7046035553Spatrick { 7146035553Spatrick if (__x) 7246035553Spatrick *__seg_ |= __mask_; 7346035553Spatrick else 7446035553Spatrick *__seg_ &= ~__mask_; 7546035553Spatrick return *this; 7646035553Spatrick } 7746035553Spatrick 78*4bdff4beSrobert#if _LIBCPP_STD_VER > 20 79*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept { 80*4bdff4beSrobert if (__x) 81*4bdff4beSrobert *__seg_ |= __mask_; 82*4bdff4beSrobert else 83*4bdff4beSrobert *__seg_ &= ~__mask_; 84*4bdff4beSrobert return *this; 85*4bdff4beSrobert } 86*4bdff4beSrobert#endif 87*4bdff4beSrobert 88*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 8946035553Spatrick __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT 9046035553Spatrick {return operator=(static_cast<bool>(__x));} 9146035553Spatrick 92*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT {*__seg_ ^= __mask_;} 93*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT 94*4bdff4beSrobert {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));} 9546035553Spatrickprivate: 96*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 97*4bdff4beSrobert explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 9846035553Spatrick : __seg_(__s), __mask_(__m) {} 9946035553Spatrick}; 10046035553Spatrick 10146035553Spatricktemplate <class _Cp> 10246035553Spatrickclass __bit_reference<_Cp, false> 10346035553Spatrick{ 10446035553Spatrick}; 10546035553Spatrick 10646035553Spatricktemplate <class _Cp> 107*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 10846035553Spatrickvoid 10946035553Spatrickswap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT 11046035553Spatrick{ 11146035553Spatrick bool __t = __x; 11246035553Spatrick __x = __y; 11346035553Spatrick __y = __t; 11446035553Spatrick} 11546035553Spatrick 11646035553Spatricktemplate <class _Cp, class _Dp> 117*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 11846035553Spatrickvoid 11946035553Spatrickswap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT 12046035553Spatrick{ 12146035553Spatrick bool __t = __x; 12246035553Spatrick __x = __y; 12346035553Spatrick __y = __t; 12446035553Spatrick} 12546035553Spatrick 12646035553Spatricktemplate <class _Cp> 127*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 12846035553Spatrickvoid 12946035553Spatrickswap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT 13046035553Spatrick{ 13146035553Spatrick bool __t = __x; 13246035553Spatrick __x = __y; 13346035553Spatrick __y = __t; 13446035553Spatrick} 13546035553Spatrick 13646035553Spatricktemplate <class _Cp> 137*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 13846035553Spatrickvoid 13946035553Spatrickswap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT 14046035553Spatrick{ 14146035553Spatrick bool __t = __x; 14246035553Spatrick __x = __y; 14346035553Spatrick __y = __t; 14446035553Spatrick} 14546035553Spatrick 14646035553Spatricktemplate <class _Cp> 14746035553Spatrickclass __bit_const_reference 14846035553Spatrick{ 14946035553Spatrick typedef typename _Cp::__storage_type __storage_type; 15046035553Spatrick typedef typename _Cp::__const_storage_pointer __storage_pointer; 15146035553Spatrick 15246035553Spatrick __storage_pointer __seg_; 15346035553Spatrick __storage_type __mask_; 15446035553Spatrick 15546035553Spatrick friend typename _Cp::__self; 15646035553Spatrick friend class __bit_iterator<_Cp, true>; 15746035553Spatrickpublic: 15846035553Spatrick _LIBCPP_INLINE_VISIBILITY 15946035553Spatrick __bit_const_reference(const __bit_const_reference&) = default; 16046035553Spatrick 161*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 16246035553Spatrick __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT 16346035553Spatrick : __seg_(__x.__seg_), __mask_(__x.__mask_) {} 16446035553Spatrick 16546035553Spatrick _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT 16646035553Spatrick {return static_cast<bool>(*__seg_ & __mask_);} 16746035553Spatrick 168*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT 169*4bdff4beSrobert {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));} 17046035553Spatrickprivate: 17146035553Spatrick _LIBCPP_INLINE_VISIBILITY 17246035553Spatrick _LIBCPP_CONSTEXPR 173*4bdff4beSrobert explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 17446035553Spatrick : __seg_(__s), __mask_(__m) {} 17546035553Spatrick 17646035553Spatrick __bit_const_reference& operator=(const __bit_const_reference&) = delete; 17746035553Spatrick}; 17846035553Spatrick 17946035553Spatrick// find 18046035553Spatrick 18146035553Spatricktemplate <class _Cp, bool _IsConst> 182*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> 18346035553Spatrick__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) 18446035553Spatrick{ 18546035553Spatrick typedef __bit_iterator<_Cp, _IsConst> _It; 18646035553Spatrick typedef typename _It::__storage_type __storage_type; 187*4bdff4beSrobert const int __bits_per_word = _It::__bits_per_word; 18846035553Spatrick // do first partial word 18946035553Spatrick if (__first.__ctz_ != 0) 19046035553Spatrick { 19146035553Spatrick __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 19246035553Spatrick __storage_type __dn = _VSTD::min(__clz_f, __n); 19346035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 19446035553Spatrick __storage_type __b = *__first.__seg_ & __m; 19546035553Spatrick if (__b) 19646035553Spatrick return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b))); 19746035553Spatrick if (__n == __dn) 19846035553Spatrick return __first + __n; 19946035553Spatrick __n -= __dn; 20046035553Spatrick ++__first.__seg_; 20146035553Spatrick } 20246035553Spatrick // do middle whole words 20346035553Spatrick for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 20446035553Spatrick if (*__first.__seg_) 20546035553Spatrick return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(*__first.__seg_))); 20646035553Spatrick // do last partial word 20746035553Spatrick if (__n > 0) 20846035553Spatrick { 20946035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 21046035553Spatrick __storage_type __b = *__first.__seg_ & __m; 21146035553Spatrick if (__b) 21246035553Spatrick return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b))); 21346035553Spatrick } 21446035553Spatrick return _It(__first.__seg_, static_cast<unsigned>(__n)); 21546035553Spatrick} 21646035553Spatrick 21746035553Spatricktemplate <class _Cp, bool _IsConst> 218*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> 21946035553Spatrick__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) 22046035553Spatrick{ 22146035553Spatrick typedef __bit_iterator<_Cp, _IsConst> _It; 22246035553Spatrick typedef typename _It::__storage_type __storage_type; 22346035553Spatrick const int __bits_per_word = _It::__bits_per_word; 22446035553Spatrick // do first partial word 22546035553Spatrick if (__first.__ctz_ != 0) 22646035553Spatrick { 22746035553Spatrick __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 22846035553Spatrick __storage_type __dn = _VSTD::min(__clz_f, __n); 22946035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 23046035553Spatrick __storage_type __b = ~*__first.__seg_ & __m; 23146035553Spatrick if (__b) 23246035553Spatrick return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b))); 23346035553Spatrick if (__n == __dn) 23446035553Spatrick return __first + __n; 23546035553Spatrick __n -= __dn; 23646035553Spatrick ++__first.__seg_; 23746035553Spatrick } 23846035553Spatrick // do middle whole words 23946035553Spatrick for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 24046035553Spatrick { 24146035553Spatrick __storage_type __b = ~*__first.__seg_; 24246035553Spatrick if (__b) 24346035553Spatrick return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b))); 24446035553Spatrick } 24546035553Spatrick // do last partial word 24646035553Spatrick if (__n > 0) 24746035553Spatrick { 24846035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 24946035553Spatrick __storage_type __b = ~*__first.__seg_ & __m; 25046035553Spatrick if (__b) 25146035553Spatrick return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b))); 25246035553Spatrick } 25346035553Spatrick return _It(__first.__seg_, static_cast<unsigned>(__n)); 25446035553Spatrick} 25546035553Spatrick 25646035553Spatricktemplate <class _Cp, bool _IsConst, class _Tp> 257*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 25846035553Spatrick__bit_iterator<_Cp, _IsConst> 259*4bdff4beSrobertfind(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) 26046035553Spatrick{ 261*4bdff4beSrobert if (static_cast<bool>(__value)) 26276d0caaeSpatrick return _VSTD::__find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first)); 26376d0caaeSpatrick return _VSTD::__find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first)); 26446035553Spatrick} 26546035553Spatrick 26646035553Spatrick// count 26746035553Spatrick 26846035553Spatricktemplate <class _Cp, bool _IsConst> 269*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __bit_iterator<_Cp, _IsConst>::difference_type 27046035553Spatrick__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) 27146035553Spatrick{ 27246035553Spatrick typedef __bit_iterator<_Cp, _IsConst> _It; 27346035553Spatrick typedef typename _It::__storage_type __storage_type; 27446035553Spatrick typedef typename _It::difference_type difference_type; 27546035553Spatrick const int __bits_per_word = _It::__bits_per_word; 27646035553Spatrick difference_type __r = 0; 27746035553Spatrick // do first partial word 27846035553Spatrick if (__first.__ctz_ != 0) 27946035553Spatrick { 28046035553Spatrick __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 28146035553Spatrick __storage_type __dn = _VSTD::min(__clz_f, __n); 28246035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 28346035553Spatrick __r = _VSTD::__libcpp_popcount(*__first.__seg_ & __m); 28446035553Spatrick __n -= __dn; 28546035553Spatrick ++__first.__seg_; 28646035553Spatrick } 28746035553Spatrick // do middle whole words 28846035553Spatrick for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 28946035553Spatrick __r += _VSTD::__libcpp_popcount(*__first.__seg_); 29046035553Spatrick // do last partial word 29146035553Spatrick if (__n > 0) 29246035553Spatrick { 29346035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 29446035553Spatrick __r += _VSTD::__libcpp_popcount(*__first.__seg_ & __m); 29546035553Spatrick } 29646035553Spatrick return __r; 29746035553Spatrick} 29846035553Spatrick 29946035553Spatricktemplate <class _Cp, bool _IsConst> 300*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI typename __bit_iterator<_Cp, _IsConst>::difference_type 30146035553Spatrick__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) 30246035553Spatrick{ 30346035553Spatrick typedef __bit_iterator<_Cp, _IsConst> _It; 30446035553Spatrick typedef typename _It::__storage_type __storage_type; 30546035553Spatrick typedef typename _It::difference_type difference_type; 30646035553Spatrick const int __bits_per_word = _It::__bits_per_word; 30746035553Spatrick difference_type __r = 0; 30846035553Spatrick // do first partial word 30946035553Spatrick if (__first.__ctz_ != 0) 31046035553Spatrick { 31146035553Spatrick __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 31246035553Spatrick __storage_type __dn = _VSTD::min(__clz_f, __n); 31346035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 31446035553Spatrick __r = _VSTD::__libcpp_popcount(~*__first.__seg_ & __m); 31546035553Spatrick __n -= __dn; 31646035553Spatrick ++__first.__seg_; 31746035553Spatrick } 31846035553Spatrick // do middle whole words 31946035553Spatrick for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) 32046035553Spatrick __r += _VSTD::__libcpp_popcount(~*__first.__seg_); 32146035553Spatrick // do last partial word 32246035553Spatrick if (__n > 0) 32346035553Spatrick { 32446035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 32546035553Spatrick __r += _VSTD::__libcpp_popcount(~*__first.__seg_ & __m); 32646035553Spatrick } 32746035553Spatrick return __r; 32846035553Spatrick} 32946035553Spatrick 33046035553Spatricktemplate <class _Cp, bool _IsConst, class _Tp> 33146035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 33246035553Spatricktypename __bit_iterator<_Cp, _IsConst>::difference_type 333*4bdff4beSrobertcount(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) 33446035553Spatrick{ 335*4bdff4beSrobert if (static_cast<bool>(__value)) 33676d0caaeSpatrick return _VSTD::__count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first)); 33776d0caaeSpatrick return _VSTD::__count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first)); 33846035553Spatrick} 33946035553Spatrick 34046035553Spatrick// fill_n 34146035553Spatrick 34246035553Spatricktemplate <class _Cp> 343*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 34446035553Spatrick__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) 34546035553Spatrick{ 34646035553Spatrick typedef __bit_iterator<_Cp, false> _It; 34746035553Spatrick typedef typename _It::__storage_type __storage_type; 34846035553Spatrick const int __bits_per_word = _It::__bits_per_word; 34946035553Spatrick // do first partial word 35046035553Spatrick if (__first.__ctz_ != 0) 35146035553Spatrick { 35246035553Spatrick __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 35346035553Spatrick __storage_type __dn = _VSTD::min(__clz_f, __n); 35446035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 35546035553Spatrick *__first.__seg_ &= ~__m; 35646035553Spatrick __n -= __dn; 35746035553Spatrick ++__first.__seg_; 35846035553Spatrick } 35946035553Spatrick // do middle whole words 36046035553Spatrick __storage_type __nw = __n / __bits_per_word; 361*4bdff4beSrobert std::fill_n(std::__to_address(__first.__seg_), __nw, 0); 36246035553Spatrick __n -= __nw * __bits_per_word; 36346035553Spatrick // do last partial word 36446035553Spatrick if (__n > 0) 36546035553Spatrick { 36646035553Spatrick __first.__seg_ += __nw; 36746035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 36846035553Spatrick *__first.__seg_ &= ~__m; 36946035553Spatrick } 37046035553Spatrick} 37146035553Spatrick 37246035553Spatricktemplate <class _Cp> 373*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void 37446035553Spatrick__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) 37546035553Spatrick{ 37646035553Spatrick typedef __bit_iterator<_Cp, false> _It; 37746035553Spatrick typedef typename _It::__storage_type __storage_type; 37846035553Spatrick const int __bits_per_word = _It::__bits_per_word; 37946035553Spatrick // do first partial word 38046035553Spatrick if (__first.__ctz_ != 0) 38146035553Spatrick { 38246035553Spatrick __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); 38346035553Spatrick __storage_type __dn = _VSTD::min(__clz_f, __n); 38446035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 38546035553Spatrick *__first.__seg_ |= __m; 38646035553Spatrick __n -= __dn; 38746035553Spatrick ++__first.__seg_; 38846035553Spatrick } 38946035553Spatrick // do middle whole words 39046035553Spatrick __storage_type __nw = __n / __bits_per_word; 391*4bdff4beSrobert // __storage_type is always an unsigned type, so -1 sets all bits 392*4bdff4beSrobert std::fill_n(std::__to_address(__first.__seg_), __nw, static_cast<__storage_type>(-1)); 39346035553Spatrick __n -= __nw * __bits_per_word; 39446035553Spatrick // do last partial word 39546035553Spatrick if (__n > 0) 39646035553Spatrick { 39746035553Spatrick __first.__seg_ += __nw; 39846035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 39946035553Spatrick *__first.__seg_ |= __m; 40046035553Spatrick } 40146035553Spatrick} 40246035553Spatrick 40346035553Spatricktemplate <class _Cp> 404*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 40546035553Spatrickvoid 406*4bdff4beSrobertfill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value) 40746035553Spatrick{ 40846035553Spatrick if (__n > 0) 40946035553Spatrick { 410*4bdff4beSrobert if (__value) 41176d0caaeSpatrick _VSTD::__fill_n_true(__first, __n); 41246035553Spatrick else 41376d0caaeSpatrick _VSTD::__fill_n_false(__first, __n); 41446035553Spatrick } 41546035553Spatrick} 41646035553Spatrick 41746035553Spatrick// fill 41846035553Spatrick 41946035553Spatricktemplate <class _Cp> 420*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 42146035553Spatrickvoid 422*4bdff4beSrobertfill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value) 42346035553Spatrick{ 424*4bdff4beSrobert _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value); 42546035553Spatrick} 42646035553Spatrick 42746035553Spatrick// copy 42846035553Spatrick 42946035553Spatricktemplate <class _Cp, bool _IsConst> 430*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> 43146035553Spatrick__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, 43246035553Spatrick __bit_iterator<_Cp, false> __result) 43346035553Spatrick{ 43446035553Spatrick typedef __bit_iterator<_Cp, _IsConst> _In; 43546035553Spatrick typedef typename _In::difference_type difference_type; 43646035553Spatrick typedef typename _In::__storage_type __storage_type; 43746035553Spatrick const int __bits_per_word = _In::__bits_per_word; 43846035553Spatrick difference_type __n = __last - __first; 43946035553Spatrick if (__n > 0) 44046035553Spatrick { 44146035553Spatrick // do first word 44246035553Spatrick if (__first.__ctz_ != 0) 44346035553Spatrick { 44446035553Spatrick unsigned __clz = __bits_per_word - __first.__ctz_; 44546035553Spatrick difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 44646035553Spatrick __n -= __dn; 44746035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 44846035553Spatrick __storage_type __b = *__first.__seg_ & __m; 44946035553Spatrick *__result.__seg_ &= ~__m; 45046035553Spatrick *__result.__seg_ |= __b; 45146035553Spatrick __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 45246035553Spatrick __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 45346035553Spatrick ++__first.__seg_; 45446035553Spatrick // __first.__ctz_ = 0; 45546035553Spatrick } 45646035553Spatrick // __first.__ctz_ == 0; 45746035553Spatrick // do middle words 45846035553Spatrick __storage_type __nw = __n / __bits_per_word; 459*4bdff4beSrobert std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_)); 46046035553Spatrick __n -= __nw * __bits_per_word; 46146035553Spatrick __result.__seg_ += __nw; 46246035553Spatrick // do last word 46346035553Spatrick if (__n > 0) 46446035553Spatrick { 46546035553Spatrick __first.__seg_ += __nw; 46646035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 46746035553Spatrick __storage_type __b = *__first.__seg_ & __m; 46846035553Spatrick *__result.__seg_ &= ~__m; 46946035553Spatrick *__result.__seg_ |= __b; 47046035553Spatrick __result.__ctz_ = static_cast<unsigned>(__n); 47146035553Spatrick } 47246035553Spatrick } 47346035553Spatrick return __result; 47446035553Spatrick} 47546035553Spatrick 47646035553Spatricktemplate <class _Cp, bool _IsConst> 477*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> 47846035553Spatrick__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, 47946035553Spatrick __bit_iterator<_Cp, false> __result) 48046035553Spatrick{ 48146035553Spatrick typedef __bit_iterator<_Cp, _IsConst> _In; 48246035553Spatrick typedef typename _In::difference_type difference_type; 48346035553Spatrick typedef typename _In::__storage_type __storage_type; 484*4bdff4beSrobert const int __bits_per_word = _In::__bits_per_word; 48546035553Spatrick difference_type __n = __last - __first; 48646035553Spatrick if (__n > 0) 48746035553Spatrick { 48846035553Spatrick // do first word 48946035553Spatrick if (__first.__ctz_ != 0) 49046035553Spatrick { 49146035553Spatrick unsigned __clz_f = __bits_per_word - __first.__ctz_; 49246035553Spatrick difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 49346035553Spatrick __n -= __dn; 49446035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 49546035553Spatrick __storage_type __b = *__first.__seg_ & __m; 49646035553Spatrick unsigned __clz_r = __bits_per_word - __result.__ctz_; 49746035553Spatrick __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 49846035553Spatrick __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 49946035553Spatrick *__result.__seg_ &= ~__m; 50046035553Spatrick if (__result.__ctz_ > __first.__ctz_) 50146035553Spatrick *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); 50246035553Spatrick else 50346035553Spatrick *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); 50446035553Spatrick __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; 50546035553Spatrick __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); 50646035553Spatrick __dn -= __ddn; 50746035553Spatrick if (__dn > 0) 50846035553Spatrick { 50946035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __dn); 51046035553Spatrick *__result.__seg_ &= ~__m; 51146035553Spatrick *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); 51246035553Spatrick __result.__ctz_ = static_cast<unsigned>(__dn); 51346035553Spatrick } 51446035553Spatrick ++__first.__seg_; 51546035553Spatrick // __first.__ctz_ = 0; 51646035553Spatrick } 51746035553Spatrick // __first.__ctz_ == 0; 51846035553Spatrick // do middle words 51946035553Spatrick unsigned __clz_r = __bits_per_word - __result.__ctz_; 52046035553Spatrick __storage_type __m = ~__storage_type(0) << __result.__ctz_; 52146035553Spatrick for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) 52246035553Spatrick { 52346035553Spatrick __storage_type __b = *__first.__seg_; 52446035553Spatrick *__result.__seg_ &= ~__m; 52546035553Spatrick *__result.__seg_ |= __b << __result.__ctz_; 52646035553Spatrick ++__result.__seg_; 52746035553Spatrick *__result.__seg_ &= __m; 52846035553Spatrick *__result.__seg_ |= __b >> __clz_r; 52946035553Spatrick } 53046035553Spatrick // do last word 53146035553Spatrick if (__n > 0) 53246035553Spatrick { 53346035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __n); 53446035553Spatrick __storage_type __b = *__first.__seg_ & __m; 53546035553Spatrick __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r)); 53646035553Spatrick __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 53746035553Spatrick *__result.__seg_ &= ~__m; 53846035553Spatrick *__result.__seg_ |= __b << __result.__ctz_; 53946035553Spatrick __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 54046035553Spatrick __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 54146035553Spatrick __n -= __dn; 54246035553Spatrick if (__n > 0) 54346035553Spatrick { 54446035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __n); 54546035553Spatrick *__result.__seg_ &= ~__m; 54646035553Spatrick *__result.__seg_ |= __b >> __dn; 54746035553Spatrick __result.__ctz_ = static_cast<unsigned>(__n); 54846035553Spatrick } 54946035553Spatrick } 55046035553Spatrick } 55146035553Spatrick return __result; 55246035553Spatrick} 55346035553Spatrick 55446035553Spatricktemplate <class _Cp, bool _IsConst> 555*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 55646035553Spatrick__bit_iterator<_Cp, false> 55746035553Spatrickcopy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) 55846035553Spatrick{ 55946035553Spatrick if (__first.__ctz_ == __result.__ctz_) 56076d0caaeSpatrick return _VSTD::__copy_aligned(__first, __last, __result); 56176d0caaeSpatrick return _VSTD::__copy_unaligned(__first, __last, __result); 56246035553Spatrick} 56346035553Spatrick 56446035553Spatrick// copy_backward 56546035553Spatrick 56646035553Spatricktemplate <class _Cp, bool _IsConst> 567*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> 56846035553Spatrick__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, 56946035553Spatrick __bit_iterator<_Cp, false> __result) 57046035553Spatrick{ 57146035553Spatrick typedef __bit_iterator<_Cp, _IsConst> _In; 57246035553Spatrick typedef typename _In::difference_type difference_type; 57346035553Spatrick typedef typename _In::__storage_type __storage_type; 57446035553Spatrick const int __bits_per_word = _In::__bits_per_word; 57546035553Spatrick difference_type __n = __last - __first; 57646035553Spatrick if (__n > 0) 57746035553Spatrick { 57846035553Spatrick // do first word 57946035553Spatrick if (__last.__ctz_ != 0) 58046035553Spatrick { 58146035553Spatrick difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n); 58246035553Spatrick __n -= __dn; 58346035553Spatrick unsigned __clz = __bits_per_word - __last.__ctz_; 58446035553Spatrick __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); 58546035553Spatrick __storage_type __b = *__last.__seg_ & __m; 58646035553Spatrick *__result.__seg_ &= ~__m; 58746035553Spatrick *__result.__seg_ |= __b; 58846035553Spatrick __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + 58946035553Spatrick __result.__ctz_) % __bits_per_word); 59046035553Spatrick // __last.__ctz_ = 0 59146035553Spatrick } 59246035553Spatrick // __last.__ctz_ == 0 || __n == 0 59346035553Spatrick // __result.__ctz_ == 0 || __n == 0 59446035553Spatrick // do middle words 59546035553Spatrick __storage_type __nw = __n / __bits_per_word; 59646035553Spatrick __result.__seg_ -= __nw; 59746035553Spatrick __last.__seg_ -= __nw; 598*4bdff4beSrobert std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_)); 59946035553Spatrick __n -= __nw * __bits_per_word; 60046035553Spatrick // do last word 60146035553Spatrick if (__n > 0) 60246035553Spatrick { 60346035553Spatrick __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); 60446035553Spatrick __storage_type __b = *--__last.__seg_ & __m; 60546035553Spatrick *--__result.__seg_ &= ~__m; 60646035553Spatrick *__result.__seg_ |= __b; 60746035553Spatrick __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); 60846035553Spatrick } 60946035553Spatrick } 61046035553Spatrick return __result; 61146035553Spatrick} 61246035553Spatrick 61346035553Spatricktemplate <class _Cp, bool _IsConst> 614*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> 61546035553Spatrick__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, 61646035553Spatrick __bit_iterator<_Cp, false> __result) 61746035553Spatrick{ 61846035553Spatrick typedef __bit_iterator<_Cp, _IsConst> _In; 61946035553Spatrick typedef typename _In::difference_type difference_type; 62046035553Spatrick typedef typename _In::__storage_type __storage_type; 62146035553Spatrick const int __bits_per_word = _In::__bits_per_word; 62246035553Spatrick difference_type __n = __last - __first; 62346035553Spatrick if (__n > 0) 62446035553Spatrick { 62546035553Spatrick // do first word 62646035553Spatrick if (__last.__ctz_ != 0) 62746035553Spatrick { 62846035553Spatrick difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n); 62946035553Spatrick __n -= __dn; 63046035553Spatrick unsigned __clz_l = __bits_per_word - __last.__ctz_; 63146035553Spatrick __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); 63246035553Spatrick __storage_type __b = *__last.__seg_ & __m; 63346035553Spatrick unsigned __clz_r = __bits_per_word - __result.__ctz_; 63446035553Spatrick __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_)); 63546035553Spatrick if (__ddn > 0) 63646035553Spatrick { 63746035553Spatrick __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); 63846035553Spatrick *__result.__seg_ &= ~__m; 63946035553Spatrick if (__result.__ctz_ > __last.__ctz_) 64046035553Spatrick *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); 64146035553Spatrick else 64246035553Spatrick *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); 64346035553Spatrick __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + 64446035553Spatrick __result.__ctz_) % __bits_per_word); 64546035553Spatrick __dn -= __ddn; 64646035553Spatrick } 64746035553Spatrick if (__dn > 0) 64846035553Spatrick { 64946035553Spatrick // __result.__ctz_ == 0 65046035553Spatrick --__result.__seg_; 65146035553Spatrick __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1)); 65246035553Spatrick __m = ~__storage_type(0) << __result.__ctz_; 65346035553Spatrick *__result.__seg_ &= ~__m; 65446035553Spatrick __last.__ctz_ -= __dn + __ddn; 65546035553Spatrick *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); 65646035553Spatrick } 65746035553Spatrick // __last.__ctz_ = 0 65846035553Spatrick } 65946035553Spatrick // __last.__ctz_ == 0 || __n == 0 66046035553Spatrick // __result.__ctz_ != 0 || __n == 0 66146035553Spatrick // do middle words 66246035553Spatrick unsigned __clz_r = __bits_per_word - __result.__ctz_; 66346035553Spatrick __storage_type __m = ~__storage_type(0) >> __clz_r; 66446035553Spatrick for (; __n >= __bits_per_word; __n -= __bits_per_word) 66546035553Spatrick { 66646035553Spatrick __storage_type __b = *--__last.__seg_; 66746035553Spatrick *__result.__seg_ &= ~__m; 66846035553Spatrick *__result.__seg_ |= __b >> __clz_r; 66946035553Spatrick *--__result.__seg_ &= __m; 67046035553Spatrick *__result.__seg_ |= __b << __result.__ctz_; 67146035553Spatrick } 67246035553Spatrick // do last word 67346035553Spatrick if (__n > 0) 67446035553Spatrick { 67546035553Spatrick __m = ~__storage_type(0) << (__bits_per_word - __n); 67646035553Spatrick __storage_type __b = *--__last.__seg_ & __m; 67746035553Spatrick __clz_r = __bits_per_word - __result.__ctz_; 67846035553Spatrick __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_)); 67946035553Spatrick __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); 68046035553Spatrick *__result.__seg_ &= ~__m; 68146035553Spatrick *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); 68246035553Spatrick __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + 68346035553Spatrick __result.__ctz_) % __bits_per_word); 68446035553Spatrick __n -= __dn; 68546035553Spatrick if (__n > 0) 68646035553Spatrick { 68746035553Spatrick // __result.__ctz_ == 0 68846035553Spatrick --__result.__seg_; 68946035553Spatrick __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); 69046035553Spatrick __m = ~__storage_type(0) << __result.__ctz_; 69146035553Spatrick *__result.__seg_ &= ~__m; 69246035553Spatrick *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); 69346035553Spatrick } 69446035553Spatrick } 69546035553Spatrick } 69646035553Spatrick return __result; 69746035553Spatrick} 69846035553Spatrick 69946035553Spatricktemplate <class _Cp, bool _IsConst> 700*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 70146035553Spatrick__bit_iterator<_Cp, false> 70246035553Spatrickcopy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) 70346035553Spatrick{ 70446035553Spatrick if (__last.__ctz_ == __result.__ctz_) 70576d0caaeSpatrick return _VSTD::__copy_backward_aligned(__first, __last, __result); 70676d0caaeSpatrick return _VSTD::__copy_backward_unaligned(__first, __last, __result); 70746035553Spatrick} 70846035553Spatrick 70946035553Spatrick// move 71046035553Spatrick 71146035553Spatricktemplate <class _Cp, bool _IsConst> 71246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 71346035553Spatrick__bit_iterator<_Cp, false> 71446035553Spatrickmove(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) 71546035553Spatrick{ 71646035553Spatrick return _VSTD::copy(__first, __last, __result); 71746035553Spatrick} 71846035553Spatrick 71946035553Spatrick// move_backward 72046035553Spatrick 72146035553Spatricktemplate <class _Cp, bool _IsConst> 72246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 72346035553Spatrick__bit_iterator<_Cp, false> 72446035553Spatrickmove_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) 72546035553Spatrick{ 72646035553Spatrick return _VSTD::copy_backward(__first, __last, __result); 72746035553Spatrick} 72846035553Spatrick 72946035553Spatrick// swap_ranges 73046035553Spatrick 73146035553Spatricktemplate <class __C1, class __C2> 732*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> 73346035553Spatrick__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, 73446035553Spatrick __bit_iterator<__C2, false> __result) 73546035553Spatrick{ 73646035553Spatrick typedef __bit_iterator<__C1, false> _I1; 73746035553Spatrick typedef typename _I1::difference_type difference_type; 73846035553Spatrick typedef typename _I1::__storage_type __storage_type; 73946035553Spatrick const int __bits_per_word = _I1::__bits_per_word; 74046035553Spatrick difference_type __n = __last - __first; 74146035553Spatrick if (__n > 0) 74246035553Spatrick { 74346035553Spatrick // do first word 74446035553Spatrick if (__first.__ctz_ != 0) 74546035553Spatrick { 74646035553Spatrick unsigned __clz = __bits_per_word - __first.__ctz_; 74746035553Spatrick difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 74846035553Spatrick __n -= __dn; 74946035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 75046035553Spatrick __storage_type __b1 = *__first.__seg_ & __m; 75146035553Spatrick *__first.__seg_ &= ~__m; 75246035553Spatrick __storage_type __b2 = *__result.__seg_ & __m; 75346035553Spatrick *__result.__seg_ &= ~__m; 75446035553Spatrick *__result.__seg_ |= __b1; 75546035553Spatrick *__first.__seg_ |= __b2; 75646035553Spatrick __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 75746035553Spatrick __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 75846035553Spatrick ++__first.__seg_; 75946035553Spatrick // __first.__ctz_ = 0; 76046035553Spatrick } 76146035553Spatrick // __first.__ctz_ == 0; 76246035553Spatrick // do middle words 76346035553Spatrick for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) 76446035553Spatrick swap(*__first.__seg_, *__result.__seg_); 76546035553Spatrick // do last word 76646035553Spatrick if (__n > 0) 76746035553Spatrick { 76846035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 76946035553Spatrick __storage_type __b1 = *__first.__seg_ & __m; 77046035553Spatrick *__first.__seg_ &= ~__m; 77146035553Spatrick __storage_type __b2 = *__result.__seg_ & __m; 77246035553Spatrick *__result.__seg_ &= ~__m; 77346035553Spatrick *__result.__seg_ |= __b1; 77446035553Spatrick *__first.__seg_ |= __b2; 77546035553Spatrick __result.__ctz_ = static_cast<unsigned>(__n); 77646035553Spatrick } 77746035553Spatrick } 77846035553Spatrick return __result; 77946035553Spatrick} 78046035553Spatrick 78146035553Spatricktemplate <class __C1, class __C2> 782*4bdff4beSrobert_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> 78346035553Spatrick__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, 78446035553Spatrick __bit_iterator<__C2, false> __result) 78546035553Spatrick{ 78646035553Spatrick typedef __bit_iterator<__C1, false> _I1; 78746035553Spatrick typedef typename _I1::difference_type difference_type; 78846035553Spatrick typedef typename _I1::__storage_type __storage_type; 78946035553Spatrick const int __bits_per_word = _I1::__bits_per_word; 79046035553Spatrick difference_type __n = __last - __first; 79146035553Spatrick if (__n > 0) 79246035553Spatrick { 79346035553Spatrick // do first word 79446035553Spatrick if (__first.__ctz_ != 0) 79546035553Spatrick { 79646035553Spatrick unsigned __clz_f = __bits_per_word - __first.__ctz_; 79746035553Spatrick difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 79846035553Spatrick __n -= __dn; 79946035553Spatrick __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 80046035553Spatrick __storage_type __b1 = *__first.__seg_ & __m; 80146035553Spatrick *__first.__seg_ &= ~__m; 80246035553Spatrick unsigned __clz_r = __bits_per_word - __result.__ctz_; 80346035553Spatrick __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 80446035553Spatrick __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 80546035553Spatrick __storage_type __b2 = *__result.__seg_ & __m; 80646035553Spatrick *__result.__seg_ &= ~__m; 80746035553Spatrick if (__result.__ctz_ > __first.__ctz_) 80846035553Spatrick { 80946035553Spatrick unsigned __s = __result.__ctz_ - __first.__ctz_; 81046035553Spatrick *__result.__seg_ |= __b1 << __s; 81146035553Spatrick *__first.__seg_ |= __b2 >> __s; 81246035553Spatrick } 81346035553Spatrick else 81446035553Spatrick { 81546035553Spatrick unsigned __s = __first.__ctz_ - __result.__ctz_; 81646035553Spatrick *__result.__seg_ |= __b1 >> __s; 81746035553Spatrick *__first.__seg_ |= __b2 << __s; 81846035553Spatrick } 81946035553Spatrick __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; 82046035553Spatrick __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); 82146035553Spatrick __dn -= __ddn; 82246035553Spatrick if (__dn > 0) 82346035553Spatrick { 82446035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __dn); 82546035553Spatrick __b2 = *__result.__seg_ & __m; 82646035553Spatrick *__result.__seg_ &= ~__m; 82746035553Spatrick unsigned __s = __first.__ctz_ + __ddn; 82846035553Spatrick *__result.__seg_ |= __b1 >> __s; 82946035553Spatrick *__first.__seg_ |= __b2 << __s; 83046035553Spatrick __result.__ctz_ = static_cast<unsigned>(__dn); 83146035553Spatrick } 83246035553Spatrick ++__first.__seg_; 83346035553Spatrick // __first.__ctz_ = 0; 83446035553Spatrick } 83546035553Spatrick // __first.__ctz_ == 0; 83646035553Spatrick // do middle words 83746035553Spatrick __storage_type __m = ~__storage_type(0) << __result.__ctz_; 83846035553Spatrick unsigned __clz_r = __bits_per_word - __result.__ctz_; 83946035553Spatrick for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) 84046035553Spatrick { 84146035553Spatrick __storage_type __b1 = *__first.__seg_; 84246035553Spatrick __storage_type __b2 = *__result.__seg_ & __m; 84346035553Spatrick *__result.__seg_ &= ~__m; 84446035553Spatrick *__result.__seg_ |= __b1 << __result.__ctz_; 84546035553Spatrick *__first.__seg_ = __b2 >> __result.__ctz_; 84646035553Spatrick ++__result.__seg_; 84746035553Spatrick __b2 = *__result.__seg_ & ~__m; 84846035553Spatrick *__result.__seg_ &= __m; 84946035553Spatrick *__result.__seg_ |= __b1 >> __clz_r; 85046035553Spatrick *__first.__seg_ |= __b2 << __clz_r; 85146035553Spatrick } 85246035553Spatrick // do last word 85346035553Spatrick if (__n > 0) 85446035553Spatrick { 85546035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __n); 85646035553Spatrick __storage_type __b1 = *__first.__seg_ & __m; 85746035553Spatrick *__first.__seg_ &= ~__m; 85846035553Spatrick __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r); 85946035553Spatrick __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 86046035553Spatrick __storage_type __b2 = *__result.__seg_ & __m; 86146035553Spatrick *__result.__seg_ &= ~__m; 86246035553Spatrick *__result.__seg_ |= __b1 << __result.__ctz_; 86346035553Spatrick *__first.__seg_ |= __b2 >> __result.__ctz_; 86446035553Spatrick __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 86546035553Spatrick __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 86646035553Spatrick __n -= __dn; 86746035553Spatrick if (__n > 0) 86846035553Spatrick { 86946035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __n); 87046035553Spatrick __b2 = *__result.__seg_ & __m; 87146035553Spatrick *__result.__seg_ &= ~__m; 87246035553Spatrick *__result.__seg_ |= __b1 >> __dn; 87346035553Spatrick *__first.__seg_ |= __b2 << __dn; 87446035553Spatrick __result.__ctz_ = static_cast<unsigned>(__n); 87546035553Spatrick } 87646035553Spatrick } 87746035553Spatrick } 87846035553Spatrick return __result; 87946035553Spatrick} 88046035553Spatrick 88146035553Spatricktemplate <class __C1, class __C2> 88246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 88346035553Spatrick__bit_iterator<__C2, false> 88446035553Spatrickswap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, 88546035553Spatrick __bit_iterator<__C2, false> __first2) 88646035553Spatrick{ 88746035553Spatrick if (__first1.__ctz_ == __first2.__ctz_) 88876d0caaeSpatrick return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2); 88976d0caaeSpatrick return _VSTD::__swap_ranges_unaligned(__first1, __last1, __first2); 89046035553Spatrick} 89146035553Spatrick 89246035553Spatrick// rotate 89346035553Spatrick 89446035553Spatricktemplate <class _Cp> 89546035553Spatrickstruct __bit_array 89646035553Spatrick{ 89746035553Spatrick typedef typename _Cp::difference_type difference_type; 89846035553Spatrick typedef typename _Cp::__storage_type __storage_type; 89946035553Spatrick typedef typename _Cp::__storage_pointer __storage_pointer; 90046035553Spatrick typedef typename _Cp::iterator iterator; 90146035553Spatrick static const unsigned __bits_per_word = _Cp::__bits_per_word; 90246035553Spatrick static const unsigned _Np = 4; 90346035553Spatrick 90446035553Spatrick difference_type __size_; 90546035553Spatrick __storage_type __word_[_Np]; 90646035553Spatrick 907*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() 90846035553Spatrick {return static_cast<difference_type>(_Np * __bits_per_word);} 909*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) { 910*4bdff4beSrobert if (__libcpp_is_constant_evaluated()) { 911*4bdff4beSrobert for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i) 912*4bdff4beSrobert std::__construct_at(__word_ + __i, 0); 913*4bdff4beSrobert } 914*4bdff4beSrobert } 915*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() 91646035553Spatrick { 91746035553Spatrick return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); 91846035553Spatrick } 919*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() 92046035553Spatrick { 92146035553Spatrick return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, 92246035553Spatrick static_cast<unsigned>(__size_ % __bits_per_word)); 92346035553Spatrick } 92446035553Spatrick}; 92546035553Spatrick 92646035553Spatricktemplate <class _Cp> 927*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> 92846035553Spatrickrotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) 92946035553Spatrick{ 93046035553Spatrick typedef __bit_iterator<_Cp, false> _I1; 93146035553Spatrick typedef typename _I1::difference_type difference_type; 93246035553Spatrick difference_type __d1 = __middle - __first; 93346035553Spatrick difference_type __d2 = __last - __middle; 93446035553Spatrick _I1 __r = __first + __d2; 93546035553Spatrick while (__d1 != 0 && __d2 != 0) 93646035553Spatrick { 93746035553Spatrick if (__d1 <= __d2) 93846035553Spatrick { 93946035553Spatrick if (__d1 <= __bit_array<_Cp>::capacity()) 94046035553Spatrick { 94146035553Spatrick __bit_array<_Cp> __b(__d1); 94246035553Spatrick _VSTD::copy(__first, __middle, __b.begin()); 94346035553Spatrick _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first)); 94446035553Spatrick break; 94546035553Spatrick } 94646035553Spatrick else 94746035553Spatrick { 94846035553Spatrick __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle); 94946035553Spatrick __first = __middle; 95046035553Spatrick __middle = __mp; 95146035553Spatrick __d2 -= __d1; 95246035553Spatrick } 95346035553Spatrick } 95446035553Spatrick else 95546035553Spatrick { 95646035553Spatrick if (__d2 <= __bit_array<_Cp>::capacity()) 95746035553Spatrick { 95846035553Spatrick __bit_array<_Cp> __b(__d2); 95946035553Spatrick _VSTD::copy(__middle, __last, __b.begin()); 96046035553Spatrick _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last)); 96146035553Spatrick break; 96246035553Spatrick } 96346035553Spatrick else 96446035553Spatrick { 96546035553Spatrick __bit_iterator<_Cp, false> __mp = __first + __d2; 96646035553Spatrick _VSTD::swap_ranges(__first, __mp, __middle); 96746035553Spatrick __first = __mp; 96846035553Spatrick __d1 -= __d2; 96946035553Spatrick } 97046035553Spatrick } 97146035553Spatrick } 97246035553Spatrick return __r; 97346035553Spatrick} 97446035553Spatrick 97546035553Spatrick// equal 97646035553Spatrick 97746035553Spatricktemplate <class _Cp, bool _IC1, bool _IC2> 978*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 97946035553Spatrick__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, 98046035553Spatrick __bit_iterator<_Cp, _IC2> __first2) 98146035553Spatrick{ 98246035553Spatrick typedef __bit_iterator<_Cp, _IC1> _It; 98346035553Spatrick typedef typename _It::difference_type difference_type; 98446035553Spatrick typedef typename _It::__storage_type __storage_type; 985*4bdff4beSrobert const int __bits_per_word = _It::__bits_per_word; 98646035553Spatrick difference_type __n = __last1 - __first1; 98746035553Spatrick if (__n > 0) 98846035553Spatrick { 98946035553Spatrick // do first word 99046035553Spatrick if (__first1.__ctz_ != 0) 99146035553Spatrick { 99246035553Spatrick unsigned __clz_f = __bits_per_word - __first1.__ctz_; 99346035553Spatrick difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n); 99446035553Spatrick __n -= __dn; 99546035553Spatrick __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 99646035553Spatrick __storage_type __b = *__first1.__seg_ & __m; 99746035553Spatrick unsigned __clz_r = __bits_per_word - __first2.__ctz_; 99846035553Spatrick __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); 99946035553Spatrick __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 100046035553Spatrick if (__first2.__ctz_ > __first1.__ctz_) 100146035553Spatrick { 100246035553Spatrick if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) 100346035553Spatrick return false; 100446035553Spatrick } 100546035553Spatrick else 100646035553Spatrick { 100746035553Spatrick if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) 100846035553Spatrick return false; 100946035553Spatrick } 101046035553Spatrick __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; 101146035553Spatrick __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word); 101246035553Spatrick __dn -= __ddn; 101346035553Spatrick if (__dn > 0) 101446035553Spatrick { 101546035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __dn); 101646035553Spatrick if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) 101746035553Spatrick return false; 101846035553Spatrick __first2.__ctz_ = static_cast<unsigned>(__dn); 101946035553Spatrick } 102046035553Spatrick ++__first1.__seg_; 102146035553Spatrick // __first1.__ctz_ = 0; 102246035553Spatrick } 102346035553Spatrick // __first1.__ctz_ == 0; 102446035553Spatrick // do middle words 102546035553Spatrick unsigned __clz_r = __bits_per_word - __first2.__ctz_; 102646035553Spatrick __storage_type __m = ~__storage_type(0) << __first2.__ctz_; 102746035553Spatrick for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) 102846035553Spatrick { 102946035553Spatrick __storage_type __b = *__first1.__seg_; 103046035553Spatrick if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) 103146035553Spatrick return false; 103246035553Spatrick ++__first2.__seg_; 103346035553Spatrick if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) 103446035553Spatrick return false; 103546035553Spatrick } 103646035553Spatrick // do last word 103746035553Spatrick if (__n > 0) 103846035553Spatrick { 103946035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __n); 104046035553Spatrick __storage_type __b = *__first1.__seg_ & __m; 104146035553Spatrick __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r)); 104246035553Spatrick __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 104346035553Spatrick if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) 104446035553Spatrick return false; 104546035553Spatrick __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; 104646035553Spatrick __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word); 104746035553Spatrick __n -= __dn; 104846035553Spatrick if (__n > 0) 104946035553Spatrick { 105046035553Spatrick __m = ~__storage_type(0) >> (__bits_per_word - __n); 105146035553Spatrick if ((*__first2.__seg_ & __m) != (__b >> __dn)) 105246035553Spatrick return false; 105346035553Spatrick } 105446035553Spatrick } 105546035553Spatrick } 105646035553Spatrick return true; 105746035553Spatrick} 105846035553Spatrick 105946035553Spatricktemplate <class _Cp, bool _IC1, bool _IC2> 1060*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool 106146035553Spatrick__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, 106246035553Spatrick __bit_iterator<_Cp, _IC2> __first2) 106346035553Spatrick{ 106446035553Spatrick typedef __bit_iterator<_Cp, _IC1> _It; 106546035553Spatrick typedef typename _It::difference_type difference_type; 106646035553Spatrick typedef typename _It::__storage_type __storage_type; 1067*4bdff4beSrobert const int __bits_per_word = _It::__bits_per_word; 106846035553Spatrick difference_type __n = __last1 - __first1; 106946035553Spatrick if (__n > 0) 107046035553Spatrick { 107146035553Spatrick // do first word 107246035553Spatrick if (__first1.__ctz_ != 0) 107346035553Spatrick { 107446035553Spatrick unsigned __clz = __bits_per_word - __first1.__ctz_; 107546035553Spatrick difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n); 107646035553Spatrick __n -= __dn; 107746035553Spatrick __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 107846035553Spatrick if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) 107946035553Spatrick return false; 108046035553Spatrick ++__first2.__seg_; 108146035553Spatrick ++__first1.__seg_; 108246035553Spatrick // __first1.__ctz_ = 0; 108346035553Spatrick // __first2.__ctz_ = 0; 108446035553Spatrick } 108546035553Spatrick // __first1.__ctz_ == 0; 108646035553Spatrick // __first2.__ctz_ == 0; 108746035553Spatrick // do middle words 108846035553Spatrick for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) 108946035553Spatrick if (*__first2.__seg_ != *__first1.__seg_) 109046035553Spatrick return false; 109146035553Spatrick // do last word 109246035553Spatrick if (__n > 0) 109346035553Spatrick { 109446035553Spatrick __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 109546035553Spatrick if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) 109646035553Spatrick return false; 109746035553Spatrick } 109846035553Spatrick } 109946035553Spatrick return true; 110046035553Spatrick} 110146035553Spatrick 110246035553Spatricktemplate <class _Cp, bool _IC1, bool _IC2> 1103*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 110446035553Spatrickbool 110546035553Spatrickequal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) 110646035553Spatrick{ 110746035553Spatrick if (__first1.__ctz_ == __first2.__ctz_) 110876d0caaeSpatrick return _VSTD::__equal_aligned(__first1, __last1, __first2); 110976d0caaeSpatrick return _VSTD::__equal_unaligned(__first1, __last1, __first2); 111046035553Spatrick} 111146035553Spatrick 111246035553Spatricktemplate <class _Cp, bool _IsConst, 111346035553Spatrick typename _Cp::__storage_type> 111446035553Spatrickclass __bit_iterator 111546035553Spatrick{ 111646035553Spatrickpublic: 111746035553Spatrick typedef typename _Cp::difference_type difference_type; 111846035553Spatrick typedef bool value_type; 111946035553Spatrick typedef __bit_iterator pointer; 1120*4bdff4beSrobert#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL 1121*4bdff4beSrobert typedef __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> > reference; 1122*4bdff4beSrobert#else 1123*4bdff4beSrobert using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >; 1124*4bdff4beSrobert#endif 112546035553Spatrick typedef random_access_iterator_tag iterator_category; 112646035553Spatrick 112746035553Spatrickprivate: 112846035553Spatrick typedef typename _Cp::__storage_type __storage_type; 1129*4bdff4beSrobert typedef __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer> 1130*4bdff4beSrobert __storage_pointer; 113146035553Spatrick static const unsigned __bits_per_word = _Cp::__bits_per_word; 113246035553Spatrick 113346035553Spatrick __storage_pointer __seg_; 113446035553Spatrick unsigned __ctz_; 113546035553Spatrick 113646035553Spatrickpublic: 1137*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT 113846035553Spatrick#if _LIBCPP_STD_VER > 11 113946035553Spatrick : __seg_(nullptr), __ctz_(0) 114046035553Spatrick#endif 114146035553Spatrick {} 114246035553Spatrick 114376d0caaeSpatrick // When _IsConst=false, this is the copy constructor. 114476d0caaeSpatrick // It is non-trivial. Making it trivial would break ABI. 114576d0caaeSpatrick // When _IsConst=true, this is a converting constructor; 114676d0caaeSpatrick // the copy and move constructors are implicitly generated 114776d0caaeSpatrick // and trivial. 1148*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 114976d0caaeSpatrick __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT 115046035553Spatrick : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} 115146035553Spatrick 115276d0caaeSpatrick // When _IsConst=false, we have a user-provided copy constructor, 115376d0caaeSpatrick // so we must also provide a copy assignment operator because 115476d0caaeSpatrick // the implicit generation of a defaulted one is deprecated. 115576d0caaeSpatrick // When _IsConst=true, the assignment operators are 115676d0caaeSpatrick // implicitly generated and trivial. 1157*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 115876d0caaeSpatrick __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) { 115976d0caaeSpatrick __seg_ = __it.__seg_; 116076d0caaeSpatrick __ctz_ = __it.__ctz_; 116176d0caaeSpatrick return *this; 116276d0caaeSpatrick } 116346035553Spatrick 1164*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT { 1165*4bdff4beSrobert return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >( 1166*4bdff4beSrobert __seg_, __storage_type(1) << __ctz_); 1167*4bdff4beSrobert } 116846035553Spatrick 1169*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() 117046035553Spatrick { 117146035553Spatrick if (__ctz_ != __bits_per_word-1) 117246035553Spatrick ++__ctz_; 117346035553Spatrick else 117446035553Spatrick { 117546035553Spatrick __ctz_ = 0; 117646035553Spatrick ++__seg_; 117746035553Spatrick } 117846035553Spatrick return *this; 117946035553Spatrick } 118046035553Spatrick 1181*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) 118246035553Spatrick { 118346035553Spatrick __bit_iterator __tmp = *this; 118446035553Spatrick ++(*this); 118546035553Spatrick return __tmp; 118646035553Spatrick } 118746035553Spatrick 1188*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() 118946035553Spatrick { 119046035553Spatrick if (__ctz_ != 0) 119146035553Spatrick --__ctz_; 119246035553Spatrick else 119346035553Spatrick { 119446035553Spatrick __ctz_ = __bits_per_word - 1; 119546035553Spatrick --__seg_; 119646035553Spatrick } 119746035553Spatrick return *this; 119846035553Spatrick } 119946035553Spatrick 1200*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) 120146035553Spatrick { 120246035553Spatrick __bit_iterator __tmp = *this; 120346035553Spatrick --(*this); 120446035553Spatrick return __tmp; 120546035553Spatrick } 120646035553Spatrick 1207*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) 120846035553Spatrick { 120946035553Spatrick if (__n >= 0) 121046035553Spatrick __seg_ += (__n + __ctz_) / __bits_per_word; 121146035553Spatrick else 121246035553Spatrick __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) 121346035553Spatrick / static_cast<difference_type>(__bits_per_word); 121446035553Spatrick __n &= (__bits_per_word - 1); 121546035553Spatrick __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word); 121646035553Spatrick return *this; 121746035553Spatrick } 121846035553Spatrick 1219*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) 122046035553Spatrick { 122146035553Spatrick return *this += -__n; 122246035553Spatrick } 122346035553Spatrick 1224*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const 122546035553Spatrick { 122646035553Spatrick __bit_iterator __t(*this); 122746035553Spatrick __t += __n; 122846035553Spatrick return __t; 122946035553Spatrick } 123046035553Spatrick 1231*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const 123246035553Spatrick { 123346035553Spatrick __bit_iterator __t(*this); 123446035553Spatrick __t -= __n; 123546035553Spatrick return __t; 123646035553Spatrick } 123746035553Spatrick 1238*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 123946035553Spatrick friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;} 124046035553Spatrick 1241*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 124246035553Spatrick friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) 124346035553Spatrick {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;} 124446035553Spatrick 1245*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const {return *(*this + __n);} 124646035553Spatrick 1247*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) 124846035553Spatrick {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;} 124946035553Spatrick 1250*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) 125146035553Spatrick {return !(__x == __y);} 125246035553Spatrick 1253*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) 125446035553Spatrick {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);} 125546035553Spatrick 1256*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) 125746035553Spatrick {return __y < __x;} 125846035553Spatrick 1259*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) 126046035553Spatrick {return !(__y < __x);} 126146035553Spatrick 1262*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) 126346035553Spatrick {return !(__x < __y);} 126446035553Spatrick 126546035553Spatrickprivate: 1266*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 1267*4bdff4beSrobert explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT 126846035553Spatrick : __seg_(__s), __ctz_(__ctz) {} 126946035553Spatrick 127046035553Spatrick friend typename _Cp::__self; 127146035553Spatrick 127246035553Spatrick friend class __bit_reference<_Cp>; 127346035553Spatrick friend class __bit_const_reference<_Cp>; 127446035553Spatrick friend class __bit_iterator<_Cp, true>; 127546035553Spatrick template <class _Dp> friend struct __bit_array; 1276*4bdff4beSrobert template <class _Dp> 1277*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1278*4bdff4beSrobert friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); 1279*4bdff4beSrobert 1280*4bdff4beSrobert template <class _Dp> 1281*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1282*4bdff4beSrobert friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); 1283*4bdff4beSrobert 1284*4bdff4beSrobert template <class _Dp, bool _IC> 1285*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1286*4bdff4beSrobert friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first, 128746035553Spatrick __bit_iterator<_Dp, _IC> __last, 128846035553Spatrick __bit_iterator<_Dp, false> __result); 1289*4bdff4beSrobert template <class _Dp, bool _IC> 1290*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1291*4bdff4beSrobert friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first, 129246035553Spatrick __bit_iterator<_Dp, _IC> __last, 129346035553Spatrick __bit_iterator<_Dp, false> __result); 1294*4bdff4beSrobert template <class _Dp, bool _IC> 1295*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1296*4bdff4beSrobert friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first, 129746035553Spatrick __bit_iterator<_Dp, _IC> __last, 129846035553Spatrick __bit_iterator<_Dp, false> __result); 1299*4bdff4beSrobert template <class _Dp, bool _IC> 1300*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1301*4bdff4beSrobert friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first, 130246035553Spatrick __bit_iterator<_Dp, _IC> __last, 130346035553Spatrick __bit_iterator<_Dp, false> __result); 1304*4bdff4beSrobert template <class _Dp, bool _IC> 1305*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1306*4bdff4beSrobert friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first, 130746035553Spatrick __bit_iterator<_Dp, _IC> __last, 130846035553Spatrick __bit_iterator<_Dp, false> __result); 1309*4bdff4beSrobert template <class _Dp, bool _IC> 1310*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1311*4bdff4beSrobert friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, 131246035553Spatrick __bit_iterator<_Dp, _IC> __last, 131346035553Spatrick __bit_iterator<_Dp, false> __result); 131446035553Spatrick template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, 131546035553Spatrick __bit_iterator<__C1, false>, 131646035553Spatrick __bit_iterator<__C2, false>); 131746035553Spatrick template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>, 131846035553Spatrick __bit_iterator<__C1, false>, 131946035553Spatrick __bit_iterator<__C2, false>); 132046035553Spatrick template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, 132146035553Spatrick __bit_iterator<__C1, false>, 132246035553Spatrick __bit_iterator<__C2, false>); 1323*4bdff4beSrobert template <class _Dp> 1324*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1325*4bdff4beSrobert friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, 132646035553Spatrick __bit_iterator<_Dp, false>, 132746035553Spatrick __bit_iterator<_Dp, false>); 1328*4bdff4beSrobert template <class _Dp, bool _IC1, bool _IC2> 1329*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1330*4bdff4beSrobert friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, 133146035553Spatrick __bit_iterator<_Dp, _IC1>, 133246035553Spatrick __bit_iterator<_Dp, _IC2>); 1333*4bdff4beSrobert template <class _Dp, bool _IC1, bool _IC2> 1334*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1335*4bdff4beSrobert friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, 133646035553Spatrick __bit_iterator<_Dp, _IC1>, 133746035553Spatrick __bit_iterator<_Dp, _IC2>); 1338*4bdff4beSrobert template <class _Dp, bool _IC1, bool _IC2> 1339*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1340*4bdff4beSrobert friend bool equal(__bit_iterator<_Dp, _IC1>, 134146035553Spatrick __bit_iterator<_Dp, _IC1>, 134246035553Spatrick __bit_iterator<_Dp, _IC2>); 1343*4bdff4beSrobert template <class _Dp, bool _IC> 1344*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1345*4bdff4beSrobert friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); 1346*4bdff4beSrobert template <class _Dp, bool _IC> 1347*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 1348*4bdff4beSrobert friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); 134946035553Spatrick template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type 1350*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 135146035553Spatrick __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); 135246035553Spatrick template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type 135346035553Spatrick __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); 135446035553Spatrick}; 135546035553Spatrick 135646035553Spatrick_LIBCPP_END_NAMESPACE_STD 135746035553Spatrick 135846035553Spatrick_LIBCPP_POP_MACROS 135946035553Spatrick 136046035553Spatrick#endif // _LIBCPP___BIT_REFERENCE 1361