blob: 3d4da1cbb68afb464347ae9834c2b3b0dad2d4a1 [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Chandler Carruth57b08b02019-01-19 10:56:40 +00004// 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
Howard Hinnant3e519522010-05-11 19:42:16 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___BIT_REFERENCE
11#define _LIBCPP___BIT_REFERENCE
12
13#include <__config>
Marshall Clowecb7f4d2018-08-17 17:27:25 +000014#include <bit>
Howard Hinnant3e519522010-05-11 19:42:16 +000015#include <algorithm>
16
Howard Hinnant073458b2011-10-17 20:05:10 +000017#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant3e519522010-05-11 19:42:16 +000018#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +000019#endif
Howard Hinnant3e519522010-05-11 19:42:16 +000020
Eric Fiseliera016efb2017-05-31 22:07:49 +000021_LIBCPP_PUSH_MACROS
22#include <__undef_macros>
23
24
Howard Hinnant3e519522010-05-11 19:42:16 +000025_LIBCPP_BEGIN_NAMESPACE_STD
26
Howard Hinnant0ae9efe2012-05-07 16:50:38 +000027template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;
Howard Hinnantc003db12011-11-29 18:15:50 +000028template <class _Cp> class __bit_const_reference;
Howard Hinnant3e519522010-05-11 19:42:16 +000029
Howard Hinnanta7744562011-07-02 20:33:23 +000030template <class _Tp>
31struct __has_storage_type
32{
33 static const bool value = false;
34};
35
Howard Hinnantc003db12011-11-29 18:15:50 +000036template <class _Cp, bool = __has_storage_type<_Cp>::value>
Howard Hinnant3e519522010-05-11 19:42:16 +000037class __bit_reference
38{
Howard Hinnantc003db12011-11-29 18:15:50 +000039 typedef typename _Cp::__storage_type __storage_type;
40 typedef typename _Cp::__storage_pointer __storage_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +000041
42 __storage_pointer __seg_;
43 __storage_type __mask_;
44
Howard Hinnantc003db12011-11-29 18:15:50 +000045 friend typename _Cp::__self;
Eric Fiselier541f9e22017-01-06 21:42:58 +000046
Howard Hinnantc003db12011-11-29 18:15:50 +000047 friend class __bit_const_reference<_Cp>;
48 friend class __bit_iterator<_Cp, false>;
Howard Hinnant3e519522010-05-11 19:42:16 +000049public:
Fangrui Songb7eb30d2019-12-05 15:54:08 -080050 _LIBCPP_INLINE_VISIBILITY
51 __bit_reference(const __bit_reference&) = default;
52
Howard Hinnantd368a842011-05-27 20:52:28 +000053 _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
54 {return static_cast<bool>(*__seg_ & __mask_);}
55 _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT
56 {return !static_cast<bool>(*this);}
Howard Hinnant3e519522010-05-11 19:42:16 +000057
58 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd368a842011-05-27 20:52:28 +000059 __bit_reference& operator=(bool __x) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +000060 {
61 if (__x)
62 *__seg_ |= __mask_;
63 else
64 *__seg_ &= ~__mask_;
65 return *this;
66 }
Howard Hinnantb3371f62010-08-22 00:02:43 +000067
Howard Hinnant3e519522010-05-11 19:42:16 +000068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd368a842011-05-27 20:52:28 +000069 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
70 {return operator=(static_cast<bool>(__x));}
Howard Hinnant3e519522010-05-11 19:42:16 +000071
Howard Hinnantd368a842011-05-27 20:52:28 +000072 _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
Howard Hinnantc003db12011-11-29 18:15:50 +000073 _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
Marshall Clowf3b851f2019-07-12 01:01:55 +000074 {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
Howard Hinnant3e519522010-05-11 19:42:16 +000075private:
76 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd368a842011-05-27 20:52:28 +000077 __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
78 : __seg_(__s), __mask_(__m) {}
Howard Hinnant3e519522010-05-11 19:42:16 +000079};
80
Howard Hinnantc003db12011-11-29 18:15:50 +000081template <class _Cp>
82class __bit_reference<_Cp, false>
Howard Hinnanta7744562011-07-02 20:33:23 +000083{
84};
85
Howard Hinnantd9db9f92013-03-26 13:48:57 +000086template <class _Cp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +000087inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd9db9f92013-03-26 13:48:57 +000088void
89swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
90{
91 bool __t = __x;
92 __x = __y;
93 __y = __t;
94}
95
Howard Hinnantc003db12011-11-29 18:15:50 +000096template <class _Cp, class _Dp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +000097inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +000098void
Howard Hinnantc003db12011-11-29 18:15:50 +000099swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000100{
101 bool __t = __x;
102 __x = __y;
103 __y = __t;
104}
105
Howard Hinnantc003db12011-11-29 18:15:50 +0000106template <class _Cp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +0000107inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000108void
Howard Hinnantc003db12011-11-29 18:15:50 +0000109swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000110{
111 bool __t = __x;
112 __x = __y;
113 __y = __t;
114}
115
Howard Hinnantc003db12011-11-29 18:15:50 +0000116template <class _Cp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +0000117inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000118void
Howard Hinnantc003db12011-11-29 18:15:50 +0000119swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000120{
121 bool __t = __x;
122 __x = __y;
123 __y = __t;
124}
125
Howard Hinnantc003db12011-11-29 18:15:50 +0000126template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000127class __bit_const_reference
128{
Howard Hinnantc003db12011-11-29 18:15:50 +0000129 typedef typename _Cp::__storage_type __storage_type;
130 typedef typename _Cp::__const_storage_pointer __storage_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000131
132 __storage_pointer __seg_;
133 __storage_type __mask_;
134
Howard Hinnantc003db12011-11-29 18:15:50 +0000135 friend typename _Cp::__self;
Howard Hinnantc003db12011-11-29 18:15:50 +0000136 friend class __bit_iterator<_Cp, true>;
Howard Hinnant3e519522010-05-11 19:42:16 +0000137public:
138 _LIBCPP_INLINE_VISIBILITY
Fangrui Songb7eb30d2019-12-05 15:54:08 -0800139 __bit_const_reference(const __bit_const_reference&) = default;
140
141 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000142 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000143 : __seg_(__x.__seg_), __mask_(__x.__mask_) {}
144
Howard Hinnanteeac9fc2012-07-07 17:04:52 +0000145 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT
Howard Hinnantd368a842011-05-27 20:52:28 +0000146 {return static_cast<bool>(*__seg_ & __mask_);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000147
Howard Hinnantc003db12011-11-29 18:15:50 +0000148 _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
Marshall Clowf3b851f2019-07-12 01:01:55 +0000149 {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__libcpp_ctz(__mask_)));}
Howard Hinnant3e519522010-05-11 19:42:16 +0000150private:
151 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteeac9fc2012-07-07 17:04:52 +0000152 _LIBCPP_CONSTEXPR
Howard Hinnantd368a842011-05-27 20:52:28 +0000153 __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
154 : __seg_(__s), __mask_(__m) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000155
Fangrui Songb7eb30d2019-12-05 15:54:08 -0800156 __bit_const_reference& operator=(const __bit_const_reference&) = delete;
Howard Hinnant3e519522010-05-11 19:42:16 +0000157};
158
159// find
160
Howard Hinnant423a8d72012-05-10 14:55:00 +0000161template <class _Cp, bool _IsConst>
162__bit_iterator<_Cp, _IsConst>
163__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000164{
Howard Hinnant423a8d72012-05-10 14:55:00 +0000165 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000166 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000167 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000168 // do first partial word
169 if (__first.__ctz_ != 0)
170 {
171 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000172 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000173 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
174 __storage_type __b = *__first.__seg_ & __m;
175 if (__b)
Marshall Clowf3b851f2019-07-12 01:01:55 +0000176 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
Howard Hinnant303e27d2013-08-07 20:42:16 +0000177 if (__n == __dn)
Marshall Clow0fc6e982014-05-06 15:33:23 +0000178 return __first + __n;
Howard Hinnant3e519522010-05-11 19:42:16 +0000179 __n -= __dn;
180 ++__first.__seg_;
181 }
182 // do middle whole words
183 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
184 if (*__first.__seg_)
Marshall Clowf3b851f2019-07-12 01:01:55 +0000185 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(*__first.__seg_)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000186 // do last partial word
187 if (__n > 0)
188 {
189 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
190 __storage_type __b = *__first.__seg_ & __m;
191 if (__b)
Marshall Clowf3b851f2019-07-12 01:01:55 +0000192 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000193 }
194 return _It(__first.__seg_, static_cast<unsigned>(__n));
195}
196
Howard Hinnant423a8d72012-05-10 14:55:00 +0000197template <class _Cp, bool _IsConst>
198__bit_iterator<_Cp, _IsConst>
199__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000200{
Howard Hinnant423a8d72012-05-10 14:55:00 +0000201 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000202 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000203 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000204 // do first partial word
205 if (__first.__ctz_ != 0)
206 {
207 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000208 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000209 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Howard Hinnant423a8d72012-05-10 14:55:00 +0000210 __storage_type __b = ~*__first.__seg_ & __m;
Howard Hinnant3e519522010-05-11 19:42:16 +0000211 if (__b)
Marshall Clowf3b851f2019-07-12 01:01:55 +0000212 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
Howard Hinnant303e27d2013-08-07 20:42:16 +0000213 if (__n == __dn)
Marshall Clow0fc6e982014-05-06 15:33:23 +0000214 return __first + __n;
Howard Hinnant3e519522010-05-11 19:42:16 +0000215 __n -= __dn;
216 ++__first.__seg_;
217 }
218 // do middle whole words
219 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
220 {
221 __storage_type __b = ~*__first.__seg_;
222 if (__b)
Marshall Clowf3b851f2019-07-12 01:01:55 +0000223 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000224 }
225 // do last partial word
226 if (__n > 0)
227 {
228 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Howard Hinnant423a8d72012-05-10 14:55:00 +0000229 __storage_type __b = ~*__first.__seg_ & __m;
Howard Hinnant3e519522010-05-11 19:42:16 +0000230 if (__b)
Marshall Clowf3b851f2019-07-12 01:01:55 +0000231 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__libcpp_ctz(__b)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000232 }
233 return _It(__first.__seg_, static_cast<unsigned>(__n));
234}
235
Howard Hinnant423a8d72012-05-10 14:55:00 +0000236template <class _Cp, bool _IsConst, class _Tp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000237inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant423a8d72012-05-10 14:55:00 +0000238__bit_iterator<_Cp, _IsConst>
239find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000240{
Howard Hinnante4383372011-10-22 20:59:45 +0000241 if (static_cast<bool>(__value_))
Howard Hinnantc003db12011-11-29 18:15:50 +0000242 return __find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
243 return __find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
Howard Hinnant3e519522010-05-11 19:42:16 +0000244}
245
246// count
247
Howard Hinnant423a8d72012-05-10 14:55:00 +0000248template <class _Cp, bool _IsConst>
249typename __bit_iterator<_Cp, _IsConst>::difference_type
250__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000251{
Howard Hinnant423a8d72012-05-10 14:55:00 +0000252 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000253 typedef typename _It::__storage_type __storage_type;
254 typedef typename _It::difference_type difference_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000255 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000256 difference_type __r = 0;
257 // do first partial word
258 if (__first.__ctz_ != 0)
259 {
260 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000261 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000262 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Marshall Clowf3b851f2019-07-12 01:01:55 +0000263 __r = _VSTD::__libcpp_popcount(*__first.__seg_ & __m);
Howard Hinnant3e519522010-05-11 19:42:16 +0000264 __n -= __dn;
265 ++__first.__seg_;
266 }
267 // do middle whole words
268 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
Marshall Clowf3b851f2019-07-12 01:01:55 +0000269 __r += _VSTD::__libcpp_popcount(*__first.__seg_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000270 // do last partial word
271 if (__n > 0)
272 {
273 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Marshall Clowf3b851f2019-07-12 01:01:55 +0000274 __r += _VSTD::__libcpp_popcount(*__first.__seg_ & __m);
Howard Hinnant3e519522010-05-11 19:42:16 +0000275 }
276 return __r;
277}
278
Howard Hinnant423a8d72012-05-10 14:55:00 +0000279template <class _Cp, bool _IsConst>
280typename __bit_iterator<_Cp, _IsConst>::difference_type
281__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000282{
Howard Hinnant423a8d72012-05-10 14:55:00 +0000283 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000284 typedef typename _It::__storage_type __storage_type;
285 typedef typename _It::difference_type difference_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000286 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000287 difference_type __r = 0;
288 // do first partial word
289 if (__first.__ctz_ != 0)
290 {
291 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000292 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000293 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Marshall Clowf3b851f2019-07-12 01:01:55 +0000294 __r = _VSTD::__libcpp_popcount(~*__first.__seg_ & __m);
Howard Hinnant3e519522010-05-11 19:42:16 +0000295 __n -= __dn;
296 ++__first.__seg_;
297 }
298 // do middle whole words
299 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
Marshall Clowf3b851f2019-07-12 01:01:55 +0000300 __r += _VSTD::__libcpp_popcount(~*__first.__seg_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000301 // do last partial word
302 if (__n > 0)
303 {
304 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Marshall Clowf3b851f2019-07-12 01:01:55 +0000305 __r += _VSTD::__libcpp_popcount(~*__first.__seg_ & __m);
Howard Hinnant3e519522010-05-11 19:42:16 +0000306 }
307 return __r;
308}
309
Howard Hinnant423a8d72012-05-10 14:55:00 +0000310template <class _Cp, bool _IsConst, class _Tp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000311inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant423a8d72012-05-10 14:55:00 +0000312typename __bit_iterator<_Cp, _IsConst>::difference_type
313count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000314{
Howard Hinnante4383372011-10-22 20:59:45 +0000315 if (static_cast<bool>(__value_))
Howard Hinnantc003db12011-11-29 18:15:50 +0000316 return __count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
317 return __count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
Howard Hinnant3e519522010-05-11 19:42:16 +0000318}
319
320// fill_n
321
Howard Hinnantc003db12011-11-29 18:15:50 +0000322template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000323void
Howard Hinnantc003db12011-11-29 18:15:50 +0000324__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000325{
Howard Hinnantc003db12011-11-29 18:15:50 +0000326 typedef __bit_iterator<_Cp, false> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000327 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000328 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000329 // do first partial word
330 if (__first.__ctz_ != 0)
331 {
332 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000333 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000334 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
335 *__first.__seg_ &= ~__m;
336 __n -= __dn;
337 ++__first.__seg_;
338 }
339 // do middle whole words
340 __storage_type __nw = __n / __bits_per_word;
Eric Fiselier0068c592019-11-16 17:13:26 -0500341 _VSTD::memset(_VSTD::__to_address(__first.__seg_), 0, __nw * sizeof(__storage_type));
Howard Hinnant3e519522010-05-11 19:42:16 +0000342 __n -= __nw * __bits_per_word;
343 // do last partial word
344 if (__n > 0)
345 {
346 __first.__seg_ += __nw;
347 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
348 *__first.__seg_ &= ~__m;
349 }
350}
351
Howard Hinnantc003db12011-11-29 18:15:50 +0000352template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000353void
Howard Hinnantc003db12011-11-29 18:15:50 +0000354__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000355{
Howard Hinnantc003db12011-11-29 18:15:50 +0000356 typedef __bit_iterator<_Cp, false> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000357 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000358 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000359 // do first partial word
360 if (__first.__ctz_ != 0)
361 {
362 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000363 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000364 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
365 *__first.__seg_ |= __m;
366 __n -= __dn;
367 ++__first.__seg_;
368 }
369 // do middle whole words
370 __storage_type __nw = __n / __bits_per_word;
Eric Fiselier0068c592019-11-16 17:13:26 -0500371 _VSTD::memset(_VSTD::__to_address(__first.__seg_), -1, __nw * sizeof(__storage_type));
Howard Hinnant3e519522010-05-11 19:42:16 +0000372 __n -= __nw * __bits_per_word;
373 // do last partial word
374 if (__n > 0)
375 {
376 __first.__seg_ += __nw;
377 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
378 *__first.__seg_ |= __m;
379 }
380}
381
Howard Hinnantc003db12011-11-29 18:15:50 +0000382template <class _Cp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +0000383inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000384void
Howard Hinnantc003db12011-11-29 18:15:50 +0000385fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000386{
387 if (__n > 0)
388 {
Howard Hinnante4383372011-10-22 20:59:45 +0000389 if (__value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000390 __fill_n_true(__first, __n);
391 else
392 __fill_n_false(__first, __n);
393 }
394}
395
396// fill
397
Howard Hinnantc003db12011-11-29 18:15:50 +0000398template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000399inline _LIBCPP_INLINE_VISIBILITY
400void
Howard Hinnantc003db12011-11-29 18:15:50 +0000401fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000402{
Howard Hinnantc003db12011-11-29 18:15:50 +0000403 _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000404}
405
406// copy
407
Howard Hinnantc003db12011-11-29 18:15:50 +0000408template <class _Cp, bool _IsConst>
409__bit_iterator<_Cp, false>
410__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
411 __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000412{
Howard Hinnantc003db12011-11-29 18:15:50 +0000413 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnant3e519522010-05-11 19:42:16 +0000414 typedef typename _In::difference_type difference_type;
415 typedef typename _In::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000416 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000417 difference_type __n = __last - __first;
418 if (__n > 0)
419 {
420 // do first word
421 if (__first.__ctz_ != 0)
422 {
423 unsigned __clz = __bits_per_word - __first.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000424 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000425 __n -= __dn;
426 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
427 __storage_type __b = *__first.__seg_ & __m;
428 *__result.__seg_ &= ~__m;
429 *__result.__seg_ |= __b;
430 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
431 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
432 ++__first.__seg_;
433 // __first.__ctz_ = 0;
434 }
435 // __first.__ctz_ == 0;
436 // do middle words
437 __storage_type __nw = __n / __bits_per_word;
Eric Fiselier0068c592019-11-16 17:13:26 -0500438 _VSTD::memmove(_VSTD::__to_address(__result.__seg_),
439 _VSTD::__to_address(__first.__seg_),
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000440 __nw * sizeof(__storage_type));
Howard Hinnant3e519522010-05-11 19:42:16 +0000441 __n -= __nw * __bits_per_word;
442 __result.__seg_ += __nw;
443 // do last word
444 if (__n > 0)
445 {
446 __first.__seg_ += __nw;
447 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
448 __storage_type __b = *__first.__seg_ & __m;
449 *__result.__seg_ &= ~__m;
450 *__result.__seg_ |= __b;
451 __result.__ctz_ = static_cast<unsigned>(__n);
452 }
453 }
454 return __result;
455}
456
Howard Hinnantc003db12011-11-29 18:15:50 +0000457template <class _Cp, bool _IsConst>
458__bit_iterator<_Cp, false>
459__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
460 __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000461{
Howard Hinnantc003db12011-11-29 18:15:50 +0000462 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnant3e519522010-05-11 19:42:16 +0000463 typedef typename _In::difference_type difference_type;
464 typedef typename _In::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000465 static const int __bits_per_word = _In::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000466 difference_type __n = __last - __first;
467 if (__n > 0)
468 {
469 // do first word
470 if (__first.__ctz_ != 0)
471 {
472 unsigned __clz_f = __bits_per_word - __first.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000473 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000474 __n -= __dn;
475 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
476 __storage_type __b = *__first.__seg_ & __m;
477 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000478 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnant3e519522010-05-11 19:42:16 +0000479 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
480 *__result.__seg_ &= ~__m;
481 if (__result.__ctz_ > __first.__ctz_)
482 *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
483 else
484 *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
485 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
486 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
487 __dn -= __ddn;
488 if (__dn > 0)
489 {
490 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
491 *__result.__seg_ &= ~__m;
492 *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
493 __result.__ctz_ = static_cast<unsigned>(__dn);
494 }
495 ++__first.__seg_;
496 // __first.__ctz_ = 0;
497 }
498 // __first.__ctz_ == 0;
499 // do middle words
500 unsigned __clz_r = __bits_per_word - __result.__ctz_;
501 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
502 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
503 {
504 __storage_type __b = *__first.__seg_;
505 *__result.__seg_ &= ~__m;
506 *__result.__seg_ |= __b << __result.__ctz_;
507 ++__result.__seg_;
508 *__result.__seg_ &= __m;
509 *__result.__seg_ |= __b >> __clz_r;
510 }
511 // do last word
512 if (__n > 0)
513 {
514 __m = ~__storage_type(0) >> (__bits_per_word - __n);
515 __storage_type __b = *__first.__seg_ & __m;
Howard Hinnantce48a112011-06-30 21:18:19 +0000516 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
Howard Hinnant3e519522010-05-11 19:42:16 +0000517 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
518 *__result.__seg_ &= ~__m;
519 *__result.__seg_ |= __b << __result.__ctz_;
520 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
521 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
522 __n -= __dn;
523 if (__n > 0)
524 {
525 __m = ~__storage_type(0) >> (__bits_per_word - __n);
526 *__result.__seg_ &= ~__m;
527 *__result.__seg_ |= __b >> __dn;
528 __result.__ctz_ = static_cast<unsigned>(__n);
529 }
530 }
531 }
532 return __result;
533}
534
Howard Hinnantc003db12011-11-29 18:15:50 +0000535template <class _Cp, bool _IsConst>
Howard Hinnant3e519522010-05-11 19:42:16 +0000536inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000537__bit_iterator<_Cp, false>
538copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000539{
540 if (__first.__ctz_ == __result.__ctz_)
541 return __copy_aligned(__first, __last, __result);
542 return __copy_unaligned(__first, __last, __result);
543}
544
545// copy_backward
546
Howard Hinnantc003db12011-11-29 18:15:50 +0000547template <class _Cp, bool _IsConst>
548__bit_iterator<_Cp, false>
549__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
550 __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000551{
Howard Hinnantc003db12011-11-29 18:15:50 +0000552 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnant3e519522010-05-11 19:42:16 +0000553 typedef typename _In::difference_type difference_type;
554 typedef typename _In::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000555 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000556 difference_type __n = __last - __first;
557 if (__n > 0)
558 {
559 // do first word
560 if (__last.__ctz_ != 0)
561 {
Howard Hinnantce48a112011-06-30 21:18:19 +0000562 difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000563 __n -= __dn;
564 unsigned __clz = __bits_per_word - __last.__ctz_;
565 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
566 __storage_type __b = *__last.__seg_ & __m;
567 *__result.__seg_ &= ~__m;
568 *__result.__seg_ |= __b;
569 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
570 __result.__ctz_) % __bits_per_word);
571 // __last.__ctz_ = 0
572 }
573 // __last.__ctz_ == 0 || __n == 0
574 // __result.__ctz_ == 0 || __n == 0
575 // do middle words
576 __storage_type __nw = __n / __bits_per_word;
577 __result.__seg_ -= __nw;
578 __last.__seg_ -= __nw;
Eric Fiselier0068c592019-11-16 17:13:26 -0500579 _VSTD::memmove(_VSTD::__to_address(__result.__seg_),
580 _VSTD::__to_address(__last.__seg_),
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000581 __nw * sizeof(__storage_type));
Howard Hinnant3e519522010-05-11 19:42:16 +0000582 __n -= __nw * __bits_per_word;
583 // do last word
584 if (__n > 0)
585 {
586 __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
587 __storage_type __b = *--__last.__seg_ & __m;
588 *--__result.__seg_ &= ~__m;
589 *__result.__seg_ |= __b;
590 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
591 }
592 }
593 return __result;
594}
595
Howard Hinnantc003db12011-11-29 18:15:50 +0000596template <class _Cp, bool _IsConst>
597__bit_iterator<_Cp, false>
598__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
599 __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000600{
Howard Hinnantc003db12011-11-29 18:15:50 +0000601 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnant3e519522010-05-11 19:42:16 +0000602 typedef typename _In::difference_type difference_type;
603 typedef typename _In::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000604 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000605 difference_type __n = __last - __first;
606 if (__n > 0)
607 {
608 // do first word
609 if (__last.__ctz_ != 0)
610 {
Howard Hinnantce48a112011-06-30 21:18:19 +0000611 difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000612 __n -= __dn;
613 unsigned __clz_l = __bits_per_word - __last.__ctz_;
614 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
615 __storage_type __b = *__last.__seg_ & __m;
616 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000617 __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000618 if (__ddn > 0)
619 {
620 __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
621 *__result.__seg_ &= ~__m;
622 if (__result.__ctz_ > __last.__ctz_)
623 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
624 else
625 *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
626 __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) +
627 __result.__ctz_) % __bits_per_word);
628 __dn -= __ddn;
629 }
630 if (__dn > 0)
631 {
632 // __result.__ctz_ == 0
633 --__result.__seg_;
634 __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
635 __m = ~__storage_type(0) << __result.__ctz_;
636 *__result.__seg_ &= ~__m;
637 __last.__ctz_ -= __dn + __ddn;
638 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
639 }
640 // __last.__ctz_ = 0
641 }
642 // __last.__ctz_ == 0 || __n == 0
643 // __result.__ctz_ != 0 || __n == 0
644 // do middle words
645 unsigned __clz_r = __bits_per_word - __result.__ctz_;
646 __storage_type __m = ~__storage_type(0) >> __clz_r;
647 for (; __n >= __bits_per_word; __n -= __bits_per_word)
648 {
649 __storage_type __b = *--__last.__seg_;
650 *__result.__seg_ &= ~__m;
651 *__result.__seg_ |= __b >> __clz_r;
652 *--__result.__seg_ &= __m;
653 *__result.__seg_ |= __b << __result.__ctz_;
654 }
655 // do last word
656 if (__n > 0)
657 {
658 __m = ~__storage_type(0) << (__bits_per_word - __n);
659 __storage_type __b = *--__last.__seg_ & __m;
Howard Hinnantc2063662011-12-01 20:21:04 +0000660 __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000661 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000662 __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
663 *__result.__seg_ &= ~__m;
664 *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
665 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
666 __result.__ctz_) % __bits_per_word);
667 __n -= __dn;
668 if (__n > 0)
669 {
670 // __result.__ctz_ == 0
671 --__result.__seg_;
672 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
673 __m = ~__storage_type(0) << __result.__ctz_;
674 *__result.__seg_ &= ~__m;
675 *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
676 }
677 }
678 }
679 return __result;
680}
681
Howard Hinnantc003db12011-11-29 18:15:50 +0000682template <class _Cp, bool _IsConst>
Howard Hinnant3e519522010-05-11 19:42:16 +0000683inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000684__bit_iterator<_Cp, false>
685copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000686{
687 if (__last.__ctz_ == __result.__ctz_)
688 return __copy_backward_aligned(__first, __last, __result);
689 return __copy_backward_unaligned(__first, __last, __result);
690}
691
692// move
693
Howard Hinnantc003db12011-11-29 18:15:50 +0000694template <class _Cp, bool _IsConst>
Howard Hinnant3e519522010-05-11 19:42:16 +0000695inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000696__bit_iterator<_Cp, false>
697move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000698{
Howard Hinnantce48a112011-06-30 21:18:19 +0000699 return _VSTD::copy(__first, __last, __result);
Howard Hinnant3e519522010-05-11 19:42:16 +0000700}
701
702// move_backward
703
Howard Hinnantc003db12011-11-29 18:15:50 +0000704template <class _Cp, bool _IsConst>
Howard Hinnant3e519522010-05-11 19:42:16 +0000705inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000706__bit_iterator<_Cp, false>
707move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000708{
Marshall Clow08de4b02014-12-22 19:10:11 +0000709 return _VSTD::copy_backward(__first, __last, __result);
Howard Hinnant3e519522010-05-11 19:42:16 +0000710}
711
712// swap_ranges
713
Howard Hinnantdbe81112011-09-23 16:11:27 +0000714template <class __C1, class __C2>
715__bit_iterator<__C2, false>
716__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
717 __bit_iterator<__C2, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000718{
Howard Hinnantdbe81112011-09-23 16:11:27 +0000719 typedef __bit_iterator<__C1, false> _I1;
Howard Hinnant3e519522010-05-11 19:42:16 +0000720 typedef typename _I1::difference_type difference_type;
721 typedef typename _I1::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000722 const int __bits_per_word = _I1::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000723 difference_type __n = __last - __first;
724 if (__n > 0)
725 {
726 // do first word
727 if (__first.__ctz_ != 0)
728 {
729 unsigned __clz = __bits_per_word - __first.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000730 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000731 __n -= __dn;
732 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
733 __storage_type __b1 = *__first.__seg_ & __m;
734 *__first.__seg_ &= ~__m;
735 __storage_type __b2 = *__result.__seg_ & __m;
736 *__result.__seg_ &= ~__m;
737 *__result.__seg_ |= __b1;
738 *__first.__seg_ |= __b2;
739 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
740 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
741 ++__first.__seg_;
742 // __first.__ctz_ = 0;
743 }
744 // __first.__ctz_ == 0;
745 // do middle words
746 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
747 swap(*__first.__seg_, *__result.__seg_);
748 // do last word
749 if (__n > 0)
750 {
751 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
752 __storage_type __b1 = *__first.__seg_ & __m;
753 *__first.__seg_ &= ~__m;
754 __storage_type __b2 = *__result.__seg_ & __m;
755 *__result.__seg_ &= ~__m;
756 *__result.__seg_ |= __b1;
757 *__first.__seg_ |= __b2;
758 __result.__ctz_ = static_cast<unsigned>(__n);
759 }
760 }
761 return __result;
762}
763
Howard Hinnantdbe81112011-09-23 16:11:27 +0000764template <class __C1, class __C2>
765__bit_iterator<__C2, false>
766__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
767 __bit_iterator<__C2, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000768{
Howard Hinnantdbe81112011-09-23 16:11:27 +0000769 typedef __bit_iterator<__C1, false> _I1;
Howard Hinnant3e519522010-05-11 19:42:16 +0000770 typedef typename _I1::difference_type difference_type;
771 typedef typename _I1::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000772 const int __bits_per_word = _I1::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000773 difference_type __n = __last - __first;
774 if (__n > 0)
775 {
776 // do first word
777 if (__first.__ctz_ != 0)
778 {
779 unsigned __clz_f = __bits_per_word - __first.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000780 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000781 __n -= __dn;
782 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
783 __storage_type __b1 = *__first.__seg_ & __m;
784 *__first.__seg_ &= ~__m;
785 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000786 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnant3e519522010-05-11 19:42:16 +0000787 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
788 __storage_type __b2 = *__result.__seg_ & __m;
789 *__result.__seg_ &= ~__m;
790 if (__result.__ctz_ > __first.__ctz_)
791 {
792 unsigned __s = __result.__ctz_ - __first.__ctz_;
793 *__result.__seg_ |= __b1 << __s;
794 *__first.__seg_ |= __b2 >> __s;
795 }
796 else
797 {
798 unsigned __s = __first.__ctz_ - __result.__ctz_;
799 *__result.__seg_ |= __b1 >> __s;
800 *__first.__seg_ |= __b2 << __s;
801 }
802 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
803 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
804 __dn -= __ddn;
805 if (__dn > 0)
806 {
807 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
808 __b2 = *__result.__seg_ & __m;
809 *__result.__seg_ &= ~__m;
810 unsigned __s = __first.__ctz_ + __ddn;
811 *__result.__seg_ |= __b1 >> __s;
812 *__first.__seg_ |= __b2 << __s;
813 __result.__ctz_ = static_cast<unsigned>(__dn);
814 }
815 ++__first.__seg_;
816 // __first.__ctz_ = 0;
817 }
818 // __first.__ctz_ == 0;
819 // do middle words
820 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
821 unsigned __clz_r = __bits_per_word - __result.__ctz_;
822 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
823 {
824 __storage_type __b1 = *__first.__seg_;
825 __storage_type __b2 = *__result.__seg_ & __m;
826 *__result.__seg_ &= ~__m;
827 *__result.__seg_ |= __b1 << __result.__ctz_;
828 *__first.__seg_ = __b2 >> __result.__ctz_;
829 ++__result.__seg_;
830 __b2 = *__result.__seg_ & ~__m;
831 *__result.__seg_ &= __m;
832 *__result.__seg_ |= __b1 >> __clz_r;
833 *__first.__seg_ |= __b2 << __clz_r;
834 }
835 // do last word
836 if (__n > 0)
837 {
838 __m = ~__storage_type(0) >> (__bits_per_word - __n);
839 __storage_type __b1 = *__first.__seg_ & __m;
840 *__first.__seg_ &= ~__m;
Howard Hinnantce48a112011-06-30 21:18:19 +0000841 __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r);
Howard Hinnant3e519522010-05-11 19:42:16 +0000842 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
843 __storage_type __b2 = *__result.__seg_ & __m;
844 *__result.__seg_ &= ~__m;
845 *__result.__seg_ |= __b1 << __result.__ctz_;
846 *__first.__seg_ |= __b2 >> __result.__ctz_;
847 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
848 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
849 __n -= __dn;
850 if (__n > 0)
851 {
852 __m = ~__storage_type(0) >> (__bits_per_word - __n);
853 __b2 = *__result.__seg_ & __m;
854 *__result.__seg_ &= ~__m;
855 *__result.__seg_ |= __b1 >> __dn;
856 *__first.__seg_ |= __b2 << __dn;
857 __result.__ctz_ = static_cast<unsigned>(__n);
858 }
859 }
860 }
861 return __result;
862}
863
Howard Hinnantdbe81112011-09-23 16:11:27 +0000864template <class __C1, class __C2>
Howard Hinnant3e519522010-05-11 19:42:16 +0000865inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantdbe81112011-09-23 16:11:27 +0000866__bit_iterator<__C2, false>
867swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
868 __bit_iterator<__C2, false> __first2)
Howard Hinnant3e519522010-05-11 19:42:16 +0000869{
870 if (__first1.__ctz_ == __first2.__ctz_)
871 return __swap_ranges_aligned(__first1, __last1, __first2);
872 return __swap_ranges_unaligned(__first1, __last1, __first2);
873}
874
875// rotate
876
Howard Hinnantc003db12011-11-29 18:15:50 +0000877template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000878struct __bit_array
879{
Howard Hinnantc003db12011-11-29 18:15:50 +0000880 typedef typename _Cp::difference_type difference_type;
881 typedef typename _Cp::__storage_type __storage_type;
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000882 typedef typename _Cp::__storage_pointer __storage_pointer;
Howard Hinnantc003db12011-11-29 18:15:50 +0000883 typedef typename _Cp::iterator iterator;
884 static const unsigned __bits_per_word = _Cp::__bits_per_word;
885 static const unsigned _Np = 4;
Howard Hinnant3e519522010-05-11 19:42:16 +0000886
887 difference_type __size_;
Howard Hinnantc003db12011-11-29 18:15:50 +0000888 __storage_type __word_[_Np];
Howard Hinnant3e519522010-05-11 19:42:16 +0000889
890 _LIBCPP_INLINE_VISIBILITY static difference_type capacity()
Howard Hinnantc003db12011-11-29 18:15:50 +0000891 {return static_cast<difference_type>(_Np * __bits_per_word);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000892 _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000893 _LIBCPP_INLINE_VISIBILITY iterator begin()
894 {
895 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
896 }
897 _LIBCPP_INLINE_VISIBILITY iterator end()
898 {
899 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
900 static_cast<unsigned>(__size_ % __bits_per_word));
901 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000902};
903
Howard Hinnantc003db12011-11-29 18:15:50 +0000904template <class _Cp>
905__bit_iterator<_Cp, false>
906rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)
Howard Hinnant3e519522010-05-11 19:42:16 +0000907{
Howard Hinnantc003db12011-11-29 18:15:50 +0000908 typedef __bit_iterator<_Cp, false> _I1;
Howard Hinnant3e519522010-05-11 19:42:16 +0000909 typedef typename _I1::difference_type difference_type;
Howard Hinnant3e519522010-05-11 19:42:16 +0000910 difference_type __d1 = __middle - __first;
911 difference_type __d2 = __last - __middle;
912 _I1 __r = __first + __d2;
913 while (__d1 != 0 && __d2 != 0)
914 {
915 if (__d1 <= __d2)
916 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000917 if (__d1 <= __bit_array<_Cp>::capacity())
Howard Hinnant3e519522010-05-11 19:42:16 +0000918 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000919 __bit_array<_Cp> __b(__d1);
Howard Hinnantce48a112011-06-30 21:18:19 +0000920 _VSTD::copy(__first, __middle, __b.begin());
921 _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first));
Howard Hinnant3e519522010-05-11 19:42:16 +0000922 break;
923 }
924 else
925 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000926 __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle);
Howard Hinnant3e519522010-05-11 19:42:16 +0000927 __first = __middle;
928 __middle = __mp;
929 __d2 -= __d1;
930 }
931 }
932 else
933 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000934 if (__d2 <= __bit_array<_Cp>::capacity())
Howard Hinnant3e519522010-05-11 19:42:16 +0000935 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000936 __bit_array<_Cp> __b(__d2);
Howard Hinnantce48a112011-06-30 21:18:19 +0000937 _VSTD::copy(__middle, __last, __b.begin());
938 _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last));
Howard Hinnant3e519522010-05-11 19:42:16 +0000939 break;
940 }
941 else
942 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000943 __bit_iterator<_Cp, false> __mp = __first + __d2;
Howard Hinnantce48a112011-06-30 21:18:19 +0000944 _VSTD::swap_ranges(__first, __mp, __middle);
Howard Hinnant3e519522010-05-11 19:42:16 +0000945 __first = __mp;
946 __d1 -= __d2;
947 }
948 }
949 }
950 return __r;
951}
952
953// equal
954
Howard Hinnant1237dcc2012-08-05 21:43:11 +0000955template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnant3e519522010-05-11 19:42:16 +0000956bool
Howard Hinnant1237dcc2012-08-05 21:43:11 +0000957__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
958 __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnant3e519522010-05-11 19:42:16 +0000959{
Howard Hinnant1237dcc2012-08-05 21:43:11 +0000960 typedef __bit_iterator<_Cp, _IC1> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000961 typedef typename _It::difference_type difference_type;
962 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000963 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000964 difference_type __n = __last1 - __first1;
965 if (__n > 0)
966 {
967 // do first word
968 if (__first1.__ctz_ != 0)
969 {
970 unsigned __clz_f = __bits_per_word - __first1.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000971 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000972 __n -= __dn;
973 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
974 __storage_type __b = *__first1.__seg_ & __m;
975 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000976 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnant3e519522010-05-11 19:42:16 +0000977 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
978 if (__first2.__ctz_ > __first1.__ctz_)
Howard Hinnant4c0de492012-05-31 23:12:03 +0000979 {
Howard Hinnant3e519522010-05-11 19:42:16 +0000980 if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
981 return false;
Howard Hinnant4c0de492012-05-31 23:12:03 +0000982 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000983 else
Howard Hinnant4c0de492012-05-31 23:12:03 +0000984 {
Howard Hinnant3e519522010-05-11 19:42:16 +0000985 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
986 return false;
Howard Hinnant4c0de492012-05-31 23:12:03 +0000987 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000988 __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
989 __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word);
990 __dn -= __ddn;
991 if (__dn > 0)
992 {
993 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
994 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
995 return false;
996 __first2.__ctz_ = static_cast<unsigned>(__dn);
997 }
998 ++__first1.__seg_;
999 // __first1.__ctz_ = 0;
1000 }
1001 // __first1.__ctz_ == 0;
1002 // do middle words
1003 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
1004 __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
1005 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_)
1006 {
1007 __storage_type __b = *__first1.__seg_;
1008 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
1009 return false;
1010 ++__first2.__seg_;
1011 if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
1012 return false;
1013 }
1014 // do last word
1015 if (__n > 0)
1016 {
1017 __m = ~__storage_type(0) >> (__bits_per_word - __n);
1018 __storage_type __b = *__first1.__seg_ & __m;
Howard Hinnantce48a112011-06-30 21:18:19 +00001019 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
Howard Hinnant3e519522010-05-11 19:42:16 +00001020 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
1021 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
1022 return false;
1023 __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
1024 __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word);
1025 __n -= __dn;
1026 if (__n > 0)
1027 {
1028 __m = ~__storage_type(0) >> (__bits_per_word - __n);
1029 if ((*__first2.__seg_ & __m) != (__b >> __dn))
1030 return false;
1031 }
1032 }
1033 }
1034 return true;
1035}
1036
Howard Hinnant1237dcc2012-08-05 21:43:11 +00001037template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnant3e519522010-05-11 19:42:16 +00001038bool
Howard Hinnant1237dcc2012-08-05 21:43:11 +00001039__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
1040 __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnant3e519522010-05-11 19:42:16 +00001041{
Howard Hinnant1237dcc2012-08-05 21:43:11 +00001042 typedef __bit_iterator<_Cp, _IC1> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +00001043 typedef typename _It::difference_type difference_type;
1044 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +00001045 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +00001046 difference_type __n = __last1 - __first1;
1047 if (__n > 0)
1048 {
1049 // do first word
1050 if (__first1.__ctz_ != 0)
1051 {
1052 unsigned __clz = __bits_per_word - __first1.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001053 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +00001054 __n -= __dn;
1055 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
1056 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
1057 return false;
1058 ++__first2.__seg_;
1059 ++__first1.__seg_;
1060 // __first1.__ctz_ = 0;
1061 // __first2.__ctz_ = 0;
1062 }
1063 // __first1.__ctz_ == 0;
1064 // __first2.__ctz_ == 0;
1065 // do middle words
1066 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
1067 if (*__first2.__seg_ != *__first1.__seg_)
1068 return false;
1069 // do last word
1070 if (__n > 0)
1071 {
1072 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
1073 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
1074 return false;
1075 }
1076 }
1077 return true;
1078}
1079
Howard Hinnantc003db12011-11-29 18:15:50 +00001080template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnant43d99232010-09-21 17:32:39 +00001081inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001082bool
Howard Hinnantc003db12011-11-29 18:15:50 +00001083equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnant3e519522010-05-11 19:42:16 +00001084{
1085 if (__first1.__ctz_ == __first2.__ctz_)
1086 return __equal_aligned(__first1, __last1, __first2);
1087 return __equal_unaligned(__first1, __last1, __first2);
1088}
1089
Howard Hinnant0ae9efe2012-05-07 16:50:38 +00001090template <class _Cp, bool _IsConst,
1091 typename _Cp::__storage_type>
Howard Hinnant3e519522010-05-11 19:42:16 +00001092class __bit_iterator
1093{
1094public:
Howard Hinnantc003db12011-11-29 18:15:50 +00001095 typedef typename _Cp::difference_type difference_type;
Howard Hinnant3e519522010-05-11 19:42:16 +00001096 typedef bool value_type;
1097 typedef __bit_iterator pointer;
Howard Hinnantc003db12011-11-29 18:15:50 +00001098 typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference;
Howard Hinnant3e519522010-05-11 19:42:16 +00001099 typedef random_access_iterator_tag iterator_category;
1100
1101private:
Howard Hinnantc003db12011-11-29 18:15:50 +00001102 typedef typename _Cp::__storage_type __storage_type;
1103 typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer,
1104 typename _Cp::__storage_pointer>::type __storage_pointer;
1105 static const unsigned __bits_per_word = _Cp::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +00001106
1107 __storage_pointer __seg_;
1108 unsigned __ctz_;
1109
1110public:
Marshall Clow36b2a3b2013-08-07 20:53:44 +00001111 _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
1112#if _LIBCPP_STD_VER > 11
1113 : __seg_(nullptr), __ctz_(0)
1114#endif
1115 {}
Howard Hinnant3e519522010-05-11 19:42:16 +00001116
Eric Fiselierf97936f2019-12-12 20:48:11 -05001117 // avoid re-declaring a copy constructor for the non-const version.
1118 using __type_for_copy_to_const =
1119 _If<_IsConst, __bit_iterator<_Cp, false>, struct __private_nat>;
1120
Howard Hinnantd368a842011-05-27 20:52:28 +00001121 _LIBCPP_INLINE_VISIBILITY
Eric Fiselierf97936f2019-12-12 20:48:11 -05001122 __bit_iterator(const __type_for_copy_to_const& __it) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001123 : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
1124
Howard Hinnantd368a842011-05-27 20:52:28 +00001125 _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
1126 {return reference(__seg_, __storage_type(1) << __ctz_);}
Howard Hinnant3e519522010-05-11 19:42:16 +00001127
1128 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()
1129 {
1130 if (__ctz_ != __bits_per_word-1)
1131 ++__ctz_;
1132 else
1133 {
1134 __ctz_ = 0;
1135 ++__seg_;
1136 }
1137 return *this;
1138 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001139
Howard Hinnant3e519522010-05-11 19:42:16 +00001140 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int)
1141 {
1142 __bit_iterator __tmp = *this;
1143 ++(*this);
1144 return __tmp;
1145 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001146
Howard Hinnant3e519522010-05-11 19:42:16 +00001147 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--()
1148 {
1149 if (__ctz_ != 0)
1150 --__ctz_;
1151 else
1152 {
1153 __ctz_ = __bits_per_word - 1;
1154 --__seg_;
1155 }
1156 return *this;
1157 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001158
Howard Hinnant3e519522010-05-11 19:42:16 +00001159 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int)
1160 {
1161 __bit_iterator __tmp = *this;
1162 --(*this);
1163 return __tmp;
1164 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001165
Howard Hinnant3e519522010-05-11 19:42:16 +00001166 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n)
1167 {
1168 if (__n >= 0)
1169 __seg_ += (__n + __ctz_) / __bits_per_word;
1170 else
1171 __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1)
1172 / static_cast<difference_type>(__bits_per_word);
1173 __n &= (__bits_per_word - 1);
1174 __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word);
1175 return *this;
1176 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001177
Howard Hinnant3e519522010-05-11 19:42:16 +00001178 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n)
1179 {
1180 return *this += -__n;
1181 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001182
Howard Hinnant3e519522010-05-11 19:42:16 +00001183 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const
1184 {
1185 __bit_iterator __t(*this);
1186 __t += __n;
1187 return __t;
1188 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001189
Howard Hinnant3e519522010-05-11 19:42:16 +00001190 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const
1191 {
1192 __bit_iterator __t(*this);
1193 __t -= __n;
1194 return __t;
1195 }
1196
1197 _LIBCPP_INLINE_VISIBILITY
1198 friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}
1199
1200 _LIBCPP_INLINE_VISIBILITY
1201 friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)
1202 {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}
1203
1204 _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);}
1205
1206 _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
1207 {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}
1208
1209 _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
1210 {return !(__x == __y);}
1211
1212 _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
1213 {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}
1214
1215 _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
1216 {return __y < __x;}
1217
1218 _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)
1219 {return !(__y < __x);}
1220
1221 _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)
1222 {return !(__x < __y);}
1223
1224private:
1225 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd368a842011-05-27 20:52:28 +00001226 __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
1227 : __seg_(__s), __ctz_(__ctz) {}
Howard Hinnant3e519522010-05-11 19:42:16 +00001228
Howard Hinnantc003db12011-11-29 18:15:50 +00001229 friend typename _Cp::__self;
Eric Fiselier541f9e22017-01-06 21:42:58 +00001230
Howard Hinnantc003db12011-11-29 18:15:50 +00001231 friend class __bit_reference<_Cp>;
1232 friend class __bit_const_reference<_Cp>;
1233 friend class __bit_iterator<_Cp, true>;
1234 template <class _Dp> friend struct __bit_array;
1235 template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1236 template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1237 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
1238 __bit_iterator<_Dp, _IC> __last,
1239 __bit_iterator<_Dp, false> __result);
1240 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,
1241 __bit_iterator<_Dp, _IC> __last,
1242 __bit_iterator<_Dp, false> __result);
1243 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,
1244 __bit_iterator<_Dp, _IC> __last,
1245 __bit_iterator<_Dp, false> __result);
1246 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first,
1247 __bit_iterator<_Dp, _IC> __last,
1248 __bit_iterator<_Dp, false> __result);
1249 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first,
1250 __bit_iterator<_Dp, _IC> __last,
1251 __bit_iterator<_Dp, false> __result);
1252 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
1253 __bit_iterator<_Dp, _IC> __last,
1254 __bit_iterator<_Dp, false> __result);
Howard Hinnantdbe81112011-09-23 16:11:27 +00001255 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
1256 __bit_iterator<__C1, false>,
1257 __bit_iterator<__C2, false>);
1258 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,
1259 __bit_iterator<__C1, false>,
1260 __bit_iterator<__C2, false>);
1261 template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
1262 __bit_iterator<__C1, false>,
1263 __bit_iterator<__C2, false>);
Howard Hinnantc003db12011-11-29 18:15:50 +00001264 template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
1265 __bit_iterator<_Dp, false>,
1266 __bit_iterator<_Dp, false>);
Howard Hinnant1237dcc2012-08-05 21:43:11 +00001267 template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
1268 __bit_iterator<_Dp, _IC1>,
1269 __bit_iterator<_Dp, _IC2>);
1270 template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
1271 __bit_iterator<_Dp, _IC1>,
1272 __bit_iterator<_Dp, _IC2>);
Howard Hinnantc003db12011-11-29 18:15:50 +00001273 template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>,
1274 __bit_iterator<_Dp, _IC1>,
1275 __bit_iterator<_Dp, _IC2>);
Howard Hinnant423a8d72012-05-10 14:55:00 +00001276 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>,
Howard Hinnantc003db12011-11-29 18:15:50 +00001277 typename _Dp::size_type);
Howard Hinnant423a8d72012-05-10 14:55:00 +00001278 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>,
Howard Hinnantc003db12011-11-29 18:15:50 +00001279 typename _Dp::size_type);
Howard Hinnant423a8d72012-05-10 14:55:00 +00001280 template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1281 __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1282 template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1283 __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
Howard Hinnant3e519522010-05-11 19:42:16 +00001284};
1285
1286_LIBCPP_END_NAMESPACE_STD
1287
Eric Fiseliera016efb2017-05-31 22:07:49 +00001288_LIBCPP_POP_MACROS
1289
Howard Hinnant3e519522010-05-11 19:42:16 +00001290#endif // _LIBCPP___BIT_REFERENCE