Back to home page

EIC code displayed by LXR

 
 

    


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