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