__bit_reference 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP___BIT_REFERENCE
  10. #define _LIBCPP___BIT_REFERENCE
  11. #include <__algorithm/copy_n.h>
  12. #include <__algorithm/fill_n.h>
  13. #include <__algorithm/min.h>
  14. #include <__bit/countr.h>
  15. #include <__bit/invert_if.h>
  16. #include <__bit/popcount.h>
  17. #include <__config>
  18. #include <__fwd/bit_reference.h>
  19. #include <__iterator/iterator_traits.h>
  20. #include <__memory/construct_at.h>
  21. #include <__memory/pointer_traits.h>
  22. #include <__type_traits/conditional.h>
  23. #include <__utility/swap.h>
  24. #include <cstring>
  25. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  26. # pragma GCC system_header
  27. #endif
  28. _LIBCPP_PUSH_MACROS
  29. #include <__undef_macros>
  30. _LIBCPP_BEGIN_NAMESPACE_STD
  31. template <class _Cp>
  32. class __bit_const_reference;
  33. template <class _Tp>
  34. struct __has_storage_type {
  35. static const bool value = false;
  36. };
  37. template <class _Cp, bool = __has_storage_type<_Cp>::value>
  38. class __bit_reference {
  39. using __storage_type = typename _Cp::__storage_type;
  40. using __storage_pointer = typename _Cp::__storage_pointer;
  41. __storage_pointer __seg_;
  42. __storage_type __mask_;
  43. friend typename _Cp::__self;
  44. friend class __bit_const_reference<_Cp>;
  45. friend class __bit_iterator<_Cp, false>;
  46. public:
  47. using __container = typename _Cp::__self;
  48. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference(const __bit_reference&) = default;
  49. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT {
  50. return static_cast<bool>(*__seg_ & __mask_);
  51. }
  52. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT {
  53. return !static_cast<bool>(*this);
  54. }
  55. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(bool __x) _NOEXCEPT {
  56. if (__x)
  57. *__seg_ |= __mask_;
  58. else
  59. *__seg_ &= ~__mask_;
  60. return *this;
  61. }
  62. #if _LIBCPP_STD_VER >= 23
  63. _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept {
  64. if (__x)
  65. *__seg_ |= __mask_;
  66. else
  67. *__seg_ &= ~__mask_;
  68. return *this;
  69. }
  70. #endif
  71. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT {
  72. return operator=(static_cast<bool>(__x));
  73. }
  74. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT { *__seg_ ^= __mask_; }
  75. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT {
  76. return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));
  77. }
  78. private:
  79. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_reference(
  80. __storage_pointer __s, __storage_type __m) _NOEXCEPT
  81. : __seg_(__s),
  82. __mask_(__m) {}
  83. };
  84. template <class _Cp>
  85. class __bit_reference<_Cp, false> {};
  86. template <class _Cp>
  87. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
  88. swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT {
  89. bool __t = __x;
  90. __x = __y;
  91. __y = __t;
  92. }
  93. template <class _Cp, class _Dp>
  94. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
  95. swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT {
  96. bool __t = __x;
  97. __x = __y;
  98. __y = __t;
  99. }
  100. template <class _Cp>
  101. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT {
  102. bool __t = __x;
  103. __x = __y;
  104. __y = __t;
  105. }
  106. template <class _Cp>
  107. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT {
  108. bool __t = __x;
  109. __x = __y;
  110. __y = __t;
  111. }
  112. template <class _Cp>
  113. class __bit_const_reference {
  114. using __storage_type = typename _Cp::__storage_type;
  115. using __storage_pointer = typename _Cp::__const_storage_pointer;
  116. __storage_pointer __seg_;
  117. __storage_type __mask_;
  118. friend typename _Cp::__self;
  119. friend class __bit_iterator<_Cp, true>;
  120. public:
  121. using __container = typename _Cp::__self;
  122. _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_const_reference&) = default;
  123. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
  124. : __seg_(__x.__seg_),
  125. __mask_(__x.__mask_) {}
  126. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT {
  127. return static_cast<bool>(*__seg_ & __mask_);
  128. }
  129. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT {
  130. return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(std::__libcpp_ctz(__mask_)));
  131. }
  132. private:
  133. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __bit_const_reference(
  134. __storage_pointer __s, __storage_type __m) _NOEXCEPT
  135. : __seg_(__s),
  136. __mask_(__m) {}
  137. __bit_const_reference& operator=(const __bit_const_reference&) = delete;
  138. };
  139. // count
  140. template <bool _ToCount, class _Cp, bool _IsConst>
  141. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __bit_iterator<_Cp, _IsConst>::difference_type
  142. __count_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) {
  143. using _It = __bit_iterator<_Cp, _IsConst>;
  144. using __storage_type = typename _It::__storage_type;
  145. using difference_type = typename _It::difference_type;
  146. const int __bits_per_word = _It::__bits_per_word;
  147. difference_type __r = 0;
  148. // do first partial word
  149. if (__first.__ctz_ != 0) {
  150. __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
  151. __storage_type __dn = std::min(__clz_f, __n);
  152. __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
  153. __r = std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_) & __m);
  154. __n -= __dn;
  155. ++__first.__seg_;
  156. }
  157. // do middle whole words
  158. for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
  159. __r += std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_));
  160. // do last partial word
  161. if (__n > 0) {
  162. __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
  163. __r += std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_) & __m);
  164. }
  165. return __r;
  166. }
  167. template <class _Cp, bool _IsConst, class _Tp>
  168. inline _LIBCPP_HIDE_FROM_ABI typename __bit_iterator<_Cp, _IsConst>::difference_type
  169. count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) {
  170. if (static_cast<bool>(__value))
  171. return std::__count_bool<true>(__first, static_cast<typename _Cp::size_type>(__last - __first));
  172. return std::__count_bool<false>(__first, static_cast<typename _Cp::size_type>(__last - __first));
  173. }
  174. // fill_n
  175. template <bool _FillValue, class _Cp>
  176. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
  177. __fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) {
  178. using _It = __bit_iterator<_Cp, false>;
  179. using __storage_type = typename _It::__storage_type;
  180. const int __bits_per_word = _It::__bits_per_word;
  181. // do first partial word
  182. if (__first.__ctz_ != 0) {
  183. __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
  184. __storage_type __dn = std::min(__clz_f, __n);
  185. __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
  186. if (_FillValue)
  187. *__first.__seg_ |= __m;
  188. else
  189. *__first.__seg_ &= ~__m;
  190. __n -= __dn;
  191. ++__first.__seg_;
  192. }
  193. // do middle whole words
  194. __storage_type __nw = __n / __bits_per_word;
  195. std::fill_n(std::__to_address(__first.__seg_), __nw, _FillValue ? static_cast<__storage_type>(-1) : 0);
  196. __n -= __nw * __bits_per_word;
  197. // do last partial word
  198. if (__n > 0) {
  199. __first.__seg_ += __nw;
  200. __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
  201. if (_FillValue)
  202. *__first.__seg_ |= __m;
  203. else
  204. *__first.__seg_ &= ~__m;
  205. }
  206. }
  207. template <class _Cp>
  208. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
  209. fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value) {
  210. if (__n > 0) {
  211. if (__value)
  212. std::__fill_n<true>(__first, __n);
  213. else
  214. std::__fill_n<false>(__first, __n);
  215. }
  216. }
  217. // fill
  218. template <class _Cp>
  219. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
  220. fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value) {
  221. std::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value);
  222. }
  223. // copy
  224. template <class _Cp, bool _IsConst>
  225. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned(
  226. __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
  227. using _In = __bit_iterator<_Cp, _IsConst>;
  228. using difference_type = typename _In::difference_type;
  229. using __storage_type = typename _In::__storage_type;
  230. const int __bits_per_word = _In::__bits_per_word;
  231. difference_type __n = __last - __first;
  232. if (__n > 0) {
  233. // do first word
  234. if (__first.__ctz_ != 0) {
  235. unsigned __clz = __bits_per_word - __first.__ctz_;
  236. difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
  237. __n -= __dn;
  238. __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
  239. __storage_type __b = *__first.__seg_ & __m;
  240. *__result.__seg_ &= ~__m;
  241. *__result.__seg_ |= __b;
  242. __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
  243. __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
  244. ++__first.__seg_;
  245. // __first.__ctz_ = 0;
  246. }
  247. // __first.__ctz_ == 0;
  248. // do middle words
  249. __storage_type __nw = __n / __bits_per_word;
  250. std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_));
  251. __n -= __nw * __bits_per_word;
  252. __result.__seg_ += __nw;
  253. // do last word
  254. if (__n > 0) {
  255. __first.__seg_ += __nw;
  256. __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
  257. __storage_type __b = *__first.__seg_ & __m;
  258. *__result.__seg_ &= ~__m;
  259. *__result.__seg_ |= __b;
  260. __result.__ctz_ = static_cast<unsigned>(__n);
  261. }
  262. }
  263. return __result;
  264. }
  265. template <class _Cp, bool _IsConst>
  266. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned(
  267. __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
  268. using _In = __bit_iterator<_Cp, _IsConst>;
  269. using difference_type = typename _In::difference_type;
  270. using __storage_type = typename _In::__storage_type;
  271. const int __bits_per_word = _In::__bits_per_word;
  272. difference_type __n = __last - __first;
  273. if (__n > 0) {
  274. // do first word
  275. if (__first.__ctz_ != 0) {
  276. unsigned __clz_f = __bits_per_word - __first.__ctz_;
  277. difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
  278. __n -= __dn;
  279. __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
  280. __storage_type __b = *__first.__seg_ & __m;
  281. unsigned __clz_r = __bits_per_word - __result.__ctz_;
  282. __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
  283. __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
  284. *__result.__seg_ &= ~__m;
  285. if (__result.__ctz_ > __first.__ctz_)
  286. *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
  287. else
  288. *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
  289. __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
  290. __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
  291. __dn -= __ddn;
  292. if (__dn > 0) {
  293. __m = ~__storage_type(0) >> (__bits_per_word - __dn);
  294. *__result.__seg_ &= ~__m;
  295. *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
  296. __result.__ctz_ = static_cast<unsigned>(__dn);
  297. }
  298. ++__first.__seg_;
  299. // __first.__ctz_ = 0;
  300. }
  301. // __first.__ctz_ == 0;
  302. // do middle words
  303. unsigned __clz_r = __bits_per_word - __result.__ctz_;
  304. __storage_type __m = ~__storage_type(0) << __result.__ctz_;
  305. for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
  306. __storage_type __b = *__first.__seg_;
  307. *__result.__seg_ &= ~__m;
  308. *__result.__seg_ |= __b << __result.__ctz_;
  309. ++__result.__seg_;
  310. *__result.__seg_ &= __m;
  311. *__result.__seg_ |= __b >> __clz_r;
  312. }
  313. // do last word
  314. if (__n > 0) {
  315. __m = ~__storage_type(0) >> (__bits_per_word - __n);
  316. __storage_type __b = *__first.__seg_ & __m;
  317. __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
  318. __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
  319. *__result.__seg_ &= ~__m;
  320. *__result.__seg_ |= __b << __result.__ctz_;
  321. __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
  322. __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
  323. __n -= __dn;
  324. if (__n > 0) {
  325. __m = ~__storage_type(0) >> (__bits_per_word - __n);
  326. *__result.__seg_ &= ~__m;
  327. *__result.__seg_ |= __b >> __dn;
  328. __result.__ctz_ = static_cast<unsigned>(__n);
  329. }
  330. }
  331. }
  332. return __result;
  333. }
  334. template <class _Cp, bool _IsConst>
  335. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false>
  336. copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
  337. if (__first.__ctz_ == __result.__ctz_)
  338. return std::__copy_aligned(__first, __last, __result);
  339. return std::__copy_unaligned(__first, __last, __result);
  340. }
  341. // copy_backward
  342. template <class _Cp, bool _IsConst>
  343. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned(
  344. __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
  345. using _In = __bit_iterator<_Cp, _IsConst>;
  346. using difference_type = typename _In::difference_type;
  347. using __storage_type = typename _In::__storage_type;
  348. const int __bits_per_word = _In::__bits_per_word;
  349. difference_type __n = __last - __first;
  350. if (__n > 0) {
  351. // do first word
  352. if (__last.__ctz_ != 0) {
  353. difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n);
  354. __n -= __dn;
  355. unsigned __clz = __bits_per_word - __last.__ctz_;
  356. __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
  357. __storage_type __b = *__last.__seg_ & __m;
  358. *__result.__seg_ &= ~__m;
  359. *__result.__seg_ |= __b;
  360. __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
  361. // __last.__ctz_ = 0
  362. }
  363. // __last.__ctz_ == 0 || __n == 0
  364. // __result.__ctz_ == 0 || __n == 0
  365. // do middle words
  366. __storage_type __nw = __n / __bits_per_word;
  367. __result.__seg_ -= __nw;
  368. __last.__seg_ -= __nw;
  369. std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_));
  370. __n -= __nw * __bits_per_word;
  371. // do last word
  372. if (__n > 0) {
  373. __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
  374. __storage_type __b = *--__last.__seg_ & __m;
  375. *--__result.__seg_ &= ~__m;
  376. *__result.__seg_ |= __b;
  377. __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
  378. }
  379. }
  380. return __result;
  381. }
  382. template <class _Cp, bool _IsConst>
  383. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned(
  384. __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
  385. using _In = __bit_iterator<_Cp, _IsConst>;
  386. using difference_type = typename _In::difference_type;
  387. using __storage_type = typename _In::__storage_type;
  388. const int __bits_per_word = _In::__bits_per_word;
  389. difference_type __n = __last - __first;
  390. if (__n > 0) {
  391. // do first word
  392. if (__last.__ctz_ != 0) {
  393. difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n);
  394. __n -= __dn;
  395. unsigned __clz_l = __bits_per_word - __last.__ctz_;
  396. __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
  397. __storage_type __b = *__last.__seg_ & __m;
  398. unsigned __clz_r = __bits_per_word - __result.__ctz_;
  399. __storage_type __ddn = std::min(__dn, static_cast<difference_type>(__result.__ctz_));
  400. if (__ddn > 0) {
  401. __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
  402. *__result.__seg_ &= ~__m;
  403. if (__result.__ctz_ > __last.__ctz_)
  404. *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
  405. else
  406. *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
  407. __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
  408. __dn -= __ddn;
  409. }
  410. if (__dn > 0) {
  411. // __result.__ctz_ == 0
  412. --__result.__seg_;
  413. __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
  414. __m = ~__storage_type(0) << __result.__ctz_;
  415. *__result.__seg_ &= ~__m;
  416. __last.__ctz_ -= __dn + __ddn;
  417. *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
  418. }
  419. // __last.__ctz_ = 0
  420. }
  421. // __last.__ctz_ == 0 || __n == 0
  422. // __result.__ctz_ != 0 || __n == 0
  423. // do middle words
  424. unsigned __clz_r = __bits_per_word - __result.__ctz_;
  425. __storage_type __m = ~__storage_type(0) >> __clz_r;
  426. for (; __n >= __bits_per_word; __n -= __bits_per_word) {
  427. __storage_type __b = *--__last.__seg_;
  428. *__result.__seg_ &= ~__m;
  429. *__result.__seg_ |= __b >> __clz_r;
  430. *--__result.__seg_ &= __m;
  431. *__result.__seg_ |= __b << __result.__ctz_;
  432. }
  433. // do last word
  434. if (__n > 0) {
  435. __m = ~__storage_type(0) << (__bits_per_word - __n);
  436. __storage_type __b = *--__last.__seg_ & __m;
  437. __clz_r = __bits_per_word - __result.__ctz_;
  438. __storage_type __dn = std::min(__n, static_cast<difference_type>(__result.__ctz_));
  439. __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
  440. *__result.__seg_ &= ~__m;
  441. *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
  442. __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word);
  443. __n -= __dn;
  444. if (__n > 0) {
  445. // __result.__ctz_ == 0
  446. --__result.__seg_;
  447. __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
  448. __m = ~__storage_type(0) << __result.__ctz_;
  449. *__result.__seg_ &= ~__m;
  450. *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
  451. }
  452. }
  453. }
  454. return __result;
  455. }
  456. template <class _Cp, bool _IsConst>
  457. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy_backward(
  458. __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
  459. if (__last.__ctz_ == __result.__ctz_)
  460. return std::__copy_backward_aligned(__first, __last, __result);
  461. return std::__copy_backward_unaligned(__first, __last, __result);
  462. }
  463. // move
  464. template <class _Cp, bool _IsConst>
  465. inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
  466. move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
  467. return std::copy(__first, __last, __result);
  468. }
  469. // move_backward
  470. template <class _Cp, bool _IsConst>
  471. inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward(
  472. __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) {
  473. return std::copy_backward(__first, __last, __result);
  474. }
  475. // swap_ranges
  476. template <class _Cl, class _Cr>
  477. _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned(
  478. __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) {
  479. using _I1 = __bit_iterator<_Cl, false>;
  480. using difference_type = typename _I1::difference_type;
  481. using __storage_type = typename _I1::__storage_type;
  482. const int __bits_per_word = _I1::__bits_per_word;
  483. difference_type __n = __last - __first;
  484. if (__n > 0) {
  485. // do first word
  486. if (__first.__ctz_ != 0) {
  487. unsigned __clz = __bits_per_word - __first.__ctz_;
  488. difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
  489. __n -= __dn;
  490. __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
  491. __storage_type __b1 = *__first.__seg_ & __m;
  492. *__first.__seg_ &= ~__m;
  493. __storage_type __b2 = *__result.__seg_ & __m;
  494. *__result.__seg_ &= ~__m;
  495. *__result.__seg_ |= __b1;
  496. *__first.__seg_ |= __b2;
  497. __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
  498. __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
  499. ++__first.__seg_;
  500. // __first.__ctz_ = 0;
  501. }
  502. // __first.__ctz_ == 0;
  503. // do middle words
  504. for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
  505. swap(*__first.__seg_, *__result.__seg_);
  506. // do last word
  507. if (__n > 0) {
  508. __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
  509. __storage_type __b1 = *__first.__seg_ & __m;
  510. *__first.__seg_ &= ~__m;
  511. __storage_type __b2 = *__result.__seg_ & __m;
  512. *__result.__seg_ &= ~__m;
  513. *__result.__seg_ |= __b1;
  514. *__first.__seg_ |= __b2;
  515. __result.__ctz_ = static_cast<unsigned>(__n);
  516. }
  517. }
  518. return __result;
  519. }
  520. template <class _Cl, class _Cr>
  521. _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned(
  522. __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) {
  523. using _I1 = __bit_iterator<_Cl, false>;
  524. using difference_type = typename _I1::difference_type;
  525. using __storage_type = typename _I1::__storage_type;
  526. const int __bits_per_word = _I1::__bits_per_word;
  527. difference_type __n = __last - __first;
  528. if (__n > 0) {
  529. // do first word
  530. if (__first.__ctz_ != 0) {
  531. unsigned __clz_f = __bits_per_word - __first.__ctz_;
  532. difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
  533. __n -= __dn;
  534. __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
  535. __storage_type __b1 = *__first.__seg_ & __m;
  536. *__first.__seg_ &= ~__m;
  537. unsigned __clz_r = __bits_per_word - __result.__ctz_;
  538. __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
  539. __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
  540. __storage_type __b2 = *__result.__seg_ & __m;
  541. *__result.__seg_ &= ~__m;
  542. if (__result.__ctz_ > __first.__ctz_) {
  543. unsigned __s = __result.__ctz_ - __first.__ctz_;
  544. *__result.__seg_ |= __b1 << __s;
  545. *__first.__seg_ |= __b2 >> __s;
  546. } else {
  547. unsigned __s = __first.__ctz_ - __result.__ctz_;
  548. *__result.__seg_ |= __b1 >> __s;
  549. *__first.__seg_ |= __b2 << __s;
  550. }
  551. __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
  552. __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
  553. __dn -= __ddn;
  554. if (__dn > 0) {
  555. __m = ~__storage_type(0) >> (__bits_per_word - __dn);
  556. __b2 = *__result.__seg_ & __m;
  557. *__result.__seg_ &= ~__m;
  558. unsigned __s = __first.__ctz_ + __ddn;
  559. *__result.__seg_ |= __b1 >> __s;
  560. *__first.__seg_ |= __b2 << __s;
  561. __result.__ctz_ = static_cast<unsigned>(__dn);
  562. }
  563. ++__first.__seg_;
  564. // __first.__ctz_ = 0;
  565. }
  566. // __first.__ctz_ == 0;
  567. // do middle words
  568. __storage_type __m = ~__storage_type(0) << __result.__ctz_;
  569. unsigned __clz_r = __bits_per_word - __result.__ctz_;
  570. for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) {
  571. __storage_type __b1 = *__first.__seg_;
  572. __storage_type __b2 = *__result.__seg_ & __m;
  573. *__result.__seg_ &= ~__m;
  574. *__result.__seg_ |= __b1 << __result.__ctz_;
  575. *__first.__seg_ = __b2 >> __result.__ctz_;
  576. ++__result.__seg_;
  577. __b2 = *__result.__seg_ & ~__m;
  578. *__result.__seg_ &= __m;
  579. *__result.__seg_ |= __b1 >> __clz_r;
  580. *__first.__seg_ |= __b2 << __clz_r;
  581. }
  582. // do last word
  583. if (__n > 0) {
  584. __m = ~__storage_type(0) >> (__bits_per_word - __n);
  585. __storage_type __b1 = *__first.__seg_ & __m;
  586. *__first.__seg_ &= ~__m;
  587. __storage_type __dn = std::min<__storage_type>(__n, __clz_r);
  588. __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
  589. __storage_type __b2 = *__result.__seg_ & __m;
  590. *__result.__seg_ &= ~__m;
  591. *__result.__seg_ |= __b1 << __result.__ctz_;
  592. *__first.__seg_ |= __b2 >> __result.__ctz_;
  593. __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
  594. __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
  595. __n -= __dn;
  596. if (__n > 0) {
  597. __m = ~__storage_type(0) >> (__bits_per_word - __n);
  598. __b2 = *__result.__seg_ & __m;
  599. *__result.__seg_ &= ~__m;
  600. *__result.__seg_ |= __b1 >> __dn;
  601. *__first.__seg_ |= __b2 << __dn;
  602. __result.__ctz_ = static_cast<unsigned>(__n);
  603. }
  604. }
  605. }
  606. return __result;
  607. }
  608. template <class _Cl, class _Cr>
  609. inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges(
  610. __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) {
  611. if (__first1.__ctz_ == __first2.__ctz_)
  612. return std::__swap_ranges_aligned(__first1, __last1, __first2);
  613. return std::__swap_ranges_unaligned(__first1, __last1, __first2);
  614. }
  615. // rotate
  616. template <class _Cp>
  617. struct __bit_array {
  618. using difference_type = typename _Cp::difference_type;
  619. using __storage_type = typename _Cp::__storage_type;
  620. using __storage_pointer = typename _Cp::__storage_pointer;
  621. using iterator = typename _Cp::iterator;
  622. static const unsigned __bits_per_word = _Cp::__bits_per_word;
  623. static const unsigned _Np = 4;
  624. difference_type __size_;
  625. __storage_type __word_[_Np];
  626. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() {
  627. return static_cast<difference_type>(_Np * __bits_per_word);
  628. }
  629. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) {
  630. if (__libcpp_is_constant_evaluated()) {
  631. for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i)
  632. std::__construct_at(__word_ + __i, 0);
  633. }
  634. }
  635. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() {
  636. return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
  637. }
  638. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() {
  639. return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
  640. static_cast<unsigned>(__size_ % __bits_per_word));
  641. }
  642. };
  643. template <class _Cp>
  644. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false>
  645. rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) {
  646. using _I1 = __bit_iterator<_Cp, false>;
  647. using difference_type = typename _I1::difference_type;
  648. difference_type __d1 = __middle - __first;
  649. difference_type __d2 = __last - __middle;
  650. _I1 __r = __first + __d2;
  651. while (__d1 != 0 && __d2 != 0) {
  652. if (__d1 <= __d2) {
  653. if (__d1 <= __bit_array<_Cp>::capacity()) {
  654. __bit_array<_Cp> __b(__d1);
  655. std::copy(__first, __middle, __b.begin());
  656. std::copy(__b.begin(), __b.end(), std::copy(__middle, __last, __first));
  657. break;
  658. } else {
  659. __bit_iterator<_Cp, false> __mp = std::swap_ranges(__first, __middle, __middle);
  660. __first = __middle;
  661. __middle = __mp;
  662. __d2 -= __d1;
  663. }
  664. } else {
  665. if (__d2 <= __bit_array<_Cp>::capacity()) {
  666. __bit_array<_Cp> __b(__d2);
  667. std::copy(__middle, __last, __b.begin());
  668. std::copy_backward(__b.begin(), __b.end(), std::copy_backward(__first, __middle, __last));
  669. break;
  670. } else {
  671. __bit_iterator<_Cp, false> __mp = __first + __d2;
  672. std::swap_ranges(__first, __mp, __middle);
  673. __first = __mp;
  674. __d1 -= __d2;
  675. }
  676. }
  677. }
  678. return __r;
  679. }
  680. // equal
  681. template <class _Cp, bool _IC1, bool _IC2>
  682. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_unaligned(
  683. __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
  684. using _It = __bit_iterator<_Cp, _IC1>;
  685. using difference_type = typename _It::difference_type;
  686. using __storage_type = typename _It::__storage_type;
  687. const int __bits_per_word = _It::__bits_per_word;
  688. difference_type __n = __last1 - __first1;
  689. if (__n > 0) {
  690. // do first word
  691. if (__first1.__ctz_ != 0) {
  692. unsigned __clz_f = __bits_per_word - __first1.__ctz_;
  693. difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n);
  694. __n -= __dn;
  695. __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
  696. __storage_type __b = *__first1.__seg_ & __m;
  697. unsigned __clz_r = __bits_per_word - __first2.__ctz_;
  698. __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
  699. __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
  700. if (__first2.__ctz_ > __first1.__ctz_) {
  701. if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
  702. return false;
  703. } else {
  704. if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
  705. return false;
  706. }
  707. __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
  708. __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word);
  709. __dn -= __ddn;
  710. if (__dn > 0) {
  711. __m = ~__storage_type(0) >> (__bits_per_word - __dn);
  712. if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
  713. return false;
  714. __first2.__ctz_ = static_cast<unsigned>(__dn);
  715. }
  716. ++__first1.__seg_;
  717. // __first1.__ctz_ = 0;
  718. }
  719. // __first1.__ctz_ == 0;
  720. // do middle words
  721. unsigned __clz_r = __bits_per_word - __first2.__ctz_;
  722. __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
  723. for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) {
  724. __storage_type __b = *__first1.__seg_;
  725. if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
  726. return false;
  727. ++__first2.__seg_;
  728. if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
  729. return false;
  730. }
  731. // do last word
  732. if (__n > 0) {
  733. __m = ~__storage_type(0) >> (__bits_per_word - __n);
  734. __storage_type __b = *__first1.__seg_ & __m;
  735. __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r));
  736. __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
  737. if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
  738. return false;
  739. __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
  740. __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word);
  741. __n -= __dn;
  742. if (__n > 0) {
  743. __m = ~__storage_type(0) >> (__bits_per_word - __n);
  744. if ((*__first2.__seg_ & __m) != (__b >> __dn))
  745. return false;
  746. }
  747. }
  748. }
  749. return true;
  750. }
  751. template <class _Cp, bool _IC1, bool _IC2>
  752. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_aligned(
  753. __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
  754. using _It = __bit_iterator<_Cp, _IC1>;
  755. using difference_type = typename _It::difference_type;
  756. using __storage_type = typename _It::__storage_type;
  757. const int __bits_per_word = _It::__bits_per_word;
  758. difference_type __n = __last1 - __first1;
  759. if (__n > 0) {
  760. // do first word
  761. if (__first1.__ctz_ != 0) {
  762. unsigned __clz = __bits_per_word - __first1.__ctz_;
  763. difference_type __dn = std::min(static_cast<difference_type>(__clz), __n);
  764. __n -= __dn;
  765. __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
  766. if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
  767. return false;
  768. ++__first2.__seg_;
  769. ++__first1.__seg_;
  770. // __first1.__ctz_ = 0;
  771. // __first2.__ctz_ = 0;
  772. }
  773. // __first1.__ctz_ == 0;
  774. // __first2.__ctz_ == 0;
  775. // do middle words
  776. for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
  777. if (*__first2.__seg_ != *__first1.__seg_)
  778. return false;
  779. // do last word
  780. if (__n > 0) {
  781. __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
  782. if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
  783. return false;
  784. }
  785. }
  786. return true;
  787. }
  788. template <class _Cp, bool _IC1, bool _IC2>
  789. inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
  790. equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) {
  791. if (__first1.__ctz_ == __first2.__ctz_)
  792. return std::__equal_aligned(__first1, __last1, __first2);
  793. return std::__equal_unaligned(__first1, __last1, __first2);
  794. }
  795. template <class _Cp, bool _IsConst, typename _Cp::__storage_type>
  796. class __bit_iterator {
  797. public:
  798. using difference_type = typename _Cp::difference_type;
  799. using value_type = bool;
  800. using pointer = __bit_iterator;
  801. #ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
  802. using reference = __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >;
  803. #else
  804. using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >;
  805. #endif
  806. using iterator_category = random_access_iterator_tag;
  807. private:
  808. using __storage_type = typename _Cp::__storage_type;
  809. using __storage_pointer =
  810. __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>;
  811. static const unsigned __bits_per_word = _Cp::__bits_per_word;
  812. __storage_pointer __seg_;
  813. unsigned __ctz_;
  814. public:
  815. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT
  816. #if _LIBCPP_STD_VER >= 14
  817. : __seg_(nullptr),
  818. __ctz_(0)
  819. #endif
  820. {
  821. }
  822. // When _IsConst=false, this is the copy constructor.
  823. // It is non-trivial. Making it trivial would break ABI.
  824. // When _IsConst=true, this is a converting constructor;
  825. // the copy and move constructors are implicitly generated
  826. // and trivial.
  827. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
  828. : __seg_(__it.__seg_),
  829. __ctz_(__it.__ctz_) {}
  830. // When _IsConst=false, we have a user-provided copy constructor,
  831. // so we must also provide a copy assignment operator because
  832. // the implicit generation of a defaulted one is deprecated.
  833. // When _IsConst=true, the assignment operators are
  834. // implicitly generated and trivial.
  835. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator&
  836. operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) {
  837. __seg_ = __it.__seg_;
  838. __ctz_ = __it.__ctz_;
  839. return *this;
  840. }
  841. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
  842. return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >(
  843. __seg_, __storage_type(1) << __ctz_);
  844. }
  845. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() {
  846. if (__ctz_ != __bits_per_word - 1)
  847. ++__ctz_;
  848. else {
  849. __ctz_ = 0;
  850. ++__seg_;
  851. }
  852. return *this;
  853. }
  854. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) {
  855. __bit_iterator __tmp = *this;
  856. ++(*this);
  857. return __tmp;
  858. }
  859. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() {
  860. if (__ctz_ != 0)
  861. --__ctz_;
  862. else {
  863. __ctz_ = __bits_per_word - 1;
  864. --__seg_;
  865. }
  866. return *this;
  867. }
  868. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) {
  869. __bit_iterator __tmp = *this;
  870. --(*this);
  871. return __tmp;
  872. }
  873. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) {
  874. if (__n >= 0)
  875. __seg_ += (__n + __ctz_) / __bits_per_word;
  876. else
  877. __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1) /
  878. static_cast<difference_type>(__bits_per_word);
  879. __n &= (__bits_per_word - 1);
  880. __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word);
  881. return *this;
  882. }
  883. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) {
  884. return *this += -__n;
  885. }
  886. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const {
  887. __bit_iterator __t(*this);
  888. __t += __n;
  889. return __t;
  890. }
  891. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const {
  892. __bit_iterator __t(*this);
  893. __t -= __n;
  894. return __t;
  895. }
  896. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator
  897. operator+(difference_type __n, const __bit_iterator& __it) {
  898. return __it + __n;
  899. }
  900. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend difference_type
  901. operator-(const __bit_iterator& __x, const __bit_iterator& __y) {
  902. return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;
  903. }
  904. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const {
  905. return *(*this + __n);
  906. }
  907. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  908. operator==(const __bit_iterator& __x, const __bit_iterator& __y) {
  909. return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;
  910. }
  911. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  912. operator!=(const __bit_iterator& __x, const __bit_iterator& __y) {
  913. return !(__x == __y);
  914. }
  915. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  916. operator<(const __bit_iterator& __x, const __bit_iterator& __y) {
  917. return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);
  918. }
  919. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  920. operator>(const __bit_iterator& __x, const __bit_iterator& __y) {
  921. return __y < __x;
  922. }
  923. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  924. operator<=(const __bit_iterator& __x, const __bit_iterator& __y) {
  925. return !(__y < __x);
  926. }
  927. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  928. operator>=(const __bit_iterator& __x, const __bit_iterator& __y) {
  929. return !(__x < __y);
  930. }
  931. private:
  932. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_iterator(
  933. __storage_pointer __s, unsigned __ctz) _NOEXCEPT
  934. : __seg_(__s),
  935. __ctz_(__ctz) {}
  936. friend typename _Cp::__self;
  937. friend class __bit_reference<_Cp>;
  938. friend class __bit_const_reference<_Cp>;
  939. friend class __bit_iterator<_Cp, true>;
  940. template <class _Dp>
  941. friend struct __bit_array;
  942. template <bool _FillValue, class _Dp>
  943. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void __fill_n(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
  944. template <class _Dp, bool _IC>
  945. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned(
  946. __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
  947. template <class _Dp, bool _IC>
  948. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_unaligned(
  949. __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
  950. template <class _Dp, bool _IC>
  951. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
  952. copy(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
  953. template <class _Dp, bool _IC>
  954. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned(
  955. __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
  956. template <class _Dp, bool _IC>
  957. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_unaligned(
  958. __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
  959. template <class _Dp, bool _IC>
  960. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
  961. copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
  962. template <class _Cl, class _Cr>
  963. friend __bit_iterator<_Cr, false>
  964. __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
  965. template <class _Cl, class _Cr>
  966. friend __bit_iterator<_Cr, false>
  967. __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
  968. template <class _Cl, class _Cr>
  969. friend __bit_iterator<_Cr, false>
  970. swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
  971. template <class _Dp>
  972. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
  973. rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>);
  974. template <class _Dp, bool _IC1, bool _IC2>
  975. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  976. __equal_aligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
  977. template <class _Dp, bool _IC1, bool _IC2>
  978. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  979. __equal_unaligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
  980. template <class _Dp, bool _IC1, bool _IC2>
  981. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
  982. equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>);
  983. template <bool _ToFind, class _Dp, bool _IC>
  984. _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC>
  985. __find_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
  986. template <bool _ToCount, class _Dp, bool _IC>
  987. friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
  988. __count_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
  989. };
  990. _LIBCPP_END_NAMESPACE_STD
  991. _LIBCPP_POP_MACROS
  992. #endif // _LIBCPP___BIT_REFERENCE