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/comp.h> 14#include <__algorithm/copy.h> 15#include <__algorithm/copy_backward.h> 16#include <__algorithm/copy_n.h> 17#include <__algorithm/equal.h> 18#include <__algorithm/min.h> 19#include <__algorithm/rotate.h> 20#include <__algorithm/swap_ranges.h> 21#include <__assert> 22#include <__bit/countr.h> 23#include <__compare/ordering.h> 24#include <__config> 25#include <__cstddef/ptrdiff_t.h> 26#include <__cstddef/size_t.h> 27#include <__functional/identity.h> 28#include <__fwd/bit_reference.h> 29#include <__iterator/iterator_traits.h> 30#include <__memory/construct_at.h> 31#include <__memory/pointer_traits.h> 32#include <__type_traits/conditional.h> 33#include <__type_traits/desugars_to.h> 34#include <__type_traits/enable_if.h> 35#include <__type_traits/is_constant_evaluated.h> 36#include <__type_traits/is_same.h> 37#include <__type_traits/is_unsigned.h> 38#include <__type_traits/void_t.h> 39#include <__utility/pair.h> 40#include <__utility/swap.h> 41#include <climits> 42 43#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 44# pragma GCC system_header 45#endif 46 47_LIBCPP_PUSH_MACROS 48#include <__undef_macros> 49 50_LIBCPP_BEGIN_NAMESPACE_STD 51 52template <class _Cp> 53class __bit_const_reference; 54 55template <class _Tp> 56struct __has_storage_type { 57 static const bool value = false; 58}; 59 60template <class, class> 61struct __size_difference_type_traits { 62 using difference_type = ptrdiff_t; 63 using size_type = size_t; 64}; 65 66template <class _Cp> 67struct __size_difference_type_traits<_Cp, __void_t<typename _Cp::difference_type, typename _Cp::size_type> > { 68 using difference_type = typename _Cp::difference_type; 69 using size_type = typename _Cp::size_type; 70}; 71 72// The `__x_mask` functions are designed to work exclusively with any unsigned `_StorageType`s, including small 73// integral types such as unsigned char/short, `uint8_t`, and `uint16_t`. To prevent undefined behavior or 74// ambiguities due to integral promotions for the small integral types, all intermediate bitwise operations are 75// explicitly cast back to the unsigned `_StorageType`. 76 77// Creates a mask of type `_StorageType` with a specified number of leading zeros (__clz) and sets all remaining 78// bits to one. 79template <class _StorageType> 80_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __trailing_mask(unsigned __clz) { 81 static_assert(is_unsigned<_StorageType>::value, "__trailing_mask only works with unsigned types"); 82 return static_cast<_StorageType>(~static_cast<_StorageType>(0)) >> __clz; 83} 84 85// Creates a mask of type `_StorageType` with a specified number of trailing zeros (__ctz) and sets all remaining 86// bits to one. 87template <class _StorageType> 88_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __leading_mask(unsigned __ctz) { 89 static_assert(is_unsigned<_StorageType>::value, "__leading_mask only works with unsigned types"); 90 return static_cast<_StorageType>(~static_cast<_StorageType>(0)) << __ctz; 91} 92 93// Creates a mask of type `_StorageType` with a specified number of leading zeros (__clz), a specified number of 94// trailing zeros (__ctz), and sets all bits in between to one. 95template <class _StorageType> 96_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _StorageType __middle_mask(unsigned __clz, unsigned __ctz) { 97 static_assert(is_unsigned<_StorageType>::value, "__middle_mask only works with unsigned types"); 98 return std::__leading_mask<_StorageType>(__ctz) & std::__trailing_mask<_StorageType>(__clz); 99} 100 101// This function is designed to operate correctly even for smaller integral types like `uint8_t`, `uint16_t`, 102// or `unsigned short`. 103// See https://github.com/llvm/llvm-project/pull/122410. 104template <class _StoragePointer> 105_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void 106__fill_masked_range(_StoragePointer __word, unsigned __clz, unsigned __ctz, bool __fill_val) { 107 static_assert(is_unsigned<typename pointer_traits<_StoragePointer>::element_type>::value, 108 "__fill_masked_range must be called with unsigned type"); 109 using _StorageType = typename pointer_traits<_StoragePointer>::element_type; 110 _LIBCPP_ASSERT_VALID_INPUT_RANGE( 111 __ctz + __clz < sizeof(_StorageType) * CHAR_BIT, "__fill_masked_range called with invalid range"); 112 _StorageType __m = std::__middle_mask<_StorageType>(__clz, __ctz); 113 if (__fill_val) 114 *__word |= __m; 115 else 116 *__word &= ~__m; 117} 118 119template <class _Cp, bool = __has_storage_type<_Cp>::value> 120class __bit_reference { 121 using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type; 122 using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__storage_pointer; 123 124 __storage_pointer __seg_; 125 __storage_type __mask_; 126 127 friend typename _Cp::__self; 128 129 friend class __bit_const_reference<_Cp>; 130 friend class __bit_iterator<_Cp, false>; 131 132public: 133 using __container _LIBCPP_NODEBUG = typename _Cp::__self; 134 135 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference(const __bit_reference&) = default; 136 137 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT { 138 return static_cast<bool>(*__seg_ & __mask_); 139 } 140 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT { 141 return !static_cast<bool>(*this); 142 } 143 144 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(bool __x) _NOEXCEPT { 145 if (__x) 146 *__seg_ |= __mask_; 147 else 148 *__seg_ &= ~__mask_; 149 return *this; 150 } 151 152#if _LIBCPP_STD_VER >= 23 153 _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept { 154 if (__x) 155 *__seg_ |= __mask_; 156 else 157 *__seg_ &= ~__mask_; 158 return *this; 159 } 160#endif 161 162 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT { 163 return operator=(static_cast<bool>(__x)); 164 } 165 166 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT { *__seg_ ^= __mask_; } 167 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT { 168 return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__countr_zero(__mask_))); 169 } 170 171private: 172 _LIBCPP_HIDE_FROM_ABI 173 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 174 : __seg_(__s), 175 __mask_(__m) {} 176}; 177 178template <class _Cp> 179class __bit_reference<_Cp, false> {}; 180 181template <class _Cp> 182inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 183swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT { 184 bool __t = __x; 185 __x = __y; 186 __y = __t; 187} 188 189template <class _Cp, class _Dp> 190inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void 191swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT { 192 bool __t = __x; 193 __x = __y; 194 __y = __t; 195} 196 197template <class _Cp> 198inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT { 199 bool __t = __x; 200 __x = __y; 201 __y = __t; 202} 203 204template <class _Cp> 205inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT { 206 bool __t = __x; 207 __x = __y; 208 __y = __t; 209} 210 211template <class _Cp> 212class __bit_const_reference { 213 using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type; 214 using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__const_storage_pointer; 215 216 __storage_pointer __seg_; 217 __storage_type __mask_; 218 219 friend typename _Cp::__self; 220 friend class __bit_iterator<_Cp, true>; 221 222public: 223 using __container _LIBCPP_NODEBUG = typename _Cp::__self; 224 225 _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_const_reference&) = default; 226 __bit_const_reference& operator=(const __bit_const_reference&) = delete; 227 228 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT 229 : __seg_(__x.__seg_), 230 __mask_(__x.__mask_) {} 231 232 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT { 233 return static_cast<bool>(*__seg_ & __mask_); 234 } 235 236 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT { 237 return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__countr_zero(__mask_))); 238 } 239 240private: 241 _LIBCPP_HIDE_FROM_ABI 242 _LIBCPP_CONSTEXPR explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT 243 : __seg_(__s), 244 __mask_(__m) {} 245}; 246 247template <class _Cp> 248struct __bit_array { 249 using difference_type _LIBCPP_NODEBUG = typename __size_difference_type_traits<_Cp>::difference_type; 250 using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type; 251 using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__storage_pointer; 252 using iterator _LIBCPP_NODEBUG = typename _Cp::iterator; 253 254 static const unsigned __bits_per_word = _Cp::__bits_per_word; 255 static const unsigned _Np = 4; 256 257 difference_type __size_; 258 __storage_type __word_[_Np]; 259 260 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() { 261 return static_cast<difference_type>(_Np * __bits_per_word); 262 } 263 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) { 264 if (__libcpp_is_constant_evaluated()) { 265 for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i) 266 std::__construct_at(__word_ + __i, 0); 267 } 268 } 269 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() { 270 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); 271 } 272 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() { 273 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, 274 static_cast<unsigned>(__size_ % __bits_per_word)); 275 } 276}; 277 278template <class _Cp, bool _IsConst, typename _Cp::__storage_type> 279class __bit_iterator { 280public: 281 using difference_type = typename __size_difference_type_traits<_Cp>::difference_type; 282 using value_type = bool; 283 using pointer = __bit_iterator; 284#ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL 285 using reference = __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >; 286#else 287 using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >; 288#endif 289 using iterator_category = random_access_iterator_tag; 290 291private: 292 using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type; 293 using __storage_pointer _LIBCPP_NODEBUG = 294 __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>; 295 296 static const unsigned __bits_per_word = _Cp::__bits_per_word; 297 298 __storage_pointer __seg_; 299 unsigned __ctz_; 300 301public: 302 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT 303#if _LIBCPP_STD_VER >= 14 304 : __seg_(nullptr), 305 __ctz_(0) 306#endif 307 { 308 } 309 310 // When _IsConst=false, this is the copy constructor. 311 // It is non-trivial. Making it trivial would break ABI. 312 // When _IsConst=true, this is a converting constructor; 313 // the copy and move constructors are implicitly generated 314 // and trivial. 315 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT 316 : __seg_(__it.__seg_), 317 __ctz_(__it.__ctz_) {} 318 319 // When _IsConst=false, we have a user-provided copy constructor, 320 // so we must also provide a copy assignment operator because 321 // the implicit generation of a defaulted one is deprecated. 322 // When _IsConst=true, the assignment operators are 323 // implicitly generated and trivial. 324 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& 325 operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) { 326 __seg_ = __it.__seg_; 327 __ctz_ = __it.__ctz_; 328 return *this; 329 } 330 331 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT { 332 _LIBCPP_ASSERT_INTERNAL(__ctz_ < __bits_per_word, "Dereferencing an invalid __bit_iterator."); 333 return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >( 334 __seg_, __storage_type(1) << __ctz_); 335 } 336 337 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() { 338 if (__ctz_ != __bits_per_word - 1) 339 ++__ctz_; 340 else { 341 __ctz_ = 0; 342 ++__seg_; 343 } 344 return *this; 345 } 346 347 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) { 348 __bit_iterator __tmp = *this; 349 ++(*this); 350 return __tmp; 351 } 352 353 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() { 354 if (__ctz_ != 0) 355 --__ctz_; 356 else { 357 __ctz_ = __bits_per_word - 1; 358 --__seg_; 359 } 360 return *this; 361 } 362 363 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) { 364 __bit_iterator __tmp = *this; 365 --(*this); 366 return __tmp; 367 } 368 369 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) { 370 if (__n >= 0) 371 __seg_ += (__n + __ctz_) / __bits_per_word; 372 else 373 __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) / 374 static_cast<difference_type>(__bits_per_word); 375 __n &= (__bits_per_word - 1); 376 __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word); 377 return *this; 378 } 379 380 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) { 381 return *this += -__n; 382 } 383 384 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const { 385 __bit_iterator __t(*this); 386 __t += __n; 387 return __t; 388 } 389 390 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const { 391 __bit_iterator __t(*this); 392 __t -= __n; 393 return __t; 394 } 395 396 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator 397 operator+(difference_type __n, const __bit_iterator& __it) { 398 return __it + __n; 399 } 400 401 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend difference_type 402 operator-(const __bit_iterator& __x, const __bit_iterator& __y) { 403 return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_; 404 } 405 406 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const { 407 return *(*this + __n); 408 } 409 410 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 411 operator==(const __bit_iterator& __x, const __bit_iterator& __y) { 412 return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_; 413 } 414 415#if _LIBCPP_STD_VER <= 17 416 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 417 operator!=(const __bit_iterator& __x, const __bit_iterator& __y) { 418 return !(__x == __y); 419 } 420 421 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 422 operator<(const __bit_iterator& __x, const __bit_iterator& __y) { 423 return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_); 424 } 425 426 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 427 operator>(const __bit_iterator& __x, const __bit_iterator& __y) { 428 return __y < __x; 429 } 430 431 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 432 operator<=(const __bit_iterator& __x, const __bit_iterator& __y) { 433 return !(__y < __x); 434 } 435 436 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 437 operator>=(const __bit_iterator& __x, const __bit_iterator& __y) { 438 return !(__x < __y); 439 } 440#else // _LIBCPP_STD_VER <= 17 441 _LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering 442 operator<=>(const __bit_iterator& __x, const __bit_iterator& __y) { 443 if (__x.__seg_ < __y.__seg_) 444 return strong_ordering::less; 445 446 if (__x.__seg_ == __y.__seg_) 447 return __x.__ctz_ <=> __y.__ctz_; 448 449 return strong_ordering::greater; 450 } 451#endif // _LIBCPP_STD_VER <= 17 452 453private: 454 _LIBCPP_HIDE_FROM_ABI 455 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT 456 : __seg_(__s), 457 __ctz_(__ctz) { 458 _LIBCPP_ASSERT_INTERNAL( 459 __ctz_ < __bits_per_word, "__bit_iterator initialized with an invalid number of trailing zeros."); 460 } 461 462 friend typename _Cp::__self; 463 464 friend class __bit_reference<_Cp>; 465 friend class __bit_const_reference<_Cp>; 466 friend class __bit_iterator<_Cp, true>; 467 template <class _Dp> 468 friend struct __bit_array; 469 470 template <bool _FillVal, class _Dp> 471 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void 472 __fill_n_bool(__bit_iterator<_Dp, false> __first, typename __size_difference_type_traits<_Dp>::size_type __n); 473 474 template <class _Dp, bool _IC> 475 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned( 476 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 477 template <class _Dp, bool _IC> 478 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_unaligned( 479 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 480 template <class _Dp, bool _IC> 481 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend pair<__bit_iterator<_Dp, _IC>, __bit_iterator<_Dp, false> > 482 __copy_impl::operator()( 483 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result) const; 484 template <class _Dp, bool _IC> 485 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned( 486 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 487 template <class _Dp, bool _IC> 488 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_unaligned( 489 __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); 490 template <class _AlgPolicy> 491 friend struct __copy_backward_impl; 492 template <class _Cl, class _Cr> 493 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Cr, false> 494 __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); 495 template <class _Cl, class _Cr> 496 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Cr, false> 497 __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); 498 template <class, class _Cl, class _Cr> 499 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend pair<__bit_iterator<_Cl, false>, __bit_iterator<_Cr, false> > 500 __swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); 501 template <class, class _Dp> 502 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend pair<__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false> > 503 __rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>); 504 template <class _Dp, bool _IsConst1, bool _IsConst2> 505 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 506 __equal_aligned(__bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>); 507 template <class _Dp, bool _IsConst1, bool _IsConst2> 508 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool 509 __equal_unaligned(__bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>); 510 template <class _Dp, 511 bool _IsConst1, 512 bool _IsConst2, 513 class _BinaryPredicate, 514 __enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>, int> > 515 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_iter_impl( 516 __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>, _BinaryPredicate); 517 template <class _Dp, 518 bool _IsConst1, 519 bool _IsConst2, 520 class _Pred, 521 class _Proj1, 522 class _Proj2, 523 __enable_if_t<__desugars_to_v<__equal_tag, _Pred, bool, bool> && __is_identity<_Proj1>::value && 524 __is_identity<_Proj2>::value, 525 int> > 526 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_impl( 527 __bit_iterator<_Dp, _IsConst1> __first1, 528 __bit_iterator<_Dp, _IsConst1> __last1, 529 __bit_iterator<_Dp, _IsConst2> __first2, 530 __bit_iterator<_Dp, _IsConst2>, 531 _Pred&, 532 _Proj1&, 533 _Proj2&); 534 template <bool _ToFind, class _Dp, bool _IC> 535 _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC> 536 __find_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type); 537 template <bool _ToCount, class _Dp, bool _IC> 538 friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 539 __count_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type); 540}; 541 542_LIBCPP_END_NAMESPACE_STD 543 544_LIBCPP_POP_MACROS 545 546#endif // _LIBCPP___BIT_REFERENCE 547