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