1e78f53d1SNikolas Klauser// -*- C++ -*- 2e78f53d1SNikolas Klauser//===----------------------------------------------------------------------===// 3e78f53d1SNikolas Klauser// 4e78f53d1SNikolas Klauser// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5e78f53d1SNikolas Klauser// See https://llvm.org/LICENSE.txt for license information. 6e78f53d1SNikolas Klauser// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7e78f53d1SNikolas Klauser// 8e78f53d1SNikolas Klauser//===----------------------------------------------------------------------===// 9e78f53d1SNikolas Klauser 10*ce777190SNikolas Klauser#ifndef _LIBCPP___CXX03___BIT_REFERENCE 11*ce777190SNikolas Klauser#define _LIBCPP___CXX03___BIT_REFERENCE 12e78f53d1SNikolas Klauser 1373fbae83SNikolas Klauser#include <__cxx03/__algorithm/copy_n.h> 1473fbae83SNikolas Klauser#include <__cxx03/__algorithm/fill_n.h> 1573fbae83SNikolas Klauser#include <__cxx03/__algorithm/min.h> 1673fbae83SNikolas Klauser#include <__cxx03/__bit/countr.h> 1773fbae83SNikolas Klauser#include <__cxx03/__bit/invert_if.h> 1873fbae83SNikolas Klauser#include <__cxx03/__bit/popcount.h> 1973fbae83SNikolas Klauser#include <__cxx03/__compare/ordering.h> 2073fbae83SNikolas Klauser#include <__cxx03/__config> 2173fbae83SNikolas Klauser#include <__cxx03/__fwd/bit_reference.h> 2273fbae83SNikolas Klauser#include <__cxx03/__iterator/iterator_traits.h> 2373fbae83SNikolas Klauser#include <__cxx03/__memory/construct_at.h> 2473fbae83SNikolas Klauser#include <__cxx03/__memory/pointer_traits.h> 2573fbae83SNikolas Klauser#include <__cxx03/__type_traits/conditional.h> 2673fbae83SNikolas Klauser#include <__cxx03/__utility/swap.h> 2773fbae83SNikolas Klauser#include <__cxx03/cstring> 28e78f53d1SNikolas Klauser 29e78f53d1SNikolas Klauser#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 30e78f53d1SNikolas Klauser# pragma GCC system_header 31e78f53d1SNikolas Klauser#endif 32e78f53d1SNikolas Klauser 33e78f53d1SNikolas Klauser_LIBCPP_PUSH_MACROS 3473fbae83SNikolas Klauser#include <__cxx03/__undef_macros> 35e78f53d1SNikolas Klauser 36e78f53d1SNikolas Klauser_LIBCPP_BEGIN_NAMESPACE_STD 37e78f53d1SNikolas Klauser 38e78f53d1SNikolas Klausertemplate <class _Cp> 39e78f53d1SNikolas Klauserclass __bit_const_reference; 40e78f53d1SNikolas Klauser 41e78f53d1SNikolas Klausertemplate <class _Tp> 42e78f53d1SNikolas Klauserstruct __has_storage_type { 43e78f53d1SNikolas Klauser static const bool value = false; 44e78f53d1SNikolas Klauser}; 45e78f53d1SNikolas Klauser 46e78f53d1SNikolas Klausertemplate <class _Cp, bool = __has_storage_type<_Cp>::value> 47e78f53d1SNikolas Klauserclass __bit_reference { 48e78f53d1SNikolas Klauser using __storage_type = typename _Cp::__storage_type; 49e78f53d1SNikolas Klauser using __storage_pointer = typename _Cp::__storage_pointer; 50e78f53d1SNikolas Klauser 51e78f53d1SNikolas Klauser __storage_pointer __seg_; 52e78f53d1SNikolas Klauser __storage_type __mask_; 53e78f53d1SNikolas Klauser 54e78f53d1SNikolas Klauser friend typename _Cp::__self; 55e78f53d1SNikolas Klauser 56e78f53d1SNikolas Klauser friend class __bit_const_reference<_Cp>; 57e78f53d1SNikolas Klauser friend class __bit_iterator<_Cp, false>; 58e78f53d1SNikolas Klauser 59e78f53d1SNikolas Klauserpublic: 60e78f53d1SNikolas Klauser using __container = typename _Cp::__self; 61e78f53d1SNikolas Klauser 62e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference(const __bit_reference&) = default; 63e78f53d1SNikolas Klauser 64e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT { 65e78f53d1SNikolas Klauser return static_cast<bool>(*__seg_ & __mask_); 66e78f53d1SNikolas Klauser } 67e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT { 68e78f53d1SNikolas Klauser return !static_cast<bool>(*this); 69e78f53d1SNikolas Klauser } 70e78f53d1SNikolas Klauser 71e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(bool __x) _NOEXCEPT { 72e78f53d1SNikolas Klauser if (__x) 73e78f53d1SNikolas Klauser *__seg_ |= __mask_; 74e78f53d1SNikolas Klauser else 75e78f53d1SNikolas Klauser *__seg_ &= ~__mask_; 76e78f53d1SNikolas Klauser return *this; 77e78f53d1SNikolas Klauser } 78e78f53d1SNikolas Klauser 79e78f53d1SNikolas Klauser#if _LIBCPP_STD_VER >= 23 80e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept { 81e78f53d1SNikolas Klauser if (__x) 82e78f53d1SNikolas Klauser *__seg_ |= __mask_; 83e78f53d1SNikolas Klauser else 84e78f53d1SNikolas Klauser *__seg_ &= ~__mask_; 85e78f53d1SNikolas Klauser return *this; 86e78f53d1SNikolas Klauser } 87e78f53d1SNikolas Klauser#endif 88e78f53d1SNikolas Klauser 89e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT { 90e78f53d1SNikolas Klauser return operator=(static_cast<bool>(__x)); 91e78f53d1SNikolas Klauser } 92e78f53d1SNikolas Klauser 93e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT { *__seg_ ^= __mask_; } 94e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT { 95e78f53d1SNikolas Klauser return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_))); 96e78f53d1SNikolas Klauser } 97e78f53d1SNikolas Klauser 98e78f53d1SNikolas Klauserprivate: 99e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI 100e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 101e78f53d1SNikolas Klauser : __seg_(__s), 102e78f53d1SNikolas Klauser __mask_(__m) {} 103e78f53d1SNikolas Klauser}; 104e78f53d1SNikolas Klauser 105e78f53d1SNikolas Klausertemplate <class _Cp> 106e78f53d1SNikolas Klauserclass __bit_reference<_Cp, false> {}; 107e78f53d1SNikolas Klauser 108e78f53d1SNikolas Klausertemplate <class _Cp> 109e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 110e78f53d1SNikolas Klauserswap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT { 111e78f53d1SNikolas Klauser bool __t = __x; 112e78f53d1SNikolas Klauser __x = __y; 113e78f53d1SNikolas Klauser __y = __t; 114e78f53d1SNikolas Klauser} 115e78f53d1SNikolas Klauser 116e78f53d1SNikolas Klausertemplate <class _Cp, class _Dp> 117e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 118e78f53d1SNikolas Klauserswap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT { 119e78f53d1SNikolas Klauser bool __t = __x; 120e78f53d1SNikolas Klauser __x = __y; 121e78f53d1SNikolas Klauser __y = __t; 122e78f53d1SNikolas Klauser} 123e78f53d1SNikolas Klauser 124e78f53d1SNikolas Klausertemplate <class _Cp> 125e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT { 126e78f53d1SNikolas Klauser bool __t = __x; 127e78f53d1SNikolas Klauser __x = __y; 128e78f53d1SNikolas Klauser __y = __t; 129e78f53d1SNikolas Klauser} 130e78f53d1SNikolas Klauser 131e78f53d1SNikolas Klausertemplate <class _Cp> 132e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT { 133e78f53d1SNikolas Klauser bool __t = __x; 134e78f53d1SNikolas Klauser __x = __y; 135e78f53d1SNikolas Klauser __y = __t; 136e78f53d1SNikolas Klauser} 137e78f53d1SNikolas Klauser 138e78f53d1SNikolas Klausertemplate <class _Cp> 139e78f53d1SNikolas Klauserclass __bit_const_reference { 140e78f53d1SNikolas Klauser using __storage_type = typename _Cp::__storage_type; 141e78f53d1SNikolas Klauser using __storage_pointer = typename _Cp::__const_storage_pointer; 142e78f53d1SNikolas Klauser 143e78f53d1SNikolas Klauser __storage_pointer __seg_; 144e78f53d1SNikolas Klauser __storage_type __mask_; 145e78f53d1SNikolas Klauser 146e78f53d1SNikolas Klauser friend typename _Cp::__self; 147e78f53d1SNikolas Klauser friend class __bit_iterator<_Cp, true>; 148e78f53d1SNikolas Klauser 149e78f53d1SNikolas Klauserpublic: 150e78f53d1SNikolas Klauser using __container = typename _Cp::__self; 151e78f53d1SNikolas Klauser 152e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_const_reference&) = default; 153e78f53d1SNikolas Klauser __bit_const_reference& operator=(const __bit_const_reference&) = delete; 154e78f53d1SNikolas Klauser 155e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT 156e78f53d1SNikolas Klauser : __seg_(__x.__seg_), 157e78f53d1SNikolas Klauser __mask_(__x.__mask_) {} 158e78f53d1SNikolas Klauser 159e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT { 160e78f53d1SNikolas Klauser return static_cast<bool>(*__seg_ & __mask_); 161e78f53d1SNikolas Klauser } 162e78f53d1SNikolas Klauser 163e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT { 164e78f53d1SNikolas Klauser return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_))); 165e78f53d1SNikolas Klauser } 166e78f53d1SNikolas Klauser 167e78f53d1SNikolas Klauserprivate: 168e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI 169e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 170e78f53d1SNikolas Klauser : __seg_(__s), 171e78f53d1SNikolas Klauser __mask_(__m) {} 172e78f53d1SNikolas Klauser}; 173e78f53d1SNikolas Klauser 174e78f53d1SNikolas Klauser// copy 175e78f53d1SNikolas Klauser 176e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst> 177e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned( 178e78f53d1SNikolas Klauser __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { 179e78f53d1SNikolas Klauser using _In = __bit_iterator<_Cp, _IsConst>; 180e78f53d1SNikolas Klauser using difference_type = typename _In::difference_type; 181e78f53d1SNikolas Klauser using __storage_type = typename _In::__storage_type; 182e78f53d1SNikolas Klauser 183e78f53d1SNikolas Klauser const int __bits_per_word = _In::__bits_per_word; 184e78f53d1SNikolas Klauser difference_type __n = __last - __first; 185e78f53d1SNikolas Klauser if (__n > 0) { 186e78f53d1SNikolas Klauser // do first word 187e78f53d1SNikolas Klauser if (__first.__ctz_ != 0) { 188e78f53d1SNikolas Klauser unsigned __clz = __bits_per_word - __first.__ctz_; 189e78f53d1SNikolas Klauser difference_type __dn = std::min(static_cast<difference_type>(__clz), __n); 190e78f53d1SNikolas Klauser __n -= __dn; 191e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 192e78f53d1SNikolas Klauser __storage_type __b = *__first.__seg_ & __m; 193e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 194e78f53d1SNikolas Klauser *__result.__seg_ |= __b; 195e78f53d1SNikolas Klauser __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 196e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 197e78f53d1SNikolas Klauser ++__first.__seg_; 198e78f53d1SNikolas Klauser // __first.__ctz_ = 0; 199e78f53d1SNikolas Klauser } 200e78f53d1SNikolas Klauser // __first.__ctz_ == 0; 201e78f53d1SNikolas Klauser // do middle words 202e78f53d1SNikolas Klauser __storage_type __nw = __n / __bits_per_word; 203e78f53d1SNikolas Klauser std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_)); 204e78f53d1SNikolas Klauser __n -= __nw * __bits_per_word; 205e78f53d1SNikolas Klauser __result.__seg_ += __nw; 206e78f53d1SNikolas Klauser // do last word 207e78f53d1SNikolas Klauser if (__n > 0) { 208e78f53d1SNikolas Klauser __first.__seg_ += __nw; 209e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 210e78f53d1SNikolas Klauser __storage_type __b = *__first.__seg_ & __m; 211e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 212e78f53d1SNikolas Klauser *__result.__seg_ |= __b; 213e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(__n); 214e78f53d1SNikolas Klauser } 215e78f53d1SNikolas Klauser } 216e78f53d1SNikolas Klauser return __result; 217e78f53d1SNikolas Klauser} 218e78f53d1SNikolas Klauser 219e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst> 220e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned( 221e78f53d1SNikolas Klauser __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { 222e78f53d1SNikolas Klauser using _In = __bit_iterator<_Cp, _IsConst>; 223e78f53d1SNikolas Klauser using difference_type = typename _In::difference_type; 224e78f53d1SNikolas Klauser using __storage_type = typename _In::__storage_type; 225e78f53d1SNikolas Klauser 226e78f53d1SNikolas Klauser const int __bits_per_word = _In::__bits_per_word; 227e78f53d1SNikolas Klauser difference_type __n = __last - __first; 228e78f53d1SNikolas Klauser if (__n > 0) { 229e78f53d1SNikolas Klauser // do first word 230e78f53d1SNikolas Klauser if (__first.__ctz_ != 0) { 231e78f53d1SNikolas Klauser unsigned __clz_f = __bits_per_word - __first.__ctz_; 232e78f53d1SNikolas Klauser difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n); 233e78f53d1SNikolas Klauser __n -= __dn; 234e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 235e78f53d1SNikolas Klauser __storage_type __b = *__first.__seg_ & __m; 236e78f53d1SNikolas Klauser unsigned __clz_r = __bits_per_word - __result.__ctz_; 237e78f53d1SNikolas Klauser __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); 238e78f53d1SNikolas Klauser __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 239e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 240e78f53d1SNikolas Klauser if (__result.__ctz_ > __first.__ctz_) 241e78f53d1SNikolas Klauser *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); 242e78f53d1SNikolas Klauser else 243e78f53d1SNikolas Klauser *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); 244e78f53d1SNikolas Klauser __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; 245e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); 246e78f53d1SNikolas Klauser __dn -= __ddn; 247e78f53d1SNikolas Klauser if (__dn > 0) { 248e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __dn); 249e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 250e78f53d1SNikolas Klauser *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); 251e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(__dn); 252e78f53d1SNikolas Klauser } 253e78f53d1SNikolas Klauser ++__first.__seg_; 254e78f53d1SNikolas Klauser // __first.__ctz_ = 0; 255e78f53d1SNikolas Klauser } 256e78f53d1SNikolas Klauser // __first.__ctz_ == 0; 257e78f53d1SNikolas Klauser // do middle words 258e78f53d1SNikolas Klauser unsigned __clz_r = __bits_per_word - __result.__ctz_; 259e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) << __result.__ctz_; 260e78f53d1SNikolas Klauser for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) { 261e78f53d1SNikolas Klauser __storage_type __b = *__first.__seg_; 262e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 263e78f53d1SNikolas Klauser *__result.__seg_ |= __b << __result.__ctz_; 264e78f53d1SNikolas Klauser ++__result.__seg_; 265e78f53d1SNikolas Klauser *__result.__seg_ &= __m; 266e78f53d1SNikolas Klauser *__result.__seg_ |= __b >> __clz_r; 267e78f53d1SNikolas Klauser } 268e78f53d1SNikolas Klauser // do last word 269e78f53d1SNikolas Klauser if (__n > 0) { 270e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __n); 271e78f53d1SNikolas Klauser __storage_type __b = *__first.__seg_ & __m; 272e78f53d1SNikolas Klauser __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r)); 273e78f53d1SNikolas Klauser __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 274e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 275e78f53d1SNikolas Klauser *__result.__seg_ |= __b << __result.__ctz_; 276e78f53d1SNikolas Klauser __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 277e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 278e78f53d1SNikolas Klauser __n -= __dn; 279e78f53d1SNikolas Klauser if (__n > 0) { 280e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __n); 281e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 282e78f53d1SNikolas Klauser *__result.__seg_ |= __b >> __dn; 283e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(__n); 284e78f53d1SNikolas Klauser } 285e78f53d1SNikolas Klauser } 286e78f53d1SNikolas Klauser } 287e78f53d1SNikolas Klauser return __result; 288e78f53d1SNikolas Klauser} 289e78f53d1SNikolas Klauser 290e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst> 291e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> 292e78f53d1SNikolas Klausercopy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { 293e78f53d1SNikolas Klauser if (__first.__ctz_ == __result.__ctz_) 294e78f53d1SNikolas Klauser return std::__copy_aligned(__first, __last, __result); 295e78f53d1SNikolas Klauser return std::__copy_unaligned(__first, __last, __result); 296e78f53d1SNikolas Klauser} 297e78f53d1SNikolas Klauser 298e78f53d1SNikolas Klauser// copy_backward 299e78f53d1SNikolas Klauser 300e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst> 301e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned( 302e78f53d1SNikolas Klauser __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { 303e78f53d1SNikolas Klauser using _In = __bit_iterator<_Cp, _IsConst>; 304e78f53d1SNikolas Klauser using difference_type = typename _In::difference_type; 305e78f53d1SNikolas Klauser using __storage_type = typename _In::__storage_type; 306e78f53d1SNikolas Klauser 307e78f53d1SNikolas Klauser const int __bits_per_word = _In::__bits_per_word; 308e78f53d1SNikolas Klauser difference_type __n = __last - __first; 309e78f53d1SNikolas Klauser if (__n > 0) { 310e78f53d1SNikolas Klauser // do first word 311e78f53d1SNikolas Klauser if (__last.__ctz_ != 0) { 312e78f53d1SNikolas Klauser difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n); 313e78f53d1SNikolas Klauser __n -= __dn; 314e78f53d1SNikolas Klauser unsigned __clz = __bits_per_word - __last.__ctz_; 315e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); 316e78f53d1SNikolas Klauser __storage_type __b = *__last.__seg_ & __m; 317e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 318e78f53d1SNikolas Klauser *__result.__seg_ |= __b; 319e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); 320e78f53d1SNikolas Klauser // __last.__ctz_ = 0 321e78f53d1SNikolas Klauser } 322e78f53d1SNikolas Klauser // __last.__ctz_ == 0 || __n == 0 323e78f53d1SNikolas Klauser // __result.__ctz_ == 0 || __n == 0 324e78f53d1SNikolas Klauser // do middle words 325e78f53d1SNikolas Klauser __storage_type __nw = __n / __bits_per_word; 326e78f53d1SNikolas Klauser __result.__seg_ -= __nw; 327e78f53d1SNikolas Klauser __last.__seg_ -= __nw; 328e78f53d1SNikolas Klauser std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_)); 329e78f53d1SNikolas Klauser __n -= __nw * __bits_per_word; 330e78f53d1SNikolas Klauser // do last word 331e78f53d1SNikolas Klauser if (__n > 0) { 332e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); 333e78f53d1SNikolas Klauser __storage_type __b = *--__last.__seg_ & __m; 334e78f53d1SNikolas Klauser *--__result.__seg_ &= ~__m; 335e78f53d1SNikolas Klauser *__result.__seg_ |= __b; 336e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); 337e78f53d1SNikolas Klauser } 338e78f53d1SNikolas Klauser } 339e78f53d1SNikolas Klauser return __result; 340e78f53d1SNikolas Klauser} 341e78f53d1SNikolas Klauser 342e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst> 343e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned( 344e78f53d1SNikolas Klauser __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { 345e78f53d1SNikolas Klauser using _In = __bit_iterator<_Cp, _IsConst>; 346e78f53d1SNikolas Klauser using difference_type = typename _In::difference_type; 347e78f53d1SNikolas Klauser using __storage_type = typename _In::__storage_type; 348e78f53d1SNikolas Klauser 349e78f53d1SNikolas Klauser const int __bits_per_word = _In::__bits_per_word; 350e78f53d1SNikolas Klauser difference_type __n = __last - __first; 351e78f53d1SNikolas Klauser if (__n > 0) { 352e78f53d1SNikolas Klauser // do first word 353e78f53d1SNikolas Klauser if (__last.__ctz_ != 0) { 354e78f53d1SNikolas Klauser difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n); 355e78f53d1SNikolas Klauser __n -= __dn; 356e78f53d1SNikolas Klauser unsigned __clz_l = __bits_per_word - __last.__ctz_; 357e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); 358e78f53d1SNikolas Klauser __storage_type __b = *__last.__seg_ & __m; 359e78f53d1SNikolas Klauser unsigned __clz_r = __bits_per_word - __result.__ctz_; 360e78f53d1SNikolas Klauser __storage_type __ddn = std::min(__dn, static_cast<difference_type>(__result.__ctz_)); 361e78f53d1SNikolas Klauser if (__ddn > 0) { 362e78f53d1SNikolas Klauser __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); 363e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 364e78f53d1SNikolas Klauser if (__result.__ctz_ > __last.__ctz_) 365e78f53d1SNikolas Klauser *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); 366e78f53d1SNikolas Klauser else 367e78f53d1SNikolas Klauser *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); 368e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); 369e78f53d1SNikolas Klauser __dn -= __ddn; 370e78f53d1SNikolas Klauser } 371e78f53d1SNikolas Klauser if (__dn > 0) { 372e78f53d1SNikolas Klauser // __result.__ctz_ == 0 373e78f53d1SNikolas Klauser --__result.__seg_; 374e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1)); 375e78f53d1SNikolas Klauser __m = ~__storage_type(0) << __result.__ctz_; 376e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 377e78f53d1SNikolas Klauser __last.__ctz_ -= __dn + __ddn; 378e78f53d1SNikolas Klauser *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); 379e78f53d1SNikolas Klauser } 380e78f53d1SNikolas Klauser // __last.__ctz_ = 0 381e78f53d1SNikolas Klauser } 382e78f53d1SNikolas Klauser // __last.__ctz_ == 0 || __n == 0 383e78f53d1SNikolas Klauser // __result.__ctz_ != 0 || __n == 0 384e78f53d1SNikolas Klauser // do middle words 385e78f53d1SNikolas Klauser unsigned __clz_r = __bits_per_word - __result.__ctz_; 386e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) >> __clz_r; 387e78f53d1SNikolas Klauser for (; __n >= __bits_per_word; __n -= __bits_per_word) { 388e78f53d1SNikolas Klauser __storage_type __b = *--__last.__seg_; 389e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 390e78f53d1SNikolas Klauser *__result.__seg_ |= __b >> __clz_r; 391e78f53d1SNikolas Klauser *--__result.__seg_ &= __m; 392e78f53d1SNikolas Klauser *__result.__seg_ |= __b << __result.__ctz_; 393e78f53d1SNikolas Klauser } 394e78f53d1SNikolas Klauser // do last word 395e78f53d1SNikolas Klauser if (__n > 0) { 396e78f53d1SNikolas Klauser __m = ~__storage_type(0) << (__bits_per_word - __n); 397e78f53d1SNikolas Klauser __storage_type __b = *--__last.__seg_ & __m; 398e78f53d1SNikolas Klauser __clz_r = __bits_per_word - __result.__ctz_; 399e78f53d1SNikolas Klauser __storage_type __dn = std::min(__n, static_cast<difference_type>(__result.__ctz_)); 400e78f53d1SNikolas Klauser __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); 401e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 402e78f53d1SNikolas Klauser *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); 403e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); 404e78f53d1SNikolas Klauser __n -= __dn; 405e78f53d1SNikolas Klauser if (__n > 0) { 406e78f53d1SNikolas Klauser // __result.__ctz_ == 0 407e78f53d1SNikolas Klauser --__result.__seg_; 408e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); 409e78f53d1SNikolas Klauser __m = ~__storage_type(0) << __result.__ctz_; 410e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 411e78f53d1SNikolas Klauser *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); 412e78f53d1SNikolas Klauser } 413e78f53d1SNikolas Klauser } 414e78f53d1SNikolas Klauser } 415e78f53d1SNikolas Klauser return __result; 416e78f53d1SNikolas Klauser} 417e78f53d1SNikolas Klauser 418e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst> 419e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy_backward( 420e78f53d1SNikolas Klauser __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { 421e78f53d1SNikolas Klauser if (__last.__ctz_ == __result.__ctz_) 422e78f53d1SNikolas Klauser return std::__copy_backward_aligned(__first, __last, __result); 423e78f53d1SNikolas Klauser return std::__copy_backward_unaligned(__first, __last, __result); 424e78f53d1SNikolas Klauser} 425e78f53d1SNikolas Klauser 426e78f53d1SNikolas Klauser// move 427e78f53d1SNikolas Klauser 428e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst> 429e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> 430e78f53d1SNikolas Klausermove(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { 431e78f53d1SNikolas Klauser return std::copy(__first, __last, __result); 432e78f53d1SNikolas Klauser} 433e78f53d1SNikolas Klauser 434e78f53d1SNikolas Klauser// move_backward 435e78f53d1SNikolas Klauser 436e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst> 437e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward( 438e78f53d1SNikolas Klauser __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { 439e78f53d1SNikolas Klauser return std::copy_backward(__first, __last, __result); 440e78f53d1SNikolas Klauser} 441e78f53d1SNikolas Klauser 442e78f53d1SNikolas Klauser// swap_ranges 443e78f53d1SNikolas Klauser 444e78f53d1SNikolas Klausertemplate <class _Cl, class _Cr> 445e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned( 446e78f53d1SNikolas Klauser __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { 447e78f53d1SNikolas Klauser using _I1 = __bit_iterator<_Cl, false>; 448e78f53d1SNikolas Klauser using difference_type = typename _I1::difference_type; 449e78f53d1SNikolas Klauser using __storage_type = typename _I1::__storage_type; 450e78f53d1SNikolas Klauser 451e78f53d1SNikolas Klauser const int __bits_per_word = _I1::__bits_per_word; 452e78f53d1SNikolas Klauser difference_type __n = __last - __first; 453e78f53d1SNikolas Klauser if (__n > 0) { 454e78f53d1SNikolas Klauser // do first word 455e78f53d1SNikolas Klauser if (__first.__ctz_ != 0) { 456e78f53d1SNikolas Klauser unsigned __clz = __bits_per_word - __first.__ctz_; 457e78f53d1SNikolas Klauser difference_type __dn = std::min(static_cast<difference_type>(__clz), __n); 458e78f53d1SNikolas Klauser __n -= __dn; 459e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 460e78f53d1SNikolas Klauser __storage_type __b1 = *__first.__seg_ & __m; 461e78f53d1SNikolas Klauser *__first.__seg_ &= ~__m; 462e78f53d1SNikolas Klauser __storage_type __b2 = *__result.__seg_ & __m; 463e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 464e78f53d1SNikolas Klauser *__result.__seg_ |= __b1; 465e78f53d1SNikolas Klauser *__first.__seg_ |= __b2; 466e78f53d1SNikolas Klauser __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 467e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 468e78f53d1SNikolas Klauser ++__first.__seg_; 469e78f53d1SNikolas Klauser // __first.__ctz_ = 0; 470e78f53d1SNikolas Klauser } 471e78f53d1SNikolas Klauser // __first.__ctz_ == 0; 472e78f53d1SNikolas Klauser // do middle words 473e78f53d1SNikolas Klauser for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) 474e78f53d1SNikolas Klauser swap(*__first.__seg_, *__result.__seg_); 475e78f53d1SNikolas Klauser // do last word 476e78f53d1SNikolas Klauser if (__n > 0) { 477e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 478e78f53d1SNikolas Klauser __storage_type __b1 = *__first.__seg_ & __m; 479e78f53d1SNikolas Klauser *__first.__seg_ &= ~__m; 480e78f53d1SNikolas Klauser __storage_type __b2 = *__result.__seg_ & __m; 481e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 482e78f53d1SNikolas Klauser *__result.__seg_ |= __b1; 483e78f53d1SNikolas Klauser *__first.__seg_ |= __b2; 484e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(__n); 485e78f53d1SNikolas Klauser } 486e78f53d1SNikolas Klauser } 487e78f53d1SNikolas Klauser return __result; 488e78f53d1SNikolas Klauser} 489e78f53d1SNikolas Klauser 490e78f53d1SNikolas Klausertemplate <class _Cl, class _Cr> 491e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned( 492e78f53d1SNikolas Klauser __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { 493e78f53d1SNikolas Klauser using _I1 = __bit_iterator<_Cl, false>; 494e78f53d1SNikolas Klauser using difference_type = typename _I1::difference_type; 495e78f53d1SNikolas Klauser using __storage_type = typename _I1::__storage_type; 496e78f53d1SNikolas Klauser 497e78f53d1SNikolas Klauser const int __bits_per_word = _I1::__bits_per_word; 498e78f53d1SNikolas Klauser difference_type __n = __last - __first; 499e78f53d1SNikolas Klauser if (__n > 0) { 500e78f53d1SNikolas Klauser // do first word 501e78f53d1SNikolas Klauser if (__first.__ctz_ != 0) { 502e78f53d1SNikolas Klauser unsigned __clz_f = __bits_per_word - __first.__ctz_; 503e78f53d1SNikolas Klauser difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n); 504e78f53d1SNikolas Klauser __n -= __dn; 505e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 506e78f53d1SNikolas Klauser __storage_type __b1 = *__first.__seg_ & __m; 507e78f53d1SNikolas Klauser *__first.__seg_ &= ~__m; 508e78f53d1SNikolas Klauser unsigned __clz_r = __bits_per_word - __result.__ctz_; 509e78f53d1SNikolas Klauser __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); 510e78f53d1SNikolas Klauser __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 511e78f53d1SNikolas Klauser __storage_type __b2 = *__result.__seg_ & __m; 512e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 513e78f53d1SNikolas Klauser if (__result.__ctz_ > __first.__ctz_) { 514e78f53d1SNikolas Klauser unsigned __s = __result.__ctz_ - __first.__ctz_; 515e78f53d1SNikolas Klauser *__result.__seg_ |= __b1 << __s; 516e78f53d1SNikolas Klauser *__first.__seg_ |= __b2 >> __s; 517e78f53d1SNikolas Klauser } else { 518e78f53d1SNikolas Klauser unsigned __s = __first.__ctz_ - __result.__ctz_; 519e78f53d1SNikolas Klauser *__result.__seg_ |= __b1 >> __s; 520e78f53d1SNikolas Klauser *__first.__seg_ |= __b2 << __s; 521e78f53d1SNikolas Klauser } 522e78f53d1SNikolas Klauser __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; 523e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); 524e78f53d1SNikolas Klauser __dn -= __ddn; 525e78f53d1SNikolas Klauser if (__dn > 0) { 526e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __dn); 527e78f53d1SNikolas Klauser __b2 = *__result.__seg_ & __m; 528e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 529e78f53d1SNikolas Klauser unsigned __s = __first.__ctz_ + __ddn; 530e78f53d1SNikolas Klauser *__result.__seg_ |= __b1 >> __s; 531e78f53d1SNikolas Klauser *__first.__seg_ |= __b2 << __s; 532e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(__dn); 533e78f53d1SNikolas Klauser } 534e78f53d1SNikolas Klauser ++__first.__seg_; 535e78f53d1SNikolas Klauser // __first.__ctz_ = 0; 536e78f53d1SNikolas Klauser } 537e78f53d1SNikolas Klauser // __first.__ctz_ == 0; 538e78f53d1SNikolas Klauser // do middle words 539e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) << __result.__ctz_; 540e78f53d1SNikolas Klauser unsigned __clz_r = __bits_per_word - __result.__ctz_; 541e78f53d1SNikolas Klauser for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) { 542e78f53d1SNikolas Klauser __storage_type __b1 = *__first.__seg_; 543e78f53d1SNikolas Klauser __storage_type __b2 = *__result.__seg_ & __m; 544e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 545e78f53d1SNikolas Klauser *__result.__seg_ |= __b1 << __result.__ctz_; 546e78f53d1SNikolas Klauser *__first.__seg_ = __b2 >> __result.__ctz_; 547e78f53d1SNikolas Klauser ++__result.__seg_; 548e78f53d1SNikolas Klauser __b2 = *__result.__seg_ & ~__m; 549e78f53d1SNikolas Klauser *__result.__seg_ &= __m; 550e78f53d1SNikolas Klauser *__result.__seg_ |= __b1 >> __clz_r; 551e78f53d1SNikolas Klauser *__first.__seg_ |= __b2 << __clz_r; 552e78f53d1SNikolas Klauser } 553e78f53d1SNikolas Klauser // do last word 554e78f53d1SNikolas Klauser if (__n > 0) { 555e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __n); 556e78f53d1SNikolas Klauser __storage_type __b1 = *__first.__seg_ & __m; 557e78f53d1SNikolas Klauser *__first.__seg_ &= ~__m; 558e78f53d1SNikolas Klauser __storage_type __dn = std::min<__storage_type>(__n, __clz_r); 559e78f53d1SNikolas Klauser __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 560e78f53d1SNikolas Klauser __storage_type __b2 = *__result.__seg_ & __m; 561e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 562e78f53d1SNikolas Klauser *__result.__seg_ |= __b1 << __result.__ctz_; 563e78f53d1SNikolas Klauser *__first.__seg_ |= __b2 >> __result.__ctz_; 564e78f53d1SNikolas Klauser __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; 565e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); 566e78f53d1SNikolas Klauser __n -= __dn; 567e78f53d1SNikolas Klauser if (__n > 0) { 568e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __n); 569e78f53d1SNikolas Klauser __b2 = *__result.__seg_ & __m; 570e78f53d1SNikolas Klauser *__result.__seg_ &= ~__m; 571e78f53d1SNikolas Klauser *__result.__seg_ |= __b1 >> __dn; 572e78f53d1SNikolas Klauser *__first.__seg_ |= __b2 << __dn; 573e78f53d1SNikolas Klauser __result.__ctz_ = static_cast<unsigned>(__n); 574e78f53d1SNikolas Klauser } 575e78f53d1SNikolas Klauser } 576e78f53d1SNikolas Klauser } 577e78f53d1SNikolas Klauser return __result; 578e78f53d1SNikolas Klauser} 579e78f53d1SNikolas Klauser 580e78f53d1SNikolas Klausertemplate <class _Cl, class _Cr> 581e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges( 582e78f53d1SNikolas Klauser __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) { 583e78f53d1SNikolas Klauser if (__first1.__ctz_ == __first2.__ctz_) 584e78f53d1SNikolas Klauser return std::__swap_ranges_aligned(__first1, __last1, __first2); 585e78f53d1SNikolas Klauser return std::__swap_ranges_unaligned(__first1, __last1, __first2); 586e78f53d1SNikolas Klauser} 587e78f53d1SNikolas Klauser 588e78f53d1SNikolas Klauser// rotate 589e78f53d1SNikolas Klauser 590e78f53d1SNikolas Klausertemplate <class _Cp> 591e78f53d1SNikolas Klauserstruct __bit_array { 592e78f53d1SNikolas Klauser using difference_type = typename _Cp::difference_type; 593e78f53d1SNikolas Klauser using __storage_type = typename _Cp::__storage_type; 594e78f53d1SNikolas Klauser using __storage_pointer = typename _Cp::__storage_pointer; 595e78f53d1SNikolas Klauser using iterator = typename _Cp::iterator; 596e78f53d1SNikolas Klauser 597e78f53d1SNikolas Klauser static const unsigned __bits_per_word = _Cp::__bits_per_word; 598e78f53d1SNikolas Klauser static const unsigned _Np = 4; 599e78f53d1SNikolas Klauser 600e78f53d1SNikolas Klauser difference_type __size_; 601e78f53d1SNikolas Klauser __storage_type __word_[_Np]; 602e78f53d1SNikolas Klauser 603e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() { 604e78f53d1SNikolas Klauser return static_cast<difference_type>(_Np * __bits_per_word); 605e78f53d1SNikolas Klauser } 606e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) { 607e78f53d1SNikolas Klauser if (__libcpp_is_constant_evaluated()) { 608e78f53d1SNikolas Klauser for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i) 609e78f53d1SNikolas Klauser std::__construct_at(__word_ + __i, 0); 610e78f53d1SNikolas Klauser } 611e78f53d1SNikolas Klauser } 612e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() { 613e78f53d1SNikolas Klauser return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); 614e78f53d1SNikolas Klauser } 615e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() { 616e78f53d1SNikolas Klauser return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, 617e78f53d1SNikolas Klauser static_cast<unsigned>(__size_ % __bits_per_word)); 618e78f53d1SNikolas Klauser } 619e78f53d1SNikolas Klauser}; 620e78f53d1SNikolas Klauser 621e78f53d1SNikolas Klausertemplate <class _Cp> 622e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> 623e78f53d1SNikolas Klauserrotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) { 624e78f53d1SNikolas Klauser using _I1 = __bit_iterator<_Cp, false>; 625e78f53d1SNikolas Klauser using difference_type = typename _I1::difference_type; 626e78f53d1SNikolas Klauser 627e78f53d1SNikolas Klauser difference_type __d1 = __middle - __first; 628e78f53d1SNikolas Klauser difference_type __d2 = __last - __middle; 629e78f53d1SNikolas Klauser _I1 __r = __first + __d2; 630e78f53d1SNikolas Klauser while (__d1 != 0 && __d2 != 0) { 631e78f53d1SNikolas Klauser if (__d1 <= __d2) { 632e78f53d1SNikolas Klauser if (__d1 <= __bit_array<_Cp>::capacity()) { 633e78f53d1SNikolas Klauser __bit_array<_Cp> __b(__d1); 634e78f53d1SNikolas Klauser std::copy(__first, __middle, __b.begin()); 635e78f53d1SNikolas Klauser std::copy(__b.begin(), __b.end(), std::copy(__middle, __last, __first)); 636e78f53d1SNikolas Klauser break; 637e78f53d1SNikolas Klauser } else { 638e78f53d1SNikolas Klauser __bit_iterator<_Cp, false> __mp = std::swap_ranges(__first, __middle, __middle); 639e78f53d1SNikolas Klauser __first = __middle; 640e78f53d1SNikolas Klauser __middle = __mp; 641e78f53d1SNikolas Klauser __d2 -= __d1; 642e78f53d1SNikolas Klauser } 643e78f53d1SNikolas Klauser } else { 644e78f53d1SNikolas Klauser if (__d2 <= __bit_array<_Cp>::capacity()) { 645e78f53d1SNikolas Klauser __bit_array<_Cp> __b(__d2); 646e78f53d1SNikolas Klauser std::copy(__middle, __last, __b.begin()); 647e78f53d1SNikolas Klauser std::copy_backward(__b.begin(), __b.end(), std::copy_backward(__first, __middle, __last)); 648e78f53d1SNikolas Klauser break; 649e78f53d1SNikolas Klauser } else { 650e78f53d1SNikolas Klauser __bit_iterator<_Cp, false> __mp = __first + __d2; 651e78f53d1SNikolas Klauser std::swap_ranges(__first, __mp, __middle); 652e78f53d1SNikolas Klauser __first = __mp; 653e78f53d1SNikolas Klauser __d1 -= __d2; 654e78f53d1SNikolas Klauser } 655e78f53d1SNikolas Klauser } 656e78f53d1SNikolas Klauser } 657e78f53d1SNikolas Klauser return __r; 658e78f53d1SNikolas Klauser} 659e78f53d1SNikolas Klauser 660e78f53d1SNikolas Klauser// equal 661e78f53d1SNikolas Klauser 662e78f53d1SNikolas Klausertemplate <class _Cp, bool _IC1, bool _IC2> 663e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_unaligned( 664e78f53d1SNikolas Klauser __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { 665e78f53d1SNikolas Klauser using _It = __bit_iterator<_Cp, _IC1>; 666e78f53d1SNikolas Klauser using difference_type = typename _It::difference_type; 667e78f53d1SNikolas Klauser using __storage_type = typename _It::__storage_type; 668e78f53d1SNikolas Klauser 669e78f53d1SNikolas Klauser const int __bits_per_word = _It::__bits_per_word; 670e78f53d1SNikolas Klauser difference_type __n = __last1 - __first1; 671e78f53d1SNikolas Klauser if (__n > 0) { 672e78f53d1SNikolas Klauser // do first word 673e78f53d1SNikolas Klauser if (__first1.__ctz_ != 0) { 674e78f53d1SNikolas Klauser unsigned __clz_f = __bits_per_word - __first1.__ctz_; 675e78f53d1SNikolas Klauser difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n); 676e78f53d1SNikolas Klauser __n -= __dn; 677e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); 678e78f53d1SNikolas Klauser __storage_type __b = *__first1.__seg_ & __m; 679e78f53d1SNikolas Klauser unsigned __clz_r = __bits_per_word - __first2.__ctz_; 680e78f53d1SNikolas Klauser __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); 681e78f53d1SNikolas Klauser __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); 682e78f53d1SNikolas Klauser if (__first2.__ctz_ > __first1.__ctz_) { 683e78f53d1SNikolas Klauser if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) 684e78f53d1SNikolas Klauser return false; 685e78f53d1SNikolas Klauser } else { 686e78f53d1SNikolas Klauser if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) 687e78f53d1SNikolas Klauser return false; 688e78f53d1SNikolas Klauser } 689e78f53d1SNikolas Klauser __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; 690e78f53d1SNikolas Klauser __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word); 691e78f53d1SNikolas Klauser __dn -= __ddn; 692e78f53d1SNikolas Klauser if (__dn > 0) { 693e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __dn); 694e78f53d1SNikolas Klauser if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) 695e78f53d1SNikolas Klauser return false; 696e78f53d1SNikolas Klauser __first2.__ctz_ = static_cast<unsigned>(__dn); 697e78f53d1SNikolas Klauser } 698e78f53d1SNikolas Klauser ++__first1.__seg_; 699e78f53d1SNikolas Klauser // __first1.__ctz_ = 0; 700e78f53d1SNikolas Klauser } 701e78f53d1SNikolas Klauser // __first1.__ctz_ == 0; 702e78f53d1SNikolas Klauser // do middle words 703e78f53d1SNikolas Klauser unsigned __clz_r = __bits_per_word - __first2.__ctz_; 704e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) << __first2.__ctz_; 705e78f53d1SNikolas Klauser for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) { 706e78f53d1SNikolas Klauser __storage_type __b = *__first1.__seg_; 707e78f53d1SNikolas Klauser if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) 708e78f53d1SNikolas Klauser return false; 709e78f53d1SNikolas Klauser ++__first2.__seg_; 710e78f53d1SNikolas Klauser if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) 711e78f53d1SNikolas Klauser return false; 712e78f53d1SNikolas Klauser } 713e78f53d1SNikolas Klauser // do last word 714e78f53d1SNikolas Klauser if (__n > 0) { 715e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __n); 716e78f53d1SNikolas Klauser __storage_type __b = *__first1.__seg_ & __m; 717e78f53d1SNikolas Klauser __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r)); 718e78f53d1SNikolas Klauser __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); 719e78f53d1SNikolas Klauser if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) 720e78f53d1SNikolas Klauser return false; 721e78f53d1SNikolas Klauser __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; 722e78f53d1SNikolas Klauser __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word); 723e78f53d1SNikolas Klauser __n -= __dn; 724e78f53d1SNikolas Klauser if (__n > 0) { 725e78f53d1SNikolas Klauser __m = ~__storage_type(0) >> (__bits_per_word - __n); 726e78f53d1SNikolas Klauser if ((*__first2.__seg_ & __m) != (__b >> __dn)) 727e78f53d1SNikolas Klauser return false; 728e78f53d1SNikolas Klauser } 729e78f53d1SNikolas Klauser } 730e78f53d1SNikolas Klauser } 731e78f53d1SNikolas Klauser return true; 732e78f53d1SNikolas Klauser} 733e78f53d1SNikolas Klauser 734e78f53d1SNikolas Klausertemplate <class _Cp, bool _IC1, bool _IC2> 735e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_aligned( 736e78f53d1SNikolas Klauser __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { 737e78f53d1SNikolas Klauser using _It = __bit_iterator<_Cp, _IC1>; 738e78f53d1SNikolas Klauser using difference_type = typename _It::difference_type; 739e78f53d1SNikolas Klauser using __storage_type = typename _It::__storage_type; 740e78f53d1SNikolas Klauser 741e78f53d1SNikolas Klauser const int __bits_per_word = _It::__bits_per_word; 742e78f53d1SNikolas Klauser difference_type __n = __last1 - __first1; 743e78f53d1SNikolas Klauser if (__n > 0) { 744e78f53d1SNikolas Klauser // do first word 745e78f53d1SNikolas Klauser if (__first1.__ctz_ != 0) { 746e78f53d1SNikolas Klauser unsigned __clz = __bits_per_word - __first1.__ctz_; 747e78f53d1SNikolas Klauser difference_type __dn = std::min(static_cast<difference_type>(__clz), __n); 748e78f53d1SNikolas Klauser __n -= __dn; 749e78f53d1SNikolas Klauser __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); 750e78f53d1SNikolas Klauser if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) 751e78f53d1SNikolas Klauser return false; 752e78f53d1SNikolas Klauser ++__first2.__seg_; 753e78f53d1SNikolas Klauser ++__first1.__seg_; 754e78f53d1SNikolas Klauser // __first1.__ctz_ = 0; 755e78f53d1SNikolas Klauser // __first2.__ctz_ = 0; 756e78f53d1SNikolas Klauser } 757e78f53d1SNikolas Klauser // __first1.__ctz_ == 0; 758e78f53d1SNikolas Klauser // __first2.__ctz_ == 0; 759e78f53d1SNikolas Klauser // do middle words 760e78f53d1SNikolas Klauser for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) 761e78f53d1SNikolas Klauser if (*__first2.__seg_ != *__first1.__seg_) 762e78f53d1SNikolas Klauser return false; 763e78f53d1SNikolas Klauser // do last word 764e78f53d1SNikolas Klauser if (__n > 0) { 765e78f53d1SNikolas Klauser __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); 766e78f53d1SNikolas Klauser if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) 767e78f53d1SNikolas Klauser return false; 768e78f53d1SNikolas Klauser } 769e78f53d1SNikolas Klauser } 770e78f53d1SNikolas Klauser return true; 771e78f53d1SNikolas Klauser} 772e78f53d1SNikolas Klauser 773e78f53d1SNikolas Klausertemplate <class _Cp, bool _IC1, bool _IC2> 774e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool 775e78f53d1SNikolas Klauserequal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { 776e78f53d1SNikolas Klauser if (__first1.__ctz_ == __first2.__ctz_) 777e78f53d1SNikolas Klauser return std::__equal_aligned(__first1, __last1, __first2); 778e78f53d1SNikolas Klauser return std::__equal_unaligned(__first1, __last1, __first2); 779e78f53d1SNikolas Klauser} 780e78f53d1SNikolas Klauser 781e78f53d1SNikolas Klausertemplate <class _Cp, bool _IsConst, typename _Cp::__storage_type> 782e78f53d1SNikolas Klauserclass __bit_iterator { 783e78f53d1SNikolas Klauserpublic: 784e78f53d1SNikolas Klauser using difference_type = typename _Cp::difference_type; 785e78f53d1SNikolas Klauser using value_type = bool; 786e78f53d1SNikolas Klauser using pointer = __bit_iterator; 787e78f53d1SNikolas Klauser#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL 788e78f53d1SNikolas Klauser using reference = __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >; 789e78f53d1SNikolas Klauser#else 790e78f53d1SNikolas Klauser using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >; 791e78f53d1SNikolas Klauser#endif 792e78f53d1SNikolas Klauser using iterator_category = random_access_iterator_tag; 793e78f53d1SNikolas Klauser 794e78f53d1SNikolas Klauserprivate: 795e78f53d1SNikolas Klauser using __storage_type = typename _Cp::__storage_type; 796e78f53d1SNikolas Klauser using __storage_pointer = 797e78f53d1SNikolas Klauser __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>; 798e78f53d1SNikolas Klauser 799e78f53d1SNikolas Klauser static const unsigned __bits_per_word = _Cp::__bits_per_word; 800e78f53d1SNikolas Klauser 801e78f53d1SNikolas Klauser __storage_pointer __seg_; 802e78f53d1SNikolas Klauser unsigned __ctz_; 803e78f53d1SNikolas Klauser 804e78f53d1SNikolas Klauserpublic: 805e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT 806e78f53d1SNikolas Klauser#if _LIBCPP_STD_VER >= 14 807e78f53d1SNikolas Klauser : __seg_(nullptr), 808e78f53d1SNikolas Klauser __ctz_(0) 809e78f53d1SNikolas Klauser#endif 810e78f53d1SNikolas Klauser { 811e78f53d1SNikolas Klauser } 812e78f53d1SNikolas Klauser 813e78f53d1SNikolas Klauser // When _IsConst=false, this is the copy constructor. 814e78f53d1SNikolas Klauser // It is non-trivial. Making it trivial would break ABI. 815e78f53d1SNikolas Klauser // When _IsConst=true, this is a converting constructor; 816e78f53d1SNikolas Klauser // the copy and move constructors are implicitly generated 817e78f53d1SNikolas Klauser // and trivial. 818e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT 819e78f53d1SNikolas Klauser : __seg_(__it.__seg_), 820e78f53d1SNikolas Klauser __ctz_(__it.__ctz_) {} 821e78f53d1SNikolas Klauser 822e78f53d1SNikolas Klauser // When _IsConst=false, we have a user-provided copy constructor, 823e78f53d1SNikolas Klauser // so we must also provide a copy assignment operator because 824e78f53d1SNikolas Klauser // the implicit generation of a defaulted one is deprecated. 825e78f53d1SNikolas Klauser // When _IsConst=true, the assignment operators are 826e78f53d1SNikolas Klauser // implicitly generated and trivial. 827e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& 828e78f53d1SNikolas Klauser operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) { 829e78f53d1SNikolas Klauser __seg_ = __it.__seg_; 830e78f53d1SNikolas Klauser __ctz_ = __it.__ctz_; 831e78f53d1SNikolas Klauser return *this; 832e78f53d1SNikolas Klauser } 833e78f53d1SNikolas Klauser 834e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT { 835e78f53d1SNikolas Klauser return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >( 836e78f53d1SNikolas Klauser __seg_, __storage_type(1) << __ctz_); 837e78f53d1SNikolas Klauser } 838e78f53d1SNikolas Klauser 839e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() { 840e78f53d1SNikolas Klauser if (__ctz_ != __bits_per_word - 1) 841e78f53d1SNikolas Klauser ++__ctz_; 842e78f53d1SNikolas Klauser else { 843e78f53d1SNikolas Klauser __ctz_ = 0; 844e78f53d1SNikolas Klauser ++__seg_; 845e78f53d1SNikolas Klauser } 846e78f53d1SNikolas Klauser return *this; 847e78f53d1SNikolas Klauser } 848e78f53d1SNikolas Klauser 849e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) { 850e78f53d1SNikolas Klauser __bit_iterator __tmp = *this; 851e78f53d1SNikolas Klauser ++(*this); 852e78f53d1SNikolas Klauser return __tmp; 853e78f53d1SNikolas Klauser } 854e78f53d1SNikolas Klauser 855e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() { 856e78f53d1SNikolas Klauser if (__ctz_ != 0) 857e78f53d1SNikolas Klauser --__ctz_; 858e78f53d1SNikolas Klauser else { 859e78f53d1SNikolas Klauser __ctz_ = __bits_per_word - 1; 860e78f53d1SNikolas Klauser --__seg_; 861e78f53d1SNikolas Klauser } 862e78f53d1SNikolas Klauser return *this; 863e78f53d1SNikolas Klauser } 864e78f53d1SNikolas Klauser 865e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) { 866e78f53d1SNikolas Klauser __bit_iterator __tmp = *this; 867e78f53d1SNikolas Klauser --(*this); 868e78f53d1SNikolas Klauser return __tmp; 869e78f53d1SNikolas Klauser } 870e78f53d1SNikolas Klauser 871e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) { 872e78f53d1SNikolas Klauser if (__n >= 0) 873e78f53d1SNikolas Klauser __seg_ += (__n + __ctz_) / __bits_per_word; 874e78f53d1SNikolas Klauser else 875e78f53d1SNikolas Klauser __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) / 876e78f53d1SNikolas Klauser static_cast<difference_type>(__bits_per_word); 877e78f53d1SNikolas Klauser __n &= (__bits_per_word - 1); 878e78f53d1SNikolas Klauser __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word); 879e78f53d1SNikolas Klauser return *this; 880e78f53d1SNikolas Klauser } 881e78f53d1SNikolas Klauser 882e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) { 883e78f53d1SNikolas Klauser return *this += -__n; 884e78f53d1SNikolas Klauser } 885e78f53d1SNikolas Klauser 886e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const { 887e78f53d1SNikolas Klauser __bit_iterator __t(*this); 888e78f53d1SNikolas Klauser __t += __n; 889e78f53d1SNikolas Klauser return __t; 890e78f53d1SNikolas Klauser } 891e78f53d1SNikolas Klauser 892e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const { 893e78f53d1SNikolas Klauser __bit_iterator __t(*this); 894e78f53d1SNikolas Klauser __t -= __n; 895e78f53d1SNikolas Klauser return __t; 896e78f53d1SNikolas Klauser } 897e78f53d1SNikolas Klauser 898e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator 899e78f53d1SNikolas Klauser operator+(difference_type __n, const __bit_iterator& __it) { 900e78f53d1SNikolas Klauser return __it + __n; 901e78f53d1SNikolas Klauser } 902e78f53d1SNikolas Klauser 903e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend difference_type 904e78f53d1SNikolas Klauser operator-(const __bit_iterator& __x, const __bit_iterator& __y) { 905e78f53d1SNikolas Klauser return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_; 906e78f53d1SNikolas Klauser } 907e78f53d1SNikolas Klauser 908e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const { 909e78f53d1SNikolas Klauser return *(*this + __n); 910e78f53d1SNikolas Klauser } 911e78f53d1SNikolas Klauser 912e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 913e78f53d1SNikolas Klauser operator==(const __bit_iterator& __x, const __bit_iterator& __y) { 914e78f53d1SNikolas Klauser return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_; 915e78f53d1SNikolas Klauser } 916e78f53d1SNikolas Klauser 917e78f53d1SNikolas Klauser#if _LIBCPP_STD_VER <= 17 918e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 919e78f53d1SNikolas Klauser operator!=(const __bit_iterator& __x, const __bit_iterator& __y) { 920e78f53d1SNikolas Klauser return !(__x == __y); 921e78f53d1SNikolas Klauser } 922e78f53d1SNikolas Klauser 923e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 924e78f53d1SNikolas Klauser operator<(const __bit_iterator& __x, const __bit_iterator& __y) { 925e78f53d1SNikolas Klauser return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_); 926e78f53d1SNikolas Klauser } 927e78f53d1SNikolas Klauser 928e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 929e78f53d1SNikolas Klauser operator>(const __bit_iterator& __x, const __bit_iterator& __y) { 930e78f53d1SNikolas Klauser return __y < __x; 931e78f53d1SNikolas Klauser } 932e78f53d1SNikolas Klauser 933e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 934e78f53d1SNikolas Klauser operator<=(const __bit_iterator& __x, const __bit_iterator& __y) { 935e78f53d1SNikolas Klauser return !(__y < __x); 936e78f53d1SNikolas Klauser } 937e78f53d1SNikolas Klauser 938e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 939e78f53d1SNikolas Klauser operator>=(const __bit_iterator& __x, const __bit_iterator& __y) { 940e78f53d1SNikolas Klauser return !(__x < __y); 941e78f53d1SNikolas Klauser } 942e78f53d1SNikolas Klauser#else // _LIBCPP_STD_VER <= 17 943e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering 944e78f53d1SNikolas Klauser operator<=>(const __bit_iterator& __x, const __bit_iterator& __y) { 945e78f53d1SNikolas Klauser if (__x.__seg_ < __y.__seg_) 946e78f53d1SNikolas Klauser return strong_ordering::less; 947e78f53d1SNikolas Klauser 948e78f53d1SNikolas Klauser if (__x.__seg_ == __y.__seg_) 949e78f53d1SNikolas Klauser return __x.__ctz_ <=> __y.__ctz_; 950e78f53d1SNikolas Klauser 951e78f53d1SNikolas Klauser return strong_ordering::greater; 952e78f53d1SNikolas Klauser } 953e78f53d1SNikolas Klauser#endif // _LIBCPP_STD_VER <= 17 954e78f53d1SNikolas Klauser 955e78f53d1SNikolas Klauserprivate: 956e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI 957e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT 958e78f53d1SNikolas Klauser : __seg_(__s), 959e78f53d1SNikolas Klauser __ctz_(__ctz) {} 960e78f53d1SNikolas Klauser 961e78f53d1SNikolas Klauser friend typename _Cp::__self; 962e78f53d1SNikolas Klauser 963e78f53d1SNikolas Klauser friend class __bit_reference<_Cp>; 964e78f53d1SNikolas Klauser friend class __bit_const_reference<_Cp>; 965e78f53d1SNikolas Klauser friend class __bit_iterator<_Cp, true>; 966e78f53d1SNikolas Klauser template <class _Dp> 967e78f53d1SNikolas Klauser friend struct __bit_array; 968e78f53d1SNikolas Klauser 969e78f53d1SNikolas Klauser template <bool _FillVal, class _Dp> 970e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void 971e78f53d1SNikolas Klauser __fill_n_bool(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); 972e78f53d1SNikolas Klauser 973e78f53d1SNikolas Klauser template <class _Dp, bool _IC> 974e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned( 975e78f53d1SNikolas Klauser __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 976e78f53d1SNikolas Klauser template <class _Dp, bool _IC> 977e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_unaligned( 978e78f53d1SNikolas Klauser __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 979e78f53d1SNikolas Klauser template <class _Dp, bool _IC> 980e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> 981e78f53d1SNikolas Klauser copy(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 982e78f53d1SNikolas Klauser template <class _Dp, bool _IC> 983e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned( 984e78f53d1SNikolas Klauser __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 985e78f53d1SNikolas Klauser template <class _Dp, bool _IC> 986e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_unaligned( 987e78f53d1SNikolas Klauser __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 988e78f53d1SNikolas Klauser template <class _Dp, bool _IC> 989e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> 990e78f53d1SNikolas Klauser copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 991e78f53d1SNikolas Klauser template <class _Cl, class _Cr> 992e78f53d1SNikolas Klauser friend __bit_iterator<_Cr, false> 993e78f53d1SNikolas Klauser __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); 994e78f53d1SNikolas Klauser template <class _Cl, class _Cr> 995e78f53d1SNikolas Klauser friend __bit_iterator<_Cr, false> 996e78f53d1SNikolas Klauser __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); 997e78f53d1SNikolas Klauser template <class _Cl, class _Cr> 998e78f53d1SNikolas Klauser friend __bit_iterator<_Cr, false> 999e78f53d1SNikolas Klauser swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); 1000e78f53d1SNikolas Klauser template <class _Dp> 1001e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> 1002e78f53d1SNikolas Klauser rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>); 1003e78f53d1SNikolas Klauser template <class _Dp, bool _IC1, bool _IC2> 1004e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 1005e78f53d1SNikolas Klauser __equal_aligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); 1006e78f53d1SNikolas Klauser template <class _Dp, bool _IC1, bool _IC2> 1007e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 1008e78f53d1SNikolas Klauser __equal_unaligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); 1009e78f53d1SNikolas Klauser template <class _Dp, bool _IC1, bool _IC2> 1010e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 1011e78f53d1SNikolas Klauser equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); 1012e78f53d1SNikolas Klauser template <bool _ToFind, class _Dp, bool _IC> 1013e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC> 1014e78f53d1SNikolas Klauser __find_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); 1015e78f53d1SNikolas Klauser template <bool _ToCount, class _Dp, bool _IC> 1016e78f53d1SNikolas Klauser friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI 1017e78f53d1SNikolas Klauser _LIBCPP_CONSTEXPR_SINCE_CXX20 __count_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); 1018e78f53d1SNikolas Klauser}; 1019e78f53d1SNikolas Klauser 1020e78f53d1SNikolas Klauser_LIBCPP_END_NAMESPACE_STD 1021e78f53d1SNikolas Klauser 1022e78f53d1SNikolas Klauser_LIBCPP_POP_MACROS 1023e78f53d1SNikolas Klauser 1024*ce777190SNikolas Klauser#endif // _LIBCPP___CXX03___BIT_REFERENCE 1025