Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/c++/v1/__bit_reference is written in an unsupported language. File is not indexed.

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___BIT_REFERENCE
0011 #define _LIBCPP___BIT_REFERENCE
0012 
0013 #include <__algorithm/copy_n.h>
0014 #include <__algorithm/min.h>
0015 #include <__bit/countr.h>
0016 #include <__compare/ordering.h>
0017 #include <__config>
0018 #include <__cstddef/ptrdiff_t.h>
0019 #include <__cstddef/size_t.h>
0020 #include <__fwd/bit_reference.h>
0021 #include <__iterator/iterator_traits.h>
0022 #include <__memory/construct_at.h>
0023 #include <__memory/pointer_traits.h>
0024 #include <__type_traits/conditional.h>
0025 #include <__type_traits/is_constant_evaluated.h>
0026 #include <__type_traits/void_t.h>
0027 #include <__utility/swap.h>
0028 
0029 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0030 #  pragma GCC system_header
0031 #endif
0032 
0033 _LIBCPP_PUSH_MACROS
0034 #include <__undef_macros>
0035 
0036 _LIBCPP_BEGIN_NAMESPACE_STD
0037 
0038 template <class _Cp>
0039 class __bit_const_reference;
0040 
0041 template <class _Tp>
0042 struct __has_storage_type {
0043   static const bool value = false;
0044 };
0045 
0046 template <class, class>
0047 struct __size_difference_type_traits {
0048   using difference_type = ptrdiff_t;
0049   using size_type       = size_t;
0050 };
0051 
0052 template <class _Cp>
0053 struct __size_difference_type_traits<_Cp, __void_t<typename _Cp::difference_type, typename _Cp::size_type> > {
0054   using difference_type = typename _Cp::difference_type;
0055   using size_type       = typename _Cp::size_type;
0056 };
0057 
0058 template <class _Cp, bool = __has_storage_type<_Cp>::value>
0059 class __bit_reference {
0060   using __storage_type _LIBCPP_NODEBUG    = typename _Cp::__storage_type;
0061   using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__storage_pointer;
0062 
0063   __storage_pointer __seg_;
0064   __storage_type __mask_;
0065 
0066   friend typename _Cp::__self;
0067 
0068   friend class __bit_const_reference<_Cp>;
0069   friend class __bit_iterator<_Cp, false>;
0070 
0071 public:
0072   using __container _LIBCPP_NODEBUG = typename _Cp::__self;
0073 
0074   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference(const __bit_reference&) = default;
0075 
0076   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT {
0077     return static_cast<bool>(*__seg_ & __mask_);
0078   }
0079   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
0080     return !static_cast<bool>(*this);
0081   }
0082 
0083   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(bool __x) _NOEXCEPT {
0084     if (__x)
0085       *__seg_ |= __mask_;
0086     else
0087       *__seg_ &= ~__mask_;
0088     return *this;
0089   }
0090 
0091 #if _LIBCPP_STD_VER >= 23
0092   _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept {
0093     if (__x)
0094       *__seg_ |= __mask_;
0095     else
0096       *__seg_ &= ~__mask_;
0097     return *this;
0098   }
0099 #endif
0100 
0101   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT {
0102     return operator=(static_cast<bool>(__x));
0103   }
0104 
0105   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT { *__seg_ ^= __mask_; }
0106   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT {
0107     return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));
0108   }
0109 
0110 private:
0111   _LIBCPP_HIDE_FROM_ABI
0112   _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
0113       : __seg_(__s),
0114         __mask_(__m) {}
0115 };
0116 
0117 template <class _Cp>
0118 class __bit_reference<_Cp, false> {};
0119 
0120 template <class _Cp>
0121 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
0122 swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT {
0123   bool __t = __x;
0124   __x      = __y;
0125   __y      = __t;
0126 }
0127 
0128 template <class _Cp, class _Dp>
0129 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
0130 swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT {
0131   bool __t = __x;
0132   __x      = __y;
0133   __y      = __t;
0134 }
0135 
0136 template <class _Cp>
0137 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT {
0138   bool __t = __x;
0139   __x      = __y;
0140   __y      = __t;
0141 }
0142 
0143 template <class _Cp>
0144 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT {
0145   bool __t = __x;
0146   __x      = __y;
0147   __y      = __t;
0148 }
0149 
0150 template <class _Cp>
0151 class __bit_const_reference {
0152   using __storage_type _LIBCPP_NODEBUG    = typename _Cp::__storage_type;
0153   using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__const_storage_pointer;
0154 
0155   __storage_pointer __seg_;
0156   __storage_type __mask_;
0157 
0158   friend typename _Cp::__self;
0159   friend class __bit_iterator<_Cp, true>;
0160 
0161 public:
0162   using __container _LIBCPP_NODEBUG = typename _Cp::__self;
0163 
0164   _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_const_reference&) = default;
0165   __bit_const_reference& operator=(const __bit_const_reference&)            = delete;
0166 
0167   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
0168       : __seg_(__x.__seg_),
0169         __mask_(__x.__mask_) {}
0170 
0171   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT {
0172     return static_cast<bool>(*__seg_ & __mask_);
0173   }
0174 
0175   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT {
0176     return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));
0177   }
0178 
0179 private:
0180   _LIBCPP_HIDE_FROM_ABI
0181   _LIBCPP_CONSTEXPR explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
0182       : __seg_(__s),
0183         __mask_(__m) {}
0184 };
0185 
0186 // copy
0187 
0188 template <class _Cp, bool _IsConst>
0189 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned(
0190     __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
0191   using _In             = __bit_iterator<_Cp, _IsConst>;
0192   using difference_type = typename _In::difference_type;
0193   using __storage_type  = typename _In::__storage_type;
0194 
0195   const int __bits_per_word = _In::__bits_per_word;
0196   difference_type __n       = __last - __first;
0197   if (__n > 0) {
0198     // do first word
0199     if (__first.__ctz_ != 0) {
0200       unsigned __clz       = __bits_per_word - __first.__ctz_;
0201       difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
0202       __n -= __dn;
0203       __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
0204       __storage_type __b = *__first.__seg_ & __m;
0205       *__result.__seg_ &= ~__m;
0206       *__result.__seg_ |= __b;
0207       __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
0208       __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
0209       ++__first.__seg_;
0210       // __first.__ctz_ = 0;
0211     }
0212     // __first.__ctz_ == 0;
0213     // do middle words
0214     __storage_type __nw = __n / __bits_per_word;
0215     std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_));
0216     __n -= __nw * __bits_per_word;
0217     __result.__seg_ += __nw;
0218     // do last word
0219     if (__n > 0) {
0220       __first.__seg_ += __nw;
0221       __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
0222       __storage_type __b = *__first.__seg_ & __m;
0223       *__result.__seg_ &= ~__m;
0224       *__result.__seg_ |= __b;
0225       __result.__ctz_ = static_cast<unsigned>(__n);
0226     }
0227   }
0228   return __result;
0229 }
0230 
0231 template <class _Cp, bool _IsConst>
0232 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned(
0233     __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
0234   using _In             = __bit_iterator<_Cp, _IsConst>;
0235   using difference_type = typename _In::difference_type;
0236   using __storage_type  = typename _In::__storage_type;
0237 
0238   const int __bits_per_word = _In::__bits_per_word;
0239   difference_type __n       = __last - __first;
0240   if (__n > 0) {
0241     // do first word
0242     if (__first.__ctz_ != 0) {
0243       unsigned __clz_f     = __bits_per_word - __first.__ctz_;
0244       difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
0245       __n -= __dn;
0246       __storage_type __m   = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
0247       __storage_type __b   = *__first.__seg_ & __m;
0248       unsigned __clz_r     = __bits_per_word - __result.__ctz_;
0249       __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
0250       __m                  = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
0251       *__result.__seg_ &= ~__m;
0252       if (__result.__ctz_ > __first.__ctz_)
0253         *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
0254       else
0255         *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
0256       __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
0257       __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
0258       __dn -= __ddn;
0259       if (__dn > 0) {
0260         __m = ~__storage_type(0) >> (__bits_per_word - __dn);
0261         *__result.__seg_ &= ~__m;
0262         *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
0263         __result.__ctz_ = static_cast<unsigned>(__dn);
0264       }
0265       ++__first.__seg_;
0266       // __first.__ctz_ = 0;
0267     }
0268     // __first.__ctz_ == 0;
0269     // do middle words
0270     unsigned __clz_r   = __bits_per_word - __result.__ctz_;
0271     __storage_type __m = ~__storage_type(0) << __result.__ctz_;
0272     for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
0273       __storage_type __b = *__first.__seg_;
0274       *__result.__seg_ &= ~__m;
0275       *__result.__seg_ |= __b << __result.__ctz_;
0276       ++__result.__seg_;
0277       *__result.__seg_ &= __m;
0278       *__result.__seg_ |= __b >> __clz_r;
0279     }
0280     // do last word
0281     if (__n > 0) {
0282       __m                 = ~__storage_type(0) >> (__bits_per_word - __n);
0283       __storage_type __b  = *__first.__seg_ & __m;
0284       __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
0285       __m                 = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
0286       *__result.__seg_ &= ~__m;
0287       *__result.__seg_ |= __b << __result.__ctz_;
0288       __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
0289       __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
0290       __n -= __dn;
0291       if (__n > 0) {
0292         __m = ~__storage_type(0) >> (__bits_per_word - __n);
0293         *__result.__seg_ &= ~__m;
0294         *__result.__seg_ |= __b >> __dn;
0295         __result.__ctz_ = static_cast<unsigned>(__n);
0296       }
0297     }
0298   }
0299   return __result;
0300 }
0301 
0302 template <class _Cp, bool _IsConst>
0303 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false>
0304 copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
0305   if (__first.__ctz_ == __result.__ctz_)
0306     return std::__copy_aligned(__first, __last, __result);
0307   return std::__copy_unaligned(__first, __last, __result);
0308 }
0309 
0310 // copy_backward
0311 
0312 template <class _Cp, bool _IsConst>
0313 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned(
0314     __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
0315   using _In             = __bit_iterator<_Cp, _IsConst>;
0316   using difference_type = typename _In::difference_type;
0317   using __storage_type  = typename _In::__storage_type;
0318 
0319   const int __bits_per_word = _In::__bits_per_word;
0320   difference_type __n       = __last - __first;
0321   if (__n > 0) {
0322     // do first word
0323     if (__last.__ctz_ != 0) {
0324       difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n);
0325       __n -= __dn;
0326       unsigned __clz     = __bits_per_word - __last.__ctz_;
0327       __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
0328       __storage_type __b = *__last.__seg_ & __m;
0329       *__result.__seg_ &= ~__m;
0330       *__result.__seg_ |= __b;
0331       __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
0332       // __last.__ctz_ = 0
0333     }
0334     // __last.__ctz_ == 0 || __n == 0
0335     // __result.__ctz_ == 0 || __n == 0
0336     // do middle words
0337     __storage_type __nw = __n / __bits_per_word;
0338     __result.__seg_ -= __nw;
0339     __last.__seg_ -= __nw;
0340     std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_));
0341     __n -= __nw * __bits_per_word;
0342     // do last word
0343     if (__n > 0) {
0344       __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
0345       __storage_type __b = *--__last.__seg_ & __m;
0346       *--__result.__seg_ &= ~__m;
0347       *__result.__seg_ |= __b;
0348       __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
0349     }
0350   }
0351   return __result;
0352 }
0353 
0354 template <class _Cp, bool _IsConst>
0355 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned(
0356     __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
0357   using _In             = __bit_iterator<_Cp, _IsConst>;
0358   using difference_type = typename _In::difference_type;
0359   using __storage_type  = typename _In::__storage_type;
0360 
0361   const int __bits_per_word = _In::__bits_per_word;
0362   difference_type __n       = __last - __first;
0363   if (__n > 0) {
0364     // do first word
0365     if (__last.__ctz_ != 0) {
0366       difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n);
0367       __n -= __dn;
0368       unsigned __clz_l     = __bits_per_word - __last.__ctz_;
0369       __storage_type __m   = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
0370       __storage_type __b   = *__last.__seg_ & __m;
0371       unsigned __clz_r     = __bits_per_word - __result.__ctz_;
0372       __storage_type __ddn = std::min(__dn, static_cast<difference_type>(__result.__ctz_));
0373       if (__ddn > 0) {
0374         __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
0375         *__result.__seg_ &= ~__m;
0376         if (__result.__ctz_ > __last.__ctz_)
0377           *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
0378         else
0379           *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
0380         __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
0381         __dn -= __ddn;
0382       }
0383       if (__dn > 0) {
0384         // __result.__ctz_ == 0
0385         --__result.__seg_;
0386         __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
0387         __m             = ~__storage_type(0) << __result.__ctz_;
0388         *__result.__seg_ &= ~__m;
0389         __last.__ctz_ -= __dn + __ddn;
0390         *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
0391       }
0392       // __last.__ctz_ = 0
0393     }
0394     // __last.__ctz_ == 0 || __n == 0
0395     // __result.__ctz_ != 0 || __n == 0
0396     // do middle words
0397     unsigned __clz_r   = __bits_per_word - __result.__ctz_;
0398     __storage_type __m = ~__storage_type(0) >> __clz_r;
0399     for (; __n >= __bits_per_word; __n -= __bits_per_word) {
0400       __storage_type __b = *--__last.__seg_;
0401       *__result.__seg_ &= ~__m;
0402       *__result.__seg_ |= __b >> __clz_r;
0403       *--__result.__seg_ &= __m;
0404       *__result.__seg_ |= __b << __result.__ctz_;
0405     }
0406     // do last word
0407     if (__n > 0) {
0408       __m                 = ~__storage_type(0) << (__bits_per_word - __n);
0409       __storage_type __b  = *--__last.__seg_ & __m;
0410       __clz_r             = __bits_per_word - __result.__ctz_;
0411       __storage_type __dn = std::min(__n, static_cast<difference_type>(__result.__ctz_));
0412       __m                 = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
0413       *__result.__seg_ &= ~__m;
0414       *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
0415       __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
0416       __n -= __dn;
0417       if (__n > 0) {
0418         // __result.__ctz_ == 0
0419         --__result.__seg_;
0420         __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
0421         __m             = ~__storage_type(0) << __result.__ctz_;
0422         *__result.__seg_ &= ~__m;
0423         *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
0424       }
0425     }
0426   }
0427   return __result;
0428 }
0429 
0430 template <class _Cp, bool _IsConst>
0431 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy_backward(
0432     __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
0433   if (__last.__ctz_ == __result.__ctz_)
0434     return std::__copy_backward_aligned(__first, __last, __result);
0435   return std::__copy_backward_unaligned(__first, __last, __result);
0436 }
0437 
0438 // move
0439 
0440 template <class _Cp, bool _IsConst>
0441 inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
0442 move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
0443   return std::copy(__first, __last, __result);
0444 }
0445 
0446 // move_backward
0447 
0448 template <class _Cp, bool _IsConst>
0449 inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward(
0450     __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
0451   return std::copy_backward(__first, __last, __result);
0452 }
0453 
0454 // swap_ranges
0455 
0456 template <class _Cl, class _Cr>
0457 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned(
0458     __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) {
0459   using _I1             = __bit_iterator<_Cl, false>;
0460   using difference_type = typename _I1::difference_type;
0461   using __storage_type  = typename _I1::__storage_type;
0462 
0463   const int __bits_per_word = _I1::__bits_per_word;
0464   difference_type __n       = __last - __first;
0465   if (__n > 0) {
0466     // do first word
0467     if (__first.__ctz_ != 0) {
0468       unsigned __clz       = __bits_per_word - __first.__ctz_;
0469       difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
0470       __n -= __dn;
0471       __storage_type __m  = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
0472       __storage_type __b1 = *__first.__seg_ & __m;
0473       *__first.__seg_ &= ~__m;
0474       __storage_type __b2 = *__result.__seg_ & __m;
0475       *__result.__seg_ &= ~__m;
0476       *__result.__seg_ |= __b1;
0477       *__first.__seg_ |= __b2;
0478       __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
0479       __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
0480       ++__first.__seg_;
0481       // __first.__ctz_ = 0;
0482     }
0483     // __first.__ctz_ == 0;
0484     // do middle words
0485     for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
0486       swap(*__first.__seg_, *__result.__seg_);
0487     // do last word
0488     if (__n > 0) {
0489       __storage_type __m  = ~__storage_type(0) >> (__bits_per_word - __n);
0490       __storage_type __b1 = *__first.__seg_ & __m;
0491       *__first.__seg_ &= ~__m;
0492       __storage_type __b2 = *__result.__seg_ & __m;
0493       *__result.__seg_ &= ~__m;
0494       *__result.__seg_ |= __b1;
0495       *__first.__seg_ |= __b2;
0496       __result.__ctz_ = static_cast<unsigned>(__n);
0497     }
0498   }
0499   return __result;
0500 }
0501 
0502 template <class _Cl, class _Cr>
0503 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned(
0504     __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) {
0505   using _I1             = __bit_iterator<_Cl, false>;
0506   using difference_type = typename _I1::difference_type;
0507   using __storage_type  = typename _I1::__storage_type;
0508 
0509   const int __bits_per_word = _I1::__bits_per_word;
0510   difference_type __n       = __last - __first;
0511   if (__n > 0) {
0512     // do first word
0513     if (__first.__ctz_ != 0) {
0514       unsigned __clz_f     = __bits_per_word - __first.__ctz_;
0515       difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
0516       __n -= __dn;
0517       __storage_type __m  = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
0518       __storage_type __b1 = *__first.__seg_ & __m;
0519       *__first.__seg_ &= ~__m;
0520       unsigned __clz_r     = __bits_per_word - __result.__ctz_;
0521       __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
0522       __m                  = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
0523       __storage_type __b2  = *__result.__seg_ & __m;
0524       *__result.__seg_ &= ~__m;
0525       if (__result.__ctz_ > __first.__ctz_) {
0526         unsigned __s = __result.__ctz_ - __first.__ctz_;
0527         *__result.__seg_ |= __b1 << __s;
0528         *__first.__seg_ |= __b2 >> __s;
0529       } else {
0530         unsigned __s = __first.__ctz_ - __result.__ctz_;
0531         *__result.__seg_ |= __b1 >> __s;
0532         *__first.__seg_ |= __b2 << __s;
0533       }
0534       __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
0535       __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
0536       __dn -= __ddn;
0537       if (__dn > 0) {
0538         __m  = ~__storage_type(0) >> (__bits_per_word - __dn);
0539         __b2 = *__result.__seg_ & __m;
0540         *__result.__seg_ &= ~__m;
0541         unsigned __s = __first.__ctz_ + __ddn;
0542         *__result.__seg_ |= __b1 >> __s;
0543         *__first.__seg_ |= __b2 << __s;
0544         __result.__ctz_ = static_cast<unsigned>(__dn);
0545       }
0546       ++__first.__seg_;
0547       // __first.__ctz_ = 0;
0548     }
0549     // __first.__ctz_ == 0;
0550     // do middle words
0551     __storage_type __m = ~__storage_type(0) << __result.__ctz_;
0552     unsigned __clz_r   = __bits_per_word - __result.__ctz_;
0553     for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
0554       __storage_type __b1 = *__first.__seg_;
0555       __storage_type __b2 = *__result.__seg_ & __m;
0556       *__result.__seg_ &= ~__m;
0557       *__result.__seg_ |= __b1 << __result.__ctz_;
0558       *__first.__seg_ = __b2 >> __result.__ctz_;
0559       ++__result.__seg_;
0560       __b2 = *__result.__seg_ & ~__m;
0561       *__result.__seg_ &= __m;
0562       *__result.__seg_ |= __b1 >> __clz_r;
0563       *__first.__seg_ |= __b2 << __clz_r;
0564     }
0565     // do last word
0566     if (__n > 0) {
0567       __m                 = ~__storage_type(0) >> (__bits_per_word - __n);
0568       __storage_type __b1 = *__first.__seg_ & __m;
0569       *__first.__seg_ &= ~__m;
0570       __storage_type __dn = std::min<__storage_type>(__n, __clz_r);
0571       __m                 = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
0572       __storage_type __b2 = *__result.__seg_ & __m;
0573       *__result.__seg_ &= ~__m;
0574       *__result.__seg_ |= __b1 << __result.__ctz_;
0575       *__first.__seg_ |= __b2 >> __result.__ctz_;
0576       __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
0577       __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
0578       __n -= __dn;
0579       if (__n > 0) {
0580         __m  = ~__storage_type(0) >> (__bits_per_word - __n);
0581         __b2 = *__result.__seg_ & __m;
0582         *__result.__seg_ &= ~__m;
0583         *__result.__seg_ |= __b1 >> __dn;
0584         *__first.__seg_ |= __b2 << __dn;
0585         __result.__ctz_ = static_cast<unsigned>(__n);
0586       }
0587     }
0588   }
0589   return __result;
0590 }
0591 
0592 template <class _Cl, class _Cr>
0593 inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges(
0594     __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) {
0595   if (__first1.__ctz_ == __first2.__ctz_)
0596     return std::__swap_ranges_aligned(__first1, __last1, __first2);
0597   return std::__swap_ranges_unaligned(__first1, __last1, __first2);
0598 }
0599 
0600 // rotate
0601 
0602 template <class _Cp>
0603 struct __bit_array {
0604   using difference_type _LIBCPP_NODEBUG   = typename __size_difference_type_traits<_Cp>::difference_type;
0605   using __storage_type _LIBCPP_NODEBUG    = typename _Cp::__storage_type;
0606   using __storage_pointer _LIBCPP_NODEBUG = typename _Cp::__storage_pointer;
0607   using iterator _LIBCPP_NODEBUG          = typename _Cp::iterator;
0608 
0609   static const unsigned __bits_per_word = _Cp::__bits_per_word;
0610   static const unsigned _Np             = 4;
0611 
0612   difference_type __size_;
0613   __storage_type __word_[_Np];
0614 
0615   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() {
0616     return static_cast<difference_type>(_Np * __bits_per_word);
0617   }
0618   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) {
0619     if (__libcpp_is_constant_evaluated()) {
0620       for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i)
0621         std::__construct_at(__word_ + __i, 0);
0622     }
0623   }
0624   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() {
0625     return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
0626   }
0627   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() {
0628     return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
0629                     static_cast<unsigned>(__size_ % __bits_per_word));
0630   }
0631 };
0632 
0633 template <class _Cp>
0634 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
0635 rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) {
0636   using _I1             = __bit_iterator<_Cp, false>;
0637   using difference_type = typename _I1::difference_type;
0638 
0639   difference_type __d1 = __middle - __first;
0640   difference_type __d2 = __last - __middle;
0641   _I1 __r              = __first + __d2;
0642   while (__d1 != 0 && __d2 != 0) {
0643     if (__d1 <= __d2) {
0644       if (__d1 <= __bit_array<_Cp>::capacity()) {
0645         __bit_array<_Cp> __b(__d1);
0646         std::copy(__first, __middle, __b.begin());
0647         std::copy(__b.begin(), __b.end(), std::copy(__middle, __last, __first));
0648         break;
0649       } else {
0650         __bit_iterator<_Cp, false> __mp = std::swap_ranges(__first, __middle, __middle);
0651         __first                         = __middle;
0652         __middle                        = __mp;
0653         __d2 -= __d1;
0654       }
0655     } else {
0656       if (__d2 <= __bit_array<_Cp>::capacity()) {
0657         __bit_array<_Cp> __b(__d2);
0658         std::copy(__middle, __last, __b.begin());
0659         std::copy_backward(__b.begin(), __b.end(), std::copy_backward(__first, __middle, __last));
0660         break;
0661       } else {
0662         __bit_iterator<_Cp, false> __mp = __first + __d2;
0663         std::swap_ranges(__first, __mp, __middle);
0664         __first = __mp;
0665         __d1 -= __d2;
0666       }
0667     }
0668   }
0669   return __r;
0670 }
0671 
0672 // equal
0673 
0674 template <class _Cp, bool _IC1, bool _IC2>
0675 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_unaligned(
0676     __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
0677   using _It             = __bit_iterator<_Cp, _IC1>;
0678   using difference_type = typename _It::difference_type;
0679   using __storage_type  = typename _It::__storage_type;
0680 
0681   const int __bits_per_word = _It::__bits_per_word;
0682   difference_type __n       = __last1 - __first1;
0683   if (__n > 0) {
0684     // do first word
0685     if (__first1.__ctz_ != 0) {
0686       unsigned __clz_f     = __bits_per_word - __first1.__ctz_;
0687       difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
0688       __n -= __dn;
0689       __storage_type __m   = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
0690       __storage_type __b   = *__first1.__seg_ & __m;
0691       unsigned __clz_r     = __bits_per_word - __first2.__ctz_;
0692       __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
0693       __m                  = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
0694       if (__first2.__ctz_ > __first1.__ctz_) {
0695         if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
0696           return false;
0697       } else {
0698         if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
0699           return false;
0700       }
0701       __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
0702       __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word);
0703       __dn -= __ddn;
0704       if (__dn > 0) {
0705         __m = ~__storage_type(0) >> (__bits_per_word - __dn);
0706         if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
0707           return false;
0708         __first2.__ctz_ = static_cast<unsigned>(__dn);
0709       }
0710       ++__first1.__seg_;
0711       // __first1.__ctz_ = 0;
0712     }
0713     // __first1.__ctz_ == 0;
0714     // do middle words
0715     unsigned __clz_r   = __bits_per_word - __first2.__ctz_;
0716     __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
0717     for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) {
0718       __storage_type __b = *__first1.__seg_;
0719       if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
0720         return false;
0721       ++__first2.__seg_;
0722       if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
0723         return false;
0724     }
0725     // do last word
0726     if (__n > 0) {
0727       __m                 = ~__storage_type(0) >> (__bits_per_word - __n);
0728       __storage_type __b  = *__first1.__seg_ & __m;
0729       __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
0730       __m                 = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
0731       if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
0732         return false;
0733       __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
0734       __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word);
0735       __n -= __dn;
0736       if (__n > 0) {
0737         __m = ~__storage_type(0) >> (__bits_per_word - __n);
0738         if ((*__first2.__seg_ & __m) != (__b >> __dn))
0739           return false;
0740       }
0741     }
0742   }
0743   return true;
0744 }
0745 
0746 template <class _Cp, bool _IC1, bool _IC2>
0747 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_aligned(
0748     __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
0749   using _It             = __bit_iterator<_Cp, _IC1>;
0750   using difference_type = typename _It::difference_type;
0751   using __storage_type  = typename _It::__storage_type;
0752 
0753   const int __bits_per_word = _It::__bits_per_word;
0754   difference_type __n       = __last1 - __first1;
0755   if (__n > 0) {
0756     // do first word
0757     if (__first1.__ctz_ != 0) {
0758       unsigned __clz       = __bits_per_word - __first1.__ctz_;
0759       difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
0760       __n -= __dn;
0761       __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
0762       if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
0763         return false;
0764       ++__first2.__seg_;
0765       ++__first1.__seg_;
0766       // __first1.__ctz_ = 0;
0767       // __first2.__ctz_ = 0;
0768     }
0769     // __first1.__ctz_ == 0;
0770     // __first2.__ctz_ == 0;
0771     // do middle words
0772     for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
0773       if (*__first2.__seg_ != *__first1.__seg_)
0774         return false;
0775     // do last word
0776     if (__n > 0) {
0777       __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
0778       if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
0779         return false;
0780     }
0781   }
0782   return true;
0783 }
0784 
0785 template <class _Cp, bool _IC1, bool _IC2>
0786 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
0787 equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
0788   if (__first1.__ctz_ == __first2.__ctz_)
0789     return std::__equal_aligned(__first1, __last1, __first2);
0790   return std::__equal_unaligned(__first1, __last1, __first2);
0791 }
0792 
0793 template <class _Cp, bool _IsConst, typename _Cp::__storage_type>
0794 class __bit_iterator {
0795 public:
0796   using difference_type = typename __size_difference_type_traits<_Cp>::difference_type;
0797   using value_type      = bool;
0798   using pointer         = __bit_iterator;
0799 #ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
0800   using reference = __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >;
0801 #else
0802   using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >;
0803 #endif
0804   using iterator_category = random_access_iterator_tag;
0805 
0806 private:
0807   using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type;
0808   using __storage_pointer _LIBCPP_NODEBUG =
0809       __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>;
0810 
0811   static const unsigned __bits_per_word = _Cp::__bits_per_word;
0812 
0813   __storage_pointer __seg_;
0814   unsigned __ctz_;
0815 
0816 public:
0817   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT
0818 #if _LIBCPP_STD_VER >= 14
0819       : __seg_(nullptr),
0820         __ctz_(0)
0821 #endif
0822   {
0823   }
0824 
0825   // When _IsConst=false, this is the copy constructor.
0826   // It is non-trivial. Making it trivial would break ABI.
0827   // When _IsConst=true, this is a converting constructor;
0828   // the copy and move constructors are implicitly generated
0829   // and trivial.
0830   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
0831       : __seg_(__it.__seg_),
0832         __ctz_(__it.__ctz_) {}
0833 
0834   // When _IsConst=false, we have a user-provided copy constructor,
0835   // so we must also provide a copy assignment operator because
0836   // the implicit generation of a defaulted one is deprecated.
0837   // When _IsConst=true, the assignment operators are
0838   // implicitly generated and trivial.
0839   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator&
0840   operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
0841     __seg_ = __it.__seg_;
0842     __ctz_ = __it.__ctz_;
0843     return *this;
0844   }
0845 
0846   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
0847     return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >(
0848         __seg_, __storage_type(1) << __ctz_);
0849   }
0850 
0851   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() {
0852     if (__ctz_ != __bits_per_word - 1)
0853       ++__ctz_;
0854     else {
0855       __ctz_ = 0;
0856       ++__seg_;
0857     }
0858     return *this;
0859   }
0860 
0861   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) {
0862     __bit_iterator __tmp = *this;
0863     ++(*this);
0864     return __tmp;
0865   }
0866 
0867   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() {
0868     if (__ctz_ != 0)
0869       --__ctz_;
0870     else {
0871       __ctz_ = __bits_per_word - 1;
0872       --__seg_;
0873     }
0874     return *this;
0875   }
0876 
0877   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) {
0878     __bit_iterator __tmp = *this;
0879     --(*this);
0880     return __tmp;
0881   }
0882 
0883   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) {
0884     if (__n >= 0)
0885       __seg_ += (__n + __ctz_) / __bits_per_word;
0886     else
0887       __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) /
0888                 static_cast<difference_type>(__bits_per_word);
0889     __n &= (__bits_per_word - 1);
0890     __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word);
0891     return *this;
0892   }
0893 
0894   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) {
0895     return *this += -__n;
0896   }
0897 
0898   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const {
0899     __bit_iterator __t(*this);
0900     __t += __n;
0901     return __t;
0902   }
0903 
0904   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const {
0905     __bit_iterator __t(*this);
0906     __t -= __n;
0907     return __t;
0908   }
0909 
0910   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator
0911   operator+(difference_type __n, const __bit_iterator& __it) {
0912     return __it + __n;
0913   }
0914 
0915   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend difference_type
0916   operator-(const __bit_iterator& __x, const __bit_iterator& __y) {
0917     return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;
0918   }
0919 
0920   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const {
0921     return *(*this + __n);
0922   }
0923 
0924   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
0925   operator==(const __bit_iterator& __x, const __bit_iterator& __y) {
0926     return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;
0927   }
0928 
0929 #if _LIBCPP_STD_VER <= 17
0930   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
0931   operator!=(const __bit_iterator& __x, const __bit_iterator& __y) {
0932     return !(__x == __y);
0933   }
0934 
0935   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
0936   operator<(const __bit_iterator& __x, const __bit_iterator& __y) {
0937     return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);
0938   }
0939 
0940   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
0941   operator>(const __bit_iterator& __x, const __bit_iterator& __y) {
0942     return __y < __x;
0943   }
0944 
0945   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
0946   operator<=(const __bit_iterator& __x, const __bit_iterator& __y) {
0947     return !(__y < __x);
0948   }
0949 
0950   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
0951   operator>=(const __bit_iterator& __x, const __bit_iterator& __y) {
0952     return !(__x < __y);
0953   }
0954 #else  // _LIBCPP_STD_VER <= 17
0955   _LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering
0956   operator<=>(const __bit_iterator& __x, const __bit_iterator& __y) {
0957     if (__x.__seg_ < __y.__seg_)
0958       return strong_ordering::less;
0959 
0960     if (__x.__seg_ == __y.__seg_)
0961       return __x.__ctz_ <=> __y.__ctz_;
0962 
0963     return strong_ordering::greater;
0964   }
0965 #endif // _LIBCPP_STD_VER <= 17
0966 
0967 private:
0968   _LIBCPP_HIDE_FROM_ABI
0969   _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
0970       : __seg_(__s),
0971         __ctz_(__ctz) {}
0972 
0973   friend typename _Cp::__self;
0974 
0975   friend class __bit_reference<_Cp>;
0976   friend class __bit_const_reference<_Cp>;
0977   friend class __bit_iterator<_Cp, true>;
0978   template <class _Dp>
0979   friend struct __bit_array;
0980 
0981   template <bool _FillVal, class _Dp>
0982   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void
0983   __fill_n_bool(__bit_iterator<_Dp, false> __first, typename __size_difference_type_traits<_Dp>::size_type __n);
0984 
0985   template <class _Dp, bool _IC>
0986   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned(
0987       __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
0988   template <class _Dp, bool _IC>
0989   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_unaligned(
0990       __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
0991   template <class _Dp, bool _IC>
0992   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
0993   copy(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
0994   template <class _Dp, bool _IC>
0995   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned(
0996       __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
0997   template <class _Dp, bool _IC>
0998   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_unaligned(
0999       __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
1000   template <class _Dp, bool _IC>
1001   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
1002   copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
1003   template <class _Cl, class _Cr>
1004   friend __bit_iterator<_Cr, false>
1005       __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
1006   template <class _Cl, class _Cr>
1007   friend __bit_iterator<_Cr, false>
1008       __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
1009   template <class _Cl, class _Cr>
1010   friend __bit_iterator<_Cr, false>
1011       swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
1012   template <class _Dp>
1013   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
1014       rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>);
1015   template <class _Dp, bool _IC1, bool _IC2>
1016   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
1017       __equal_aligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
1018   template <class _Dp, bool _IC1, bool _IC2>
1019   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
1020       __equal_unaligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
1021   template <class _Dp, bool _IC1, bool _IC2>
1022   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
1023       equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
1024   template <bool _ToFind, class _Dp, bool _IC>
1025   _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC>
1026       __find_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
1027   template <bool _ToCount, class _Dp, bool _IC>
1028   friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1029   __count_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
1030 };
1031 
1032 _LIBCPP_END_NAMESPACE_STD
1033 
1034 _LIBCPP_POP_MACROS
1035 
1036 #endif // _LIBCPP___BIT_REFERENCE