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