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