blob: c208af2b4d76064c94a6f1399a7baf9ad4a07e06 [file] [log] [blame]
Howard Hinnant3e519522010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnant5b08a8a2010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnant3e519522010-05-11 19:42:16 +00005//
Howard Hinnant412dbeb2010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnant3e519522010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP___BIT_REFERENCE
12#define _LIBCPP___BIT_REFERENCE
13
14#include <__config>
Marshall Clowecb7f4d2018-08-17 17:27:25 +000015#include <bit>
Howard Hinnant3e519522010-05-11 19:42:16 +000016#include <algorithm>
17
Howard Hinnant073458b2011-10-17 20:05:10 +000018#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant3e519522010-05-11 19:42:16 +000019#pragma GCC system_header
Howard Hinnant073458b2011-10-17 20:05:10 +000020#endif
Howard Hinnant3e519522010-05-11 19:42:16 +000021
Eric Fiseliera016efb2017-05-31 22:07:49 +000022_LIBCPP_PUSH_MACROS
23#include <__undef_macros>
24
25
Howard Hinnant3e519522010-05-11 19:42:16 +000026_LIBCPP_BEGIN_NAMESPACE_STD
27
Howard Hinnant0ae9efe2012-05-07 16:50:38 +000028template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;
Howard Hinnantc003db12011-11-29 18:15:50 +000029template <class _Cp> class __bit_const_reference;
Howard Hinnant3e519522010-05-11 19:42:16 +000030
Howard Hinnanta7744562011-07-02 20:33:23 +000031template <class _Tp>
32struct __has_storage_type
33{
34 static const bool value = false;
35};
36
Howard Hinnantc003db12011-11-29 18:15:50 +000037template <class _Cp, bool = __has_storage_type<_Cp>::value>
Howard Hinnant3e519522010-05-11 19:42:16 +000038class __bit_reference
39{
Howard Hinnantc003db12011-11-29 18:15:50 +000040 typedef typename _Cp::__storage_type __storage_type;
41 typedef typename _Cp::__storage_pointer __storage_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +000042
43 __storage_pointer __seg_;
44 __storage_type __mask_;
45
Howard Hinnantc003db12011-11-29 18:15:50 +000046 friend typename _Cp::__self;
Eric Fiselier541f9e22017-01-06 21:42:58 +000047
Howard Hinnantc003db12011-11-29 18:15:50 +000048 friend class __bit_const_reference<_Cp>;
49 friend class __bit_iterator<_Cp, false>;
Howard Hinnant3e519522010-05-11 19:42:16 +000050public:
Howard Hinnantd368a842011-05-27 20:52:28 +000051 _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
52 {return static_cast<bool>(*__seg_ & __mask_);}
53 _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT
54 {return !static_cast<bool>(*this);}
Howard Hinnant3e519522010-05-11 19:42:16 +000055
56 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd368a842011-05-27 20:52:28 +000057 __bit_reference& operator=(bool __x) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +000058 {
59 if (__x)
60 *__seg_ |= __mask_;
61 else
62 *__seg_ &= ~__mask_;
63 return *this;
64 }
Howard Hinnantb3371f62010-08-22 00:02:43 +000065
Howard Hinnant3e519522010-05-11 19:42:16 +000066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd368a842011-05-27 20:52:28 +000067 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
68 {return operator=(static_cast<bool>(__x));}
Howard Hinnant3e519522010-05-11 19:42:16 +000069
Howard Hinnantd368a842011-05-27 20:52:28 +000070 _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
Howard Hinnantc003db12011-11-29 18:15:50 +000071 _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
72 {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
Howard Hinnant3e519522010-05-11 19:42:16 +000073private:
74 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd368a842011-05-27 20:52:28 +000075 __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
76 : __seg_(__s), __mask_(__m) {}
Howard Hinnant3e519522010-05-11 19:42:16 +000077};
78
Howard Hinnantc003db12011-11-29 18:15:50 +000079template <class _Cp>
80class __bit_reference<_Cp, false>
Howard Hinnanta7744562011-07-02 20:33:23 +000081{
82};
83
Howard Hinnantd9db9f92013-03-26 13:48:57 +000084template <class _Cp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +000085inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd9db9f92013-03-26 13:48:57 +000086void
87swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
88{
89 bool __t = __x;
90 __x = __y;
91 __y = __t;
92}
93
Howard Hinnantc003db12011-11-29 18:15:50 +000094template <class _Cp, class _Dp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +000095inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +000096void
Howard Hinnantc003db12011-11-29 18:15:50 +000097swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +000098{
99 bool __t = __x;
100 __x = __y;
101 __y = __t;
102}
103
Howard Hinnantc003db12011-11-29 18:15:50 +0000104template <class _Cp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +0000105inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000106void
Howard Hinnantc003db12011-11-29 18:15:50 +0000107swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000108{
109 bool __t = __x;
110 __x = __y;
111 __y = __t;
112}
113
Howard Hinnantc003db12011-11-29 18:15:50 +0000114template <class _Cp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +0000115inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000116void
Howard Hinnantc003db12011-11-29 18:15:50 +0000117swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000118{
119 bool __t = __x;
120 __x = __y;
121 __y = __t;
122}
123
Howard Hinnantc003db12011-11-29 18:15:50 +0000124template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000125class __bit_const_reference
126{
Howard Hinnantc003db12011-11-29 18:15:50 +0000127 typedef typename _Cp::__storage_type __storage_type;
128 typedef typename _Cp::__const_storage_pointer __storage_pointer;
Howard Hinnant3e519522010-05-11 19:42:16 +0000129
130 __storage_pointer __seg_;
131 __storage_type __mask_;
132
Howard Hinnantc003db12011-11-29 18:15:50 +0000133 friend typename _Cp::__self;
Howard Hinnantc003db12011-11-29 18:15:50 +0000134 friend class __bit_iterator<_Cp, true>;
Howard Hinnant3e519522010-05-11 19:42:16 +0000135public:
136 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000137 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +0000138 : __seg_(__x.__seg_), __mask_(__x.__mask_) {}
139
Howard Hinnanteeac9fc2012-07-07 17:04:52 +0000140 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT
Howard Hinnantd368a842011-05-27 20:52:28 +0000141 {return static_cast<bool>(*__seg_ & __mask_);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000142
Howard Hinnantc003db12011-11-29 18:15:50 +0000143 _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
144 {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
Howard Hinnant3e519522010-05-11 19:42:16 +0000145private:
146 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteeac9fc2012-07-07 17:04:52 +0000147 _LIBCPP_CONSTEXPR
Howard Hinnantd368a842011-05-27 20:52:28 +0000148 __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
149 : __seg_(__s), __mask_(__m) {}
Howard Hinnant3e519522010-05-11 19:42:16 +0000150
151 __bit_const_reference& operator=(const __bit_const_reference& __x);
152};
153
154// find
155
Howard Hinnant423a8d72012-05-10 14:55:00 +0000156template <class _Cp, bool _IsConst>
157__bit_iterator<_Cp, _IsConst>
158__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000159{
Howard Hinnant423a8d72012-05-10 14:55:00 +0000160 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000161 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000162 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000163 // do first partial word
164 if (__first.__ctz_ != 0)
165 {
166 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000167 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000168 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
169 __storage_type __b = *__first.__seg_ & __m;
170 if (__b)
Howard Hinnantce48a112011-06-30 21:18:19 +0000171 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant303e27d2013-08-07 20:42:16 +0000172 if (__n == __dn)
Marshall Clow0fc6e982014-05-06 15:33:23 +0000173 return __first + __n;
Howard Hinnant3e519522010-05-11 19:42:16 +0000174 __n -= __dn;
175 ++__first.__seg_;
176 }
177 // do middle whole words
178 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
179 if (*__first.__seg_)
Howard Hinnantce48a112011-06-30 21:18:19 +0000180 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(*__first.__seg_)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000181 // do last partial word
182 if (__n > 0)
183 {
184 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
185 __storage_type __b = *__first.__seg_ & __m;
186 if (__b)
Howard Hinnantce48a112011-06-30 21:18:19 +0000187 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000188 }
189 return _It(__first.__seg_, static_cast<unsigned>(__n));
190}
191
Howard Hinnant423a8d72012-05-10 14:55:00 +0000192template <class _Cp, bool _IsConst>
193__bit_iterator<_Cp, _IsConst>
194__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000195{
Howard Hinnant423a8d72012-05-10 14:55:00 +0000196 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000197 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000198 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000199 // do first partial word
200 if (__first.__ctz_ != 0)
201 {
202 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000203 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000204 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Howard Hinnant423a8d72012-05-10 14:55:00 +0000205 __storage_type __b = ~*__first.__seg_ & __m;
Howard Hinnant3e519522010-05-11 19:42:16 +0000206 if (__b)
Howard Hinnantce48a112011-06-30 21:18:19 +0000207 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant303e27d2013-08-07 20:42:16 +0000208 if (__n == __dn)
Marshall Clow0fc6e982014-05-06 15:33:23 +0000209 return __first + __n;
Howard Hinnant3e519522010-05-11 19:42:16 +0000210 __n -= __dn;
211 ++__first.__seg_;
212 }
213 // do middle whole words
214 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
215 {
216 __storage_type __b = ~*__first.__seg_;
217 if (__b)
Howard Hinnantce48a112011-06-30 21:18:19 +0000218 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000219 }
220 // do last partial word
221 if (__n > 0)
222 {
223 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Howard Hinnant423a8d72012-05-10 14:55:00 +0000224 __storage_type __b = ~*__first.__seg_ & __m;
Howard Hinnant3e519522010-05-11 19:42:16 +0000225 if (__b)
Howard Hinnantce48a112011-06-30 21:18:19 +0000226 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant3e519522010-05-11 19:42:16 +0000227 }
228 return _It(__first.__seg_, static_cast<unsigned>(__n));
229}
230
Howard Hinnant423a8d72012-05-10 14:55:00 +0000231template <class _Cp, bool _IsConst, class _Tp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000232inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant423a8d72012-05-10 14:55:00 +0000233__bit_iterator<_Cp, _IsConst>
234find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000235{
Howard Hinnante4383372011-10-22 20:59:45 +0000236 if (static_cast<bool>(__value_))
Howard Hinnantc003db12011-11-29 18:15:50 +0000237 return __find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
238 return __find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
Howard Hinnant3e519522010-05-11 19:42:16 +0000239}
240
241// count
242
Howard Hinnant423a8d72012-05-10 14:55:00 +0000243template <class _Cp, bool _IsConst>
244typename __bit_iterator<_Cp, _IsConst>::difference_type
245__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000246{
Howard Hinnant423a8d72012-05-10 14:55:00 +0000247 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000248 typedef typename _It::__storage_type __storage_type;
249 typedef typename _It::difference_type difference_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000250 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000251 difference_type __r = 0;
252 // do first partial word
253 if (__first.__ctz_ != 0)
254 {
255 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000256 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000257 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Marshall Clowecb7f4d2018-08-17 17:27:25 +0000258 __r = _VSTD::__popcount(*__first.__seg_ & __m);
Howard Hinnant3e519522010-05-11 19:42:16 +0000259 __n -= __dn;
260 ++__first.__seg_;
261 }
262 // do middle whole words
263 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
Marshall Clowecb7f4d2018-08-17 17:27:25 +0000264 __r += _VSTD::__popcount(*__first.__seg_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000265 // do last partial word
266 if (__n > 0)
267 {
268 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Marshall Clowecb7f4d2018-08-17 17:27:25 +0000269 __r += _VSTD::__popcount(*__first.__seg_ & __m);
Howard Hinnant3e519522010-05-11 19:42:16 +0000270 }
271 return __r;
272}
273
Howard Hinnant423a8d72012-05-10 14:55:00 +0000274template <class _Cp, bool _IsConst>
275typename __bit_iterator<_Cp, _IsConst>::difference_type
276__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000277{
Howard Hinnant423a8d72012-05-10 14:55:00 +0000278 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000279 typedef typename _It::__storage_type __storage_type;
280 typedef typename _It::difference_type difference_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000281 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000282 difference_type __r = 0;
283 // do first partial word
284 if (__first.__ctz_ != 0)
285 {
286 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000287 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000288 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Marshall Clowecb7f4d2018-08-17 17:27:25 +0000289 __r = _VSTD::__popcount(~*__first.__seg_ & __m);
Howard Hinnant3e519522010-05-11 19:42:16 +0000290 __n -= __dn;
291 ++__first.__seg_;
292 }
293 // do middle whole words
294 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
Marshall Clowecb7f4d2018-08-17 17:27:25 +0000295 __r += _VSTD::__popcount(~*__first.__seg_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000296 // do last partial word
297 if (__n > 0)
298 {
299 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Marshall Clowecb7f4d2018-08-17 17:27:25 +0000300 __r += _VSTD::__popcount(~*__first.__seg_ & __m);
Howard Hinnant3e519522010-05-11 19:42:16 +0000301 }
302 return __r;
303}
304
Howard Hinnant423a8d72012-05-10 14:55:00 +0000305template <class _Cp, bool _IsConst, class _Tp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000306inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant423a8d72012-05-10 14:55:00 +0000307typename __bit_iterator<_Cp, _IsConst>::difference_type
308count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000309{
Howard Hinnante4383372011-10-22 20:59:45 +0000310 if (static_cast<bool>(__value_))
Howard Hinnantc003db12011-11-29 18:15:50 +0000311 return __count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
312 return __count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
Howard Hinnant3e519522010-05-11 19:42:16 +0000313}
314
315// fill_n
316
Howard Hinnantc003db12011-11-29 18:15:50 +0000317template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000318void
Howard Hinnantc003db12011-11-29 18:15:50 +0000319__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000320{
Howard Hinnantc003db12011-11-29 18:15:50 +0000321 typedef __bit_iterator<_Cp, false> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000322 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000323 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000324 // do first partial word
325 if (__first.__ctz_ != 0)
326 {
327 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000328 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000329 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
330 *__first.__seg_ &= ~__m;
331 __n -= __dn;
332 ++__first.__seg_;
333 }
334 // do middle whole words
335 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000336 _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));
Howard Hinnant3e519522010-05-11 19:42:16 +0000337 __n -= __nw * __bits_per_word;
338 // do last partial word
339 if (__n > 0)
340 {
341 __first.__seg_ += __nw;
342 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
343 *__first.__seg_ &= ~__m;
344 }
345}
346
Howard Hinnantc003db12011-11-29 18:15:50 +0000347template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000348void
Howard Hinnantc003db12011-11-29 18:15:50 +0000349__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
Howard Hinnant3e519522010-05-11 19:42:16 +0000350{
Howard Hinnantc003db12011-11-29 18:15:50 +0000351 typedef __bit_iterator<_Cp, false> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000352 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000353 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000354 // do first partial word
355 if (__first.__ctz_ != 0)
356 {
357 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnantce48a112011-06-30 21:18:19 +0000358 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000359 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
360 *__first.__seg_ |= __m;
361 __n -= __dn;
362 ++__first.__seg_;
363 }
364 // do middle whole words
365 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000366 _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));
Howard Hinnant3e519522010-05-11 19:42:16 +0000367 __n -= __nw * __bits_per_word;
368 // do last partial word
369 if (__n > 0)
370 {
371 __first.__seg_ += __nw;
372 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
373 *__first.__seg_ |= __m;
374 }
375}
376
Howard Hinnantc003db12011-11-29 18:15:50 +0000377template <class _Cp>
Howard Hinnant3af48ef2013-10-04 22:09:00 +0000378inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +0000379void
Howard Hinnantc003db12011-11-29 18:15:50 +0000380fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000381{
382 if (__n > 0)
383 {
Howard Hinnante4383372011-10-22 20:59:45 +0000384 if (__value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000385 __fill_n_true(__first, __n);
386 else
387 __fill_n_false(__first, __n);
388 }
389}
390
391// fill
392
Howard Hinnantc003db12011-11-29 18:15:50 +0000393template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000394inline _LIBCPP_INLINE_VISIBILITY
395void
Howard Hinnantc003db12011-11-29 18:15:50 +0000396fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_)
Howard Hinnant3e519522010-05-11 19:42:16 +0000397{
Howard Hinnantc003db12011-11-29 18:15:50 +0000398 _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_);
Howard Hinnant3e519522010-05-11 19:42:16 +0000399}
400
401// copy
402
Howard Hinnantc003db12011-11-29 18:15:50 +0000403template <class _Cp, bool _IsConst>
404__bit_iterator<_Cp, false>
405__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
406 __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000407{
Howard Hinnantc003db12011-11-29 18:15:50 +0000408 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnant3e519522010-05-11 19:42:16 +0000409 typedef typename _In::difference_type difference_type;
410 typedef typename _In::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000411 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000412 difference_type __n = __last - __first;
413 if (__n > 0)
414 {
415 // do first word
416 if (__first.__ctz_ != 0)
417 {
418 unsigned __clz = __bits_per_word - __first.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000419 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000420 __n -= __dn;
421 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
422 __storage_type __b = *__first.__seg_ & __m;
423 *__result.__seg_ &= ~__m;
424 *__result.__seg_ |= __b;
425 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
426 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
427 ++__first.__seg_;
428 // __first.__ctz_ = 0;
429 }
430 // __first.__ctz_ == 0;
431 // do middle words
432 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000433 _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
434 _VSTD::__to_raw_pointer(__first.__seg_),
435 __nw * sizeof(__storage_type));
Howard Hinnant3e519522010-05-11 19:42:16 +0000436 __n -= __nw * __bits_per_word;
437 __result.__seg_ += __nw;
438 // do last word
439 if (__n > 0)
440 {
441 __first.__seg_ += __nw;
442 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
443 __storage_type __b = *__first.__seg_ & __m;
444 *__result.__seg_ &= ~__m;
445 *__result.__seg_ |= __b;
446 __result.__ctz_ = static_cast<unsigned>(__n);
447 }
448 }
449 return __result;
450}
451
Howard Hinnantc003db12011-11-29 18:15:50 +0000452template <class _Cp, bool _IsConst>
453__bit_iterator<_Cp, false>
454__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
455 __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000456{
Howard Hinnantc003db12011-11-29 18:15:50 +0000457 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnant3e519522010-05-11 19:42:16 +0000458 typedef typename _In::difference_type difference_type;
459 typedef typename _In::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000460 static const int __bits_per_word = _In::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000461 difference_type __n = __last - __first;
462 if (__n > 0)
463 {
464 // do first word
465 if (__first.__ctz_ != 0)
466 {
467 unsigned __clz_f = __bits_per_word - __first.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000468 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000469 __n -= __dn;
470 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
471 __storage_type __b = *__first.__seg_ & __m;
472 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000473 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnant3e519522010-05-11 19:42:16 +0000474 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
475 *__result.__seg_ &= ~__m;
476 if (__result.__ctz_ > __first.__ctz_)
477 *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
478 else
479 *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
480 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
481 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
482 __dn -= __ddn;
483 if (__dn > 0)
484 {
485 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
486 *__result.__seg_ &= ~__m;
487 *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
488 __result.__ctz_ = static_cast<unsigned>(__dn);
489 }
490 ++__first.__seg_;
491 // __first.__ctz_ = 0;
492 }
493 // __first.__ctz_ == 0;
494 // do middle words
495 unsigned __clz_r = __bits_per_word - __result.__ctz_;
496 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
497 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
498 {
499 __storage_type __b = *__first.__seg_;
500 *__result.__seg_ &= ~__m;
501 *__result.__seg_ |= __b << __result.__ctz_;
502 ++__result.__seg_;
503 *__result.__seg_ &= __m;
504 *__result.__seg_ |= __b >> __clz_r;
505 }
506 // do last word
507 if (__n > 0)
508 {
509 __m = ~__storage_type(0) >> (__bits_per_word - __n);
510 __storage_type __b = *__first.__seg_ & __m;
Howard Hinnantce48a112011-06-30 21:18:19 +0000511 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
Howard Hinnant3e519522010-05-11 19:42:16 +0000512 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
513 *__result.__seg_ &= ~__m;
514 *__result.__seg_ |= __b << __result.__ctz_;
515 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
516 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
517 __n -= __dn;
518 if (__n > 0)
519 {
520 __m = ~__storage_type(0) >> (__bits_per_word - __n);
521 *__result.__seg_ &= ~__m;
522 *__result.__seg_ |= __b >> __dn;
523 __result.__ctz_ = static_cast<unsigned>(__n);
524 }
525 }
526 }
527 return __result;
528}
529
Howard Hinnantc003db12011-11-29 18:15:50 +0000530template <class _Cp, bool _IsConst>
Howard Hinnant3e519522010-05-11 19:42:16 +0000531inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000532__bit_iterator<_Cp, false>
533copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000534{
535 if (__first.__ctz_ == __result.__ctz_)
536 return __copy_aligned(__first, __last, __result);
537 return __copy_unaligned(__first, __last, __result);
538}
539
540// copy_backward
541
Howard Hinnantc003db12011-11-29 18:15:50 +0000542template <class _Cp, bool _IsConst>
543__bit_iterator<_Cp, false>
544__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
545 __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000546{
Howard Hinnantc003db12011-11-29 18:15:50 +0000547 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnant3e519522010-05-11 19:42:16 +0000548 typedef typename _In::difference_type difference_type;
549 typedef typename _In::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000550 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000551 difference_type __n = __last - __first;
552 if (__n > 0)
553 {
554 // do first word
555 if (__last.__ctz_ != 0)
556 {
Howard Hinnantce48a112011-06-30 21:18:19 +0000557 difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000558 __n -= __dn;
559 unsigned __clz = __bits_per_word - __last.__ctz_;
560 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
561 __storage_type __b = *__last.__seg_ & __m;
562 *__result.__seg_ &= ~__m;
563 *__result.__seg_ |= __b;
564 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
565 __result.__ctz_) % __bits_per_word);
566 // __last.__ctz_ = 0
567 }
568 // __last.__ctz_ == 0 || __n == 0
569 // __result.__ctz_ == 0 || __n == 0
570 // do middle words
571 __storage_type __nw = __n / __bits_per_word;
572 __result.__seg_ -= __nw;
573 __last.__seg_ -= __nw;
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000574 _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
575 _VSTD::__to_raw_pointer(__last.__seg_),
576 __nw * sizeof(__storage_type));
Howard Hinnant3e519522010-05-11 19:42:16 +0000577 __n -= __nw * __bits_per_word;
578 // do last word
579 if (__n > 0)
580 {
581 __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
582 __storage_type __b = *--__last.__seg_ & __m;
583 *--__result.__seg_ &= ~__m;
584 *__result.__seg_ |= __b;
585 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
586 }
587 }
588 return __result;
589}
590
Howard Hinnantc003db12011-11-29 18:15:50 +0000591template <class _Cp, bool _IsConst>
592__bit_iterator<_Cp, false>
593__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
594 __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000595{
Howard Hinnantc003db12011-11-29 18:15:50 +0000596 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnant3e519522010-05-11 19:42:16 +0000597 typedef typename _In::difference_type difference_type;
598 typedef typename _In::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000599 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000600 difference_type __n = __last - __first;
601 if (__n > 0)
602 {
603 // do first word
604 if (__last.__ctz_ != 0)
605 {
Howard Hinnantce48a112011-06-30 21:18:19 +0000606 difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000607 __n -= __dn;
608 unsigned __clz_l = __bits_per_word - __last.__ctz_;
609 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
610 __storage_type __b = *__last.__seg_ & __m;
611 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000612 __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000613 if (__ddn > 0)
614 {
615 __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
616 *__result.__seg_ &= ~__m;
617 if (__result.__ctz_ > __last.__ctz_)
618 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
619 else
620 *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
621 __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) +
622 __result.__ctz_) % __bits_per_word);
623 __dn -= __ddn;
624 }
625 if (__dn > 0)
626 {
627 // __result.__ctz_ == 0
628 --__result.__seg_;
629 __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
630 __m = ~__storage_type(0) << __result.__ctz_;
631 *__result.__seg_ &= ~__m;
632 __last.__ctz_ -= __dn + __ddn;
633 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
634 }
635 // __last.__ctz_ = 0
636 }
637 // __last.__ctz_ == 0 || __n == 0
638 // __result.__ctz_ != 0 || __n == 0
639 // do middle words
640 unsigned __clz_r = __bits_per_word - __result.__ctz_;
641 __storage_type __m = ~__storage_type(0) >> __clz_r;
642 for (; __n >= __bits_per_word; __n -= __bits_per_word)
643 {
644 __storage_type __b = *--__last.__seg_;
645 *__result.__seg_ &= ~__m;
646 *__result.__seg_ |= __b >> __clz_r;
647 *--__result.__seg_ &= __m;
648 *__result.__seg_ |= __b << __result.__ctz_;
649 }
650 // do last word
651 if (__n > 0)
652 {
653 __m = ~__storage_type(0) << (__bits_per_word - __n);
654 __storage_type __b = *--__last.__seg_ & __m;
Howard Hinnantc2063662011-12-01 20:21:04 +0000655 __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000656 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_));
Howard Hinnant3e519522010-05-11 19:42:16 +0000657 __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
658 *__result.__seg_ &= ~__m;
659 *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
660 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
661 __result.__ctz_) % __bits_per_word);
662 __n -= __dn;
663 if (__n > 0)
664 {
665 // __result.__ctz_ == 0
666 --__result.__seg_;
667 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
668 __m = ~__storage_type(0) << __result.__ctz_;
669 *__result.__seg_ &= ~__m;
670 *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
671 }
672 }
673 }
674 return __result;
675}
676
Howard Hinnantc003db12011-11-29 18:15:50 +0000677template <class _Cp, bool _IsConst>
Howard Hinnant3e519522010-05-11 19:42:16 +0000678inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000679__bit_iterator<_Cp, false>
680copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000681{
682 if (__last.__ctz_ == __result.__ctz_)
683 return __copy_backward_aligned(__first, __last, __result);
684 return __copy_backward_unaligned(__first, __last, __result);
685}
686
687// move
688
Howard Hinnantc003db12011-11-29 18:15:50 +0000689template <class _Cp, bool _IsConst>
Howard Hinnant3e519522010-05-11 19:42:16 +0000690inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000691__bit_iterator<_Cp, false>
692move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000693{
Howard Hinnantce48a112011-06-30 21:18:19 +0000694 return _VSTD::copy(__first, __last, __result);
Howard Hinnant3e519522010-05-11 19:42:16 +0000695}
696
697// move_backward
698
Howard Hinnantc003db12011-11-29 18:15:50 +0000699template <class _Cp, bool _IsConst>
Howard Hinnant3e519522010-05-11 19:42:16 +0000700inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +0000701__bit_iterator<_Cp, false>
702move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000703{
Marshall Clow08de4b02014-12-22 19:10:11 +0000704 return _VSTD::copy_backward(__first, __last, __result);
Howard Hinnant3e519522010-05-11 19:42:16 +0000705}
706
707// swap_ranges
708
Howard Hinnantdbe81112011-09-23 16:11:27 +0000709template <class __C1, class __C2>
710__bit_iterator<__C2, false>
711__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
712 __bit_iterator<__C2, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000713{
Howard Hinnantdbe81112011-09-23 16:11:27 +0000714 typedef __bit_iterator<__C1, false> _I1;
Howard Hinnant3e519522010-05-11 19:42:16 +0000715 typedef typename _I1::difference_type difference_type;
716 typedef typename _I1::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000717 const int __bits_per_word = _I1::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000718 difference_type __n = __last - __first;
719 if (__n > 0)
720 {
721 // do first word
722 if (__first.__ctz_ != 0)
723 {
724 unsigned __clz = __bits_per_word - __first.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000725 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000726 __n -= __dn;
727 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
728 __storage_type __b1 = *__first.__seg_ & __m;
729 *__first.__seg_ &= ~__m;
730 __storage_type __b2 = *__result.__seg_ & __m;
731 *__result.__seg_ &= ~__m;
732 *__result.__seg_ |= __b1;
733 *__first.__seg_ |= __b2;
734 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
735 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
736 ++__first.__seg_;
737 // __first.__ctz_ = 0;
738 }
739 // __first.__ctz_ == 0;
740 // do middle words
741 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
742 swap(*__first.__seg_, *__result.__seg_);
743 // do last word
744 if (__n > 0)
745 {
746 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
747 __storage_type __b1 = *__first.__seg_ & __m;
748 *__first.__seg_ &= ~__m;
749 __storage_type __b2 = *__result.__seg_ & __m;
750 *__result.__seg_ &= ~__m;
751 *__result.__seg_ |= __b1;
752 *__first.__seg_ |= __b2;
753 __result.__ctz_ = static_cast<unsigned>(__n);
754 }
755 }
756 return __result;
757}
758
Howard Hinnantdbe81112011-09-23 16:11:27 +0000759template <class __C1, class __C2>
760__bit_iterator<__C2, false>
761__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
762 __bit_iterator<__C2, false> __result)
Howard Hinnant3e519522010-05-11 19:42:16 +0000763{
Howard Hinnantdbe81112011-09-23 16:11:27 +0000764 typedef __bit_iterator<__C1, false> _I1;
Howard Hinnant3e519522010-05-11 19:42:16 +0000765 typedef typename _I1::difference_type difference_type;
766 typedef typename _I1::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000767 const int __bits_per_word = _I1::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000768 difference_type __n = __last - __first;
769 if (__n > 0)
770 {
771 // do first word
772 if (__first.__ctz_ != 0)
773 {
774 unsigned __clz_f = __bits_per_word - __first.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000775 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000776 __n -= __dn;
777 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
778 __storage_type __b1 = *__first.__seg_ & __m;
779 *__first.__seg_ &= ~__m;
780 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000781 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnant3e519522010-05-11 19:42:16 +0000782 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
783 __storage_type __b2 = *__result.__seg_ & __m;
784 *__result.__seg_ &= ~__m;
785 if (__result.__ctz_ > __first.__ctz_)
786 {
787 unsigned __s = __result.__ctz_ - __first.__ctz_;
788 *__result.__seg_ |= __b1 << __s;
789 *__first.__seg_ |= __b2 >> __s;
790 }
791 else
792 {
793 unsigned __s = __first.__ctz_ - __result.__ctz_;
794 *__result.__seg_ |= __b1 >> __s;
795 *__first.__seg_ |= __b2 << __s;
796 }
797 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
798 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
799 __dn -= __ddn;
800 if (__dn > 0)
801 {
802 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
803 __b2 = *__result.__seg_ & __m;
804 *__result.__seg_ &= ~__m;
805 unsigned __s = __first.__ctz_ + __ddn;
806 *__result.__seg_ |= __b1 >> __s;
807 *__first.__seg_ |= __b2 << __s;
808 __result.__ctz_ = static_cast<unsigned>(__dn);
809 }
810 ++__first.__seg_;
811 // __first.__ctz_ = 0;
812 }
813 // __first.__ctz_ == 0;
814 // do middle words
815 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
816 unsigned __clz_r = __bits_per_word - __result.__ctz_;
817 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
818 {
819 __storage_type __b1 = *__first.__seg_;
820 __storage_type __b2 = *__result.__seg_ & __m;
821 *__result.__seg_ &= ~__m;
822 *__result.__seg_ |= __b1 << __result.__ctz_;
823 *__first.__seg_ = __b2 >> __result.__ctz_;
824 ++__result.__seg_;
825 __b2 = *__result.__seg_ & ~__m;
826 *__result.__seg_ &= __m;
827 *__result.__seg_ |= __b1 >> __clz_r;
828 *__first.__seg_ |= __b2 << __clz_r;
829 }
830 // do last word
831 if (__n > 0)
832 {
833 __m = ~__storage_type(0) >> (__bits_per_word - __n);
834 __storage_type __b1 = *__first.__seg_ & __m;
835 *__first.__seg_ &= ~__m;
Howard Hinnantce48a112011-06-30 21:18:19 +0000836 __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r);
Howard Hinnant3e519522010-05-11 19:42:16 +0000837 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
838 __storage_type __b2 = *__result.__seg_ & __m;
839 *__result.__seg_ &= ~__m;
840 *__result.__seg_ |= __b1 << __result.__ctz_;
841 *__first.__seg_ |= __b2 >> __result.__ctz_;
842 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
843 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
844 __n -= __dn;
845 if (__n > 0)
846 {
847 __m = ~__storage_type(0) >> (__bits_per_word - __n);
848 __b2 = *__result.__seg_ & __m;
849 *__result.__seg_ &= ~__m;
850 *__result.__seg_ |= __b1 >> __dn;
851 *__first.__seg_ |= __b2 << __dn;
852 __result.__ctz_ = static_cast<unsigned>(__n);
853 }
854 }
855 }
856 return __result;
857}
858
Howard Hinnantdbe81112011-09-23 16:11:27 +0000859template <class __C1, class __C2>
Howard Hinnant3e519522010-05-11 19:42:16 +0000860inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantdbe81112011-09-23 16:11:27 +0000861__bit_iterator<__C2, false>
862swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
863 __bit_iterator<__C2, false> __first2)
Howard Hinnant3e519522010-05-11 19:42:16 +0000864{
865 if (__first1.__ctz_ == __first2.__ctz_)
866 return __swap_ranges_aligned(__first1, __last1, __first2);
867 return __swap_ranges_unaligned(__first1, __last1, __first2);
868}
869
870// rotate
871
Howard Hinnantc003db12011-11-29 18:15:50 +0000872template <class _Cp>
Howard Hinnant3e519522010-05-11 19:42:16 +0000873struct __bit_array
874{
Howard Hinnantc003db12011-11-29 18:15:50 +0000875 typedef typename _Cp::difference_type difference_type;
876 typedef typename _Cp::__storage_type __storage_type;
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000877 typedef typename _Cp::__storage_pointer __storage_pointer;
Howard Hinnantc003db12011-11-29 18:15:50 +0000878 typedef typename _Cp::iterator iterator;
879 static const unsigned __bits_per_word = _Cp::__bits_per_word;
880 static const unsigned _Np = 4;
Howard Hinnant3e519522010-05-11 19:42:16 +0000881
882 difference_type __size_;
Howard Hinnantc003db12011-11-29 18:15:50 +0000883 __storage_type __word_[_Np];
Howard Hinnant3e519522010-05-11 19:42:16 +0000884
885 _LIBCPP_INLINE_VISIBILITY static difference_type capacity()
Howard Hinnantc003db12011-11-29 18:15:50 +0000886 {return static_cast<difference_type>(_Np * __bits_per_word);}
Howard Hinnant3e519522010-05-11 19:42:16 +0000887 _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000888 _LIBCPP_INLINE_VISIBILITY iterator begin()
889 {
890 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
891 }
892 _LIBCPP_INLINE_VISIBILITY iterator end()
893 {
894 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
895 static_cast<unsigned>(__size_ % __bits_per_word));
896 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000897};
898
Howard Hinnantc003db12011-11-29 18:15:50 +0000899template <class _Cp>
900__bit_iterator<_Cp, false>
901rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)
Howard Hinnant3e519522010-05-11 19:42:16 +0000902{
Howard Hinnantc003db12011-11-29 18:15:50 +0000903 typedef __bit_iterator<_Cp, false> _I1;
Howard Hinnant3e519522010-05-11 19:42:16 +0000904 typedef typename _I1::difference_type difference_type;
Howard Hinnant3e519522010-05-11 19:42:16 +0000905 difference_type __d1 = __middle - __first;
906 difference_type __d2 = __last - __middle;
907 _I1 __r = __first + __d2;
908 while (__d1 != 0 && __d2 != 0)
909 {
910 if (__d1 <= __d2)
911 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000912 if (__d1 <= __bit_array<_Cp>::capacity())
Howard Hinnant3e519522010-05-11 19:42:16 +0000913 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000914 __bit_array<_Cp> __b(__d1);
Howard Hinnantce48a112011-06-30 21:18:19 +0000915 _VSTD::copy(__first, __middle, __b.begin());
916 _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first));
Howard Hinnant3e519522010-05-11 19:42:16 +0000917 break;
918 }
919 else
920 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000921 __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle);
Howard Hinnant3e519522010-05-11 19:42:16 +0000922 __first = __middle;
923 __middle = __mp;
924 __d2 -= __d1;
925 }
926 }
927 else
928 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000929 if (__d2 <= __bit_array<_Cp>::capacity())
Howard Hinnant3e519522010-05-11 19:42:16 +0000930 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000931 __bit_array<_Cp> __b(__d2);
Howard Hinnantce48a112011-06-30 21:18:19 +0000932 _VSTD::copy(__middle, __last, __b.begin());
933 _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last));
Howard Hinnant3e519522010-05-11 19:42:16 +0000934 break;
935 }
936 else
937 {
Howard Hinnantc003db12011-11-29 18:15:50 +0000938 __bit_iterator<_Cp, false> __mp = __first + __d2;
Howard Hinnantce48a112011-06-30 21:18:19 +0000939 _VSTD::swap_ranges(__first, __mp, __middle);
Howard Hinnant3e519522010-05-11 19:42:16 +0000940 __first = __mp;
941 __d1 -= __d2;
942 }
943 }
944 }
945 return __r;
946}
947
948// equal
949
Howard Hinnant1237dcc2012-08-05 21:43:11 +0000950template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnant3e519522010-05-11 19:42:16 +0000951bool
Howard Hinnant1237dcc2012-08-05 21:43:11 +0000952__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
953 __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnant3e519522010-05-11 19:42:16 +0000954{
Howard Hinnant1237dcc2012-08-05 21:43:11 +0000955 typedef __bit_iterator<_Cp, _IC1> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +0000956 typedef typename _It::difference_type difference_type;
957 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +0000958 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +0000959 difference_type __n = __last1 - __first1;
960 if (__n > 0)
961 {
962 // do first word
963 if (__first1.__ctz_ != 0)
964 {
965 unsigned __clz_f = __bits_per_word - __first1.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000966 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +0000967 __n -= __dn;
968 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
969 __storage_type __b = *__first1.__seg_ & __m;
970 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +0000971 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnant3e519522010-05-11 19:42:16 +0000972 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
973 if (__first2.__ctz_ > __first1.__ctz_)
Howard Hinnant4c0de492012-05-31 23:12:03 +0000974 {
Howard Hinnant3e519522010-05-11 19:42:16 +0000975 if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
976 return false;
Howard Hinnant4c0de492012-05-31 23:12:03 +0000977 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000978 else
Howard Hinnant4c0de492012-05-31 23:12:03 +0000979 {
Howard Hinnant3e519522010-05-11 19:42:16 +0000980 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
981 return false;
Howard Hinnant4c0de492012-05-31 23:12:03 +0000982 }
Howard Hinnant3e519522010-05-11 19:42:16 +0000983 __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
984 __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word);
985 __dn -= __ddn;
986 if (__dn > 0)
987 {
988 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
989 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
990 return false;
991 __first2.__ctz_ = static_cast<unsigned>(__dn);
992 }
993 ++__first1.__seg_;
994 // __first1.__ctz_ = 0;
995 }
996 // __first1.__ctz_ == 0;
997 // do middle words
998 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
999 __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
1000 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_)
1001 {
1002 __storage_type __b = *__first1.__seg_;
1003 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
1004 return false;
1005 ++__first2.__seg_;
1006 if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
1007 return false;
1008 }
1009 // do last word
1010 if (__n > 0)
1011 {
1012 __m = ~__storage_type(0) >> (__bits_per_word - __n);
1013 __storage_type __b = *__first1.__seg_ & __m;
Howard Hinnantce48a112011-06-30 21:18:19 +00001014 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
Howard Hinnant3e519522010-05-11 19:42:16 +00001015 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
1016 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
1017 return false;
1018 __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
1019 __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word);
1020 __n -= __dn;
1021 if (__n > 0)
1022 {
1023 __m = ~__storage_type(0) >> (__bits_per_word - __n);
1024 if ((*__first2.__seg_ & __m) != (__b >> __dn))
1025 return false;
1026 }
1027 }
1028 }
1029 return true;
1030}
1031
Howard Hinnant1237dcc2012-08-05 21:43:11 +00001032template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnant3e519522010-05-11 19:42:16 +00001033bool
Howard Hinnant1237dcc2012-08-05 21:43:11 +00001034__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
1035 __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnant3e519522010-05-11 19:42:16 +00001036{
Howard Hinnant1237dcc2012-08-05 21:43:11 +00001037 typedef __bit_iterator<_Cp, _IC1> _It;
Howard Hinnant3e519522010-05-11 19:42:16 +00001038 typedef typename _It::difference_type difference_type;
1039 typedef typename _It::__storage_type __storage_type;
Eric Fiselieraec08782016-12-24 00:24:44 +00001040 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +00001041 difference_type __n = __last1 - __first1;
1042 if (__n > 0)
1043 {
1044 // do first word
1045 if (__first1.__ctz_ != 0)
1046 {
1047 unsigned __clz = __bits_per_word - __first1.__ctz_;
Howard Hinnantce48a112011-06-30 21:18:19 +00001048 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnant3e519522010-05-11 19:42:16 +00001049 __n -= __dn;
1050 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
1051 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
1052 return false;
1053 ++__first2.__seg_;
1054 ++__first1.__seg_;
1055 // __first1.__ctz_ = 0;
1056 // __first2.__ctz_ = 0;
1057 }
1058 // __first1.__ctz_ == 0;
1059 // __first2.__ctz_ == 0;
1060 // do middle words
1061 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
1062 if (*__first2.__seg_ != *__first1.__seg_)
1063 return false;
1064 // do last word
1065 if (__n > 0)
1066 {
1067 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
1068 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
1069 return false;
1070 }
1071 }
1072 return true;
1073}
1074
Howard Hinnantc003db12011-11-29 18:15:50 +00001075template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnant43d99232010-09-21 17:32:39 +00001076inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3e519522010-05-11 19:42:16 +00001077bool
Howard Hinnantc003db12011-11-29 18:15:50 +00001078equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnant3e519522010-05-11 19:42:16 +00001079{
1080 if (__first1.__ctz_ == __first2.__ctz_)
1081 return __equal_aligned(__first1, __last1, __first2);
1082 return __equal_unaligned(__first1, __last1, __first2);
1083}
1084
Howard Hinnant0ae9efe2012-05-07 16:50:38 +00001085template <class _Cp, bool _IsConst,
1086 typename _Cp::__storage_type>
Howard Hinnant3e519522010-05-11 19:42:16 +00001087class __bit_iterator
1088{
1089public:
Howard Hinnantc003db12011-11-29 18:15:50 +00001090 typedef typename _Cp::difference_type difference_type;
Howard Hinnant3e519522010-05-11 19:42:16 +00001091 typedef bool value_type;
1092 typedef __bit_iterator pointer;
Howard Hinnantc003db12011-11-29 18:15:50 +00001093 typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference;
Howard Hinnant3e519522010-05-11 19:42:16 +00001094 typedef random_access_iterator_tag iterator_category;
1095
1096private:
Howard Hinnantc003db12011-11-29 18:15:50 +00001097 typedef typename _Cp::__storage_type __storage_type;
1098 typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer,
1099 typename _Cp::__storage_pointer>::type __storage_pointer;
1100 static const unsigned __bits_per_word = _Cp::__bits_per_word;
Howard Hinnant3e519522010-05-11 19:42:16 +00001101
1102 __storage_pointer __seg_;
1103 unsigned __ctz_;
1104
1105public:
Marshall Clow36b2a3b2013-08-07 20:53:44 +00001106 _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
1107#if _LIBCPP_STD_VER > 11
1108 : __seg_(nullptr), __ctz_(0)
1109#endif
1110 {}
Howard Hinnant3e519522010-05-11 19:42:16 +00001111
Howard Hinnantd368a842011-05-27 20:52:28 +00001112 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantc003db12011-11-29 18:15:50 +00001113 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
Howard Hinnant3e519522010-05-11 19:42:16 +00001114 : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
1115
Howard Hinnantd368a842011-05-27 20:52:28 +00001116 _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
1117 {return reference(__seg_, __storage_type(1) << __ctz_);}
Howard Hinnant3e519522010-05-11 19:42:16 +00001118
1119 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()
1120 {
1121 if (__ctz_ != __bits_per_word-1)
1122 ++__ctz_;
1123 else
1124 {
1125 __ctz_ = 0;
1126 ++__seg_;
1127 }
1128 return *this;
1129 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001130
Howard Hinnant3e519522010-05-11 19:42:16 +00001131 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int)
1132 {
1133 __bit_iterator __tmp = *this;
1134 ++(*this);
1135 return __tmp;
1136 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001137
Howard Hinnant3e519522010-05-11 19:42:16 +00001138 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--()
1139 {
1140 if (__ctz_ != 0)
1141 --__ctz_;
1142 else
1143 {
1144 __ctz_ = __bits_per_word - 1;
1145 --__seg_;
1146 }
1147 return *this;
1148 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001149
Howard Hinnant3e519522010-05-11 19:42:16 +00001150 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int)
1151 {
1152 __bit_iterator __tmp = *this;
1153 --(*this);
1154 return __tmp;
1155 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001156
Howard Hinnant3e519522010-05-11 19:42:16 +00001157 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n)
1158 {
1159 if (__n >= 0)
1160 __seg_ += (__n + __ctz_) / __bits_per_word;
1161 else
1162 __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1)
1163 / static_cast<difference_type>(__bits_per_word);
1164 __n &= (__bits_per_word - 1);
1165 __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word);
1166 return *this;
1167 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001168
Howard Hinnant3e519522010-05-11 19:42:16 +00001169 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n)
1170 {
1171 return *this += -__n;
1172 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001173
Howard Hinnant3e519522010-05-11 19:42:16 +00001174 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const
1175 {
1176 __bit_iterator __t(*this);
1177 __t += __n;
1178 return __t;
1179 }
Howard Hinnantb3371f62010-08-22 00:02:43 +00001180
Howard Hinnant3e519522010-05-11 19:42:16 +00001181 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const
1182 {
1183 __bit_iterator __t(*this);
1184 __t -= __n;
1185 return __t;
1186 }
1187
1188 _LIBCPP_INLINE_VISIBILITY
1189 friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}
1190
1191 _LIBCPP_INLINE_VISIBILITY
1192 friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)
1193 {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}
1194
1195 _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);}
1196
1197 _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
1198 {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}
1199
1200 _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
1201 {return !(__x == __y);}
1202
1203 _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
1204 {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}
1205
1206 _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
1207 {return __y < __x;}
1208
1209 _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)
1210 {return !(__y < __x);}
1211
1212 _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)
1213 {return !(__x < __y);}
1214
1215private:
1216 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd368a842011-05-27 20:52:28 +00001217 __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
1218 : __seg_(__s), __ctz_(__ctz) {}
Howard Hinnant3e519522010-05-11 19:42:16 +00001219
Howard Hinnantc003db12011-11-29 18:15:50 +00001220 friend typename _Cp::__self;
Eric Fiselier541f9e22017-01-06 21:42:58 +00001221
Howard Hinnantc003db12011-11-29 18:15:50 +00001222 friend class __bit_reference<_Cp>;
1223 friend class __bit_const_reference<_Cp>;
1224 friend class __bit_iterator<_Cp, true>;
1225 template <class _Dp> friend struct __bit_array;
1226 template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1227 template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1228 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
1229 __bit_iterator<_Dp, _IC> __last,
1230 __bit_iterator<_Dp, false> __result);
1231 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,
1232 __bit_iterator<_Dp, _IC> __last,
1233 __bit_iterator<_Dp, false> __result);
1234 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,
1235 __bit_iterator<_Dp, _IC> __last,
1236 __bit_iterator<_Dp, false> __result);
1237 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_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_backward_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_backward(__bit_iterator<_Dp, _IC> __first,
1244 __bit_iterator<_Dp, _IC> __last,
1245 __bit_iterator<_Dp, false> __result);
Howard Hinnantdbe81112011-09-23 16:11:27 +00001246 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
1247 __bit_iterator<__C1, false>,
1248 __bit_iterator<__C2, false>);
1249 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,
1250 __bit_iterator<__C1, false>,
1251 __bit_iterator<__C2, false>);
1252 template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
1253 __bit_iterator<__C1, false>,
1254 __bit_iterator<__C2, false>);
Howard Hinnantc003db12011-11-29 18:15:50 +00001255 template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
1256 __bit_iterator<_Dp, false>,
1257 __bit_iterator<_Dp, false>);
Howard Hinnant1237dcc2012-08-05 21:43:11 +00001258 template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
1259 __bit_iterator<_Dp, _IC1>,
1260 __bit_iterator<_Dp, _IC2>);
1261 template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
1262 __bit_iterator<_Dp, _IC1>,
1263 __bit_iterator<_Dp, _IC2>);
Howard Hinnantc003db12011-11-29 18:15:50 +00001264 template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>,
1265 __bit_iterator<_Dp, _IC1>,
1266 __bit_iterator<_Dp, _IC2>);
Howard Hinnant423a8d72012-05-10 14:55:00 +00001267 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>,
Howard Hinnantc003db12011-11-29 18:15:50 +00001268 typename _Dp::size_type);
Howard Hinnant423a8d72012-05-10 14:55:00 +00001269 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>,
Howard Hinnantc003db12011-11-29 18:15:50 +00001270 typename _Dp::size_type);
Howard Hinnant423a8d72012-05-10 14:55:00 +00001271 template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1272 __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1273 template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1274 __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
Howard Hinnant3e519522010-05-11 19:42:16 +00001275};
1276
1277_LIBCPP_END_NAMESPACE_STD
1278
Eric Fiseliera016efb2017-05-31 22:07:49 +00001279_LIBCPP_POP_MACROS
1280
Howard Hinnant3e519522010-05-11 19:42:16 +00001281#endif // _LIBCPP___BIT_REFERENCE