blob: 9aea961452845a7a5d5de2fc563105f594f59df6 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-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 Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP___BIT_REFERENCE
12#define _LIBCPP___BIT_REFERENCE
13
14#include <__config>
15#include <algorithm>
16
Howard Hinnant66c6f972011-11-29 16:45:27 +000017#include <__undef_min_max>
18
Howard Hinnant08e17472011-10-17 20:05:10 +000019#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000020#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +000021#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000022
23_LIBCPP_BEGIN_NAMESPACE_STD
24
Howard Hinnantf867f632012-05-07 16:50:38 +000025template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;
Howard Hinnant99968442011-11-29 18:15:50 +000026template <class _Cp> class __bit_const_reference;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000027
Howard Hinnantf03c3b42011-07-02 20:33:23 +000028template <class _Tp>
29struct __has_storage_type
30{
31 static const bool value = false;
32};
33
Howard Hinnant99968442011-11-29 18:15:50 +000034template <class _Cp, bool = __has_storage_type<_Cp>::value>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000035class __bit_reference
36{
Howard Hinnant99968442011-11-29 18:15:50 +000037 typedef typename _Cp::__storage_type __storage_type;
38 typedef typename _Cp::__storage_pointer __storage_pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000039
40 __storage_pointer __seg_;
41 __storage_type __mask_;
42
Howard Hinnant99968442011-11-29 18:15:50 +000043 friend typename _Cp::__self;
Eric Fiselier5170d7d2017-01-06 21:42:58 +000044
Howard Hinnant99968442011-11-29 18:15:50 +000045 friend class __bit_const_reference<_Cp>;
46 friend class __bit_iterator<_Cp, false>;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000047public:
Howard Hinnant10f25d22011-05-27 20:52:28 +000048 _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
49 {return static_cast<bool>(*__seg_ & __mask_);}
50 _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT
51 {return !static_cast<bool>(*this);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000052
53 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant10f25d22011-05-27 20:52:28 +000054 __bit_reference& operator=(bool __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000055 {
56 if (__x)
57 *__seg_ |= __mask_;
58 else
59 *__seg_ &= ~__mask_;
60 return *this;
61 }
Howard Hinnant324bb032010-08-22 00:02:43 +000062
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000063 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant10f25d22011-05-27 20:52:28 +000064 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
65 {return operator=(static_cast<bool>(__x));}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000066
Howard Hinnant10f25d22011-05-27 20:52:28 +000067 _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
Howard Hinnant99968442011-11-29 18:15:50 +000068 _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
69 {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000070private:
71 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant10f25d22011-05-27 20:52:28 +000072 __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
73 : __seg_(__s), __mask_(__m) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000074};
75
Howard Hinnant99968442011-11-29 18:15:50 +000076template <class _Cp>
77class __bit_reference<_Cp, false>
Howard Hinnantf03c3b42011-07-02 20:33:23 +000078{
79};
80
Howard Hinnantd9cdb2d2013-03-26 13:48:57 +000081template <class _Cp>
Howard Hinnant1e564242013-10-04 22:09:00 +000082inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd9cdb2d2013-03-26 13:48:57 +000083void
84swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
85{
86 bool __t = __x;
87 __x = __y;
88 __y = __t;
89}
90
Howard Hinnant99968442011-11-29 18:15:50 +000091template <class _Cp, class _Dp>
Howard Hinnant1e564242013-10-04 22:09:00 +000092inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000093void
Howard Hinnant99968442011-11-29 18:15:50 +000094swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000095{
96 bool __t = __x;
97 __x = __y;
98 __y = __t;
99}
100
Howard Hinnant99968442011-11-29 18:15:50 +0000101template <class _Cp>
Howard Hinnant1e564242013-10-04 22:09:00 +0000102inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000103void
Howard Hinnant99968442011-11-29 18:15:50 +0000104swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000105{
106 bool __t = __x;
107 __x = __y;
108 __y = __t;
109}
110
Howard Hinnant99968442011-11-29 18:15:50 +0000111template <class _Cp>
Howard Hinnant1e564242013-10-04 22:09:00 +0000112inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000113void
Howard Hinnant99968442011-11-29 18:15:50 +0000114swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000115{
116 bool __t = __x;
117 __x = __y;
118 __y = __t;
119}
120
Howard Hinnant99968442011-11-29 18:15:50 +0000121template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000122class __bit_const_reference
123{
Howard Hinnant99968442011-11-29 18:15:50 +0000124 typedef typename _Cp::__storage_type __storage_type;
125 typedef typename _Cp::__const_storage_pointer __storage_pointer;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000126
127 __storage_pointer __seg_;
128 __storage_type __mask_;
129
Howard Hinnant99968442011-11-29 18:15:50 +0000130 friend typename _Cp::__self;
Howard Hinnant99968442011-11-29 18:15:50 +0000131 friend class __bit_iterator<_Cp, true>;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000132public:
133 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000134 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000135 : __seg_(__x.__seg_), __mask_(__x.__mask_) {}
136
Howard Hinnant90d87232012-07-07 17:04:52 +0000137 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT
Howard Hinnant10f25d22011-05-27 20:52:28 +0000138 {return static_cast<bool>(*__seg_ & __mask_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000139
Howard Hinnant99968442011-11-29 18:15:50 +0000140 _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
141 {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000142private:
143 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant90d87232012-07-07 17:04:52 +0000144 _LIBCPP_CONSTEXPR
Howard Hinnant10f25d22011-05-27 20:52:28 +0000145 __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
146 : __seg_(__s), __mask_(__m) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000147
148 __bit_const_reference& operator=(const __bit_const_reference& __x);
149};
150
151// find
152
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000153template <class _Cp, bool _IsConst>
154__bit_iterator<_Cp, _IsConst>
155__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000156{
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000157 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000158 typedef typename _It::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000159 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160 // do first partial word
161 if (__first.__ctz_ != 0)
162 {
163 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000164 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000165 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
166 __storage_type __b = *__first.__seg_ & __m;
167 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000168 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant36ba3992013-08-07 20:42:16 +0000169 if (__n == __dn)
Marshall Clow6b5be702014-05-06 15:33:23 +0000170 return __first + __n;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000171 __n -= __dn;
172 ++__first.__seg_;
173 }
174 // do middle whole words
175 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
176 if (*__first.__seg_)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000177 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(*__first.__seg_)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000178 // do last partial word
179 if (__n > 0)
180 {
181 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
182 __storage_type __b = *__first.__seg_ & __m;
183 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000184 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000185 }
186 return _It(__first.__seg_, static_cast<unsigned>(__n));
187}
188
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000189template <class _Cp, bool _IsConst>
190__bit_iterator<_Cp, _IsConst>
191__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000192{
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000193 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000194 typedef typename _It::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000195 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000196 // do first partial word
197 if (__first.__ctz_ != 0)
198 {
199 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000200 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000201 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000202 __storage_type __b = ~*__first.__seg_ & __m;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000203 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000204 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnant36ba3992013-08-07 20:42:16 +0000205 if (__n == __dn)
Marshall Clow6b5be702014-05-06 15:33:23 +0000206 return __first + __n;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000207 __n -= __dn;
208 ++__first.__seg_;
209 }
210 // do middle whole words
211 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
212 {
213 __storage_type __b = ~*__first.__seg_;
214 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000215 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000216 }
217 // do last partial word
218 if (__n > 0)
219 {
220 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000221 __storage_type __b = ~*__first.__seg_ & __m;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000222 if (__b)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000223 return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000224 }
225 return _It(__first.__seg_, static_cast<unsigned>(__n));
226}
227
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000228template <class _Cp, bool _IsConst, class _Tp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000229inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000230__bit_iterator<_Cp, _IsConst>
231find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000232{
Howard Hinnant78b68282011-10-22 20:59:45 +0000233 if (static_cast<bool>(__value_))
Howard Hinnant99968442011-11-29 18:15:50 +0000234 return __find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
235 return __find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000236}
237
238// count
239
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000240template <class _Cp, bool _IsConst>
241typename __bit_iterator<_Cp, _IsConst>::difference_type
242__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000243{
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000244 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000245 typedef typename _It::__storage_type __storage_type;
246 typedef typename _It::difference_type difference_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000247 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000248 difference_type __r = 0;
249 // do first partial word
250 if (__first.__ctz_ != 0)
251 {
252 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000253 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000254 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Howard Hinnant0949eed2011-06-30 21:18:19 +0000255 __r = _VSTD::__pop_count(*__first.__seg_ & __m);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000256 __n -= __dn;
257 ++__first.__seg_;
258 }
259 // do middle whole words
260 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000261 __r += _VSTD::__pop_count(*__first.__seg_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000262 // do last partial word
263 if (__n > 0)
264 {
265 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000266 __r += _VSTD::__pop_count(*__first.__seg_ & __m);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000267 }
268 return __r;
269}
270
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000271template <class _Cp, bool _IsConst>
272typename __bit_iterator<_Cp, _IsConst>::difference_type
273__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000274{
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000275 typedef __bit_iterator<_Cp, _IsConst> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000276 typedef typename _It::__storage_type __storage_type;
277 typedef typename _It::difference_type difference_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000278 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000279 difference_type __r = 0;
280 // do first partial word
281 if (__first.__ctz_ != 0)
282 {
283 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000284 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000285 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000286 __r = _VSTD::__pop_count(~*__first.__seg_ & __m);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000287 __n -= __dn;
288 ++__first.__seg_;
289 }
290 // do middle whole words
291 for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000292 __r += _VSTD::__pop_count(~*__first.__seg_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000293 // do last partial word
294 if (__n > 0)
295 {
296 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000297 __r += _VSTD::__pop_count(~*__first.__seg_ & __m);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000298 }
299 return __r;
300}
301
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000302template <class _Cp, bool _IsConst, class _Tp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000303inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantffa7fbe2012-05-10 14:55:00 +0000304typename __bit_iterator<_Cp, _IsConst>::difference_type
305count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000306{
Howard Hinnant78b68282011-10-22 20:59:45 +0000307 if (static_cast<bool>(__value_))
Howard Hinnant99968442011-11-29 18:15:50 +0000308 return __count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
309 return __count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000310}
311
312// fill_n
313
Howard Hinnant99968442011-11-29 18:15:50 +0000314template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000315void
Howard Hinnant99968442011-11-29 18:15:50 +0000316__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000317{
Howard Hinnant99968442011-11-29 18:15:50 +0000318 typedef __bit_iterator<_Cp, false> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000319 typedef typename _It::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000320 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000321 // do first partial word
322 if (__first.__ctz_ != 0)
323 {
324 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000325 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000326 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
327 *__first.__seg_ &= ~__m;
328 __n -= __dn;
329 ++__first.__seg_;
330 }
331 // do middle whole words
332 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000333 _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000334 __n -= __nw * __bits_per_word;
335 // do last partial word
336 if (__n > 0)
337 {
338 __first.__seg_ += __nw;
339 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
340 *__first.__seg_ &= ~__m;
341 }
342}
343
Howard Hinnant99968442011-11-29 18:15:50 +0000344template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000345void
Howard Hinnant99968442011-11-29 18:15:50 +0000346__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000347{
Howard Hinnant99968442011-11-29 18:15:50 +0000348 typedef __bit_iterator<_Cp, false> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000349 typedef typename _It::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000350 const int __bits_per_word = _It::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000351 // do first partial word
352 if (__first.__ctz_ != 0)
353 {
354 __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000355 __storage_type __dn = _VSTD::min(__clz_f, __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000356 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
357 *__first.__seg_ |= __m;
358 __n -= __dn;
359 ++__first.__seg_;
360 }
361 // do middle whole words
362 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000363 _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000364 __n -= __nw * __bits_per_word;
365 // do last partial word
366 if (__n > 0)
367 {
368 __first.__seg_ += __nw;
369 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
370 *__first.__seg_ |= __m;
371 }
372}
373
Howard Hinnant99968442011-11-29 18:15:50 +0000374template <class _Cp>
Howard Hinnant1e564242013-10-04 22:09:00 +0000375inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000376void
Howard Hinnant99968442011-11-29 18:15:50 +0000377fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000378{
379 if (__n > 0)
380 {
Howard Hinnant78b68282011-10-22 20:59:45 +0000381 if (__value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000382 __fill_n_true(__first, __n);
383 else
384 __fill_n_false(__first, __n);
385 }
386}
387
388// fill
389
Howard Hinnant99968442011-11-29 18:15:50 +0000390template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000391inline _LIBCPP_INLINE_VISIBILITY
392void
Howard Hinnant99968442011-11-29 18:15:50 +0000393fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000394{
Howard Hinnant99968442011-11-29 18:15:50 +0000395 _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000396}
397
398// copy
399
Howard Hinnant99968442011-11-29 18:15:50 +0000400template <class _Cp, bool _IsConst>
401__bit_iterator<_Cp, false>
402__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
403 __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000404{
Howard Hinnant99968442011-11-29 18:15:50 +0000405 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000406 typedef typename _In::difference_type difference_type;
407 typedef typename _In::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000408 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000409 difference_type __n = __last - __first;
410 if (__n > 0)
411 {
412 // do first word
413 if (__first.__ctz_ != 0)
414 {
415 unsigned __clz = __bits_per_word - __first.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000416 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000417 __n -= __dn;
418 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
419 __storage_type __b = *__first.__seg_ & __m;
420 *__result.__seg_ &= ~__m;
421 *__result.__seg_ |= __b;
422 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
423 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
424 ++__first.__seg_;
425 // __first.__ctz_ = 0;
426 }
427 // __first.__ctz_ == 0;
428 // do middle words
429 __storage_type __nw = __n / __bits_per_word;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000430 _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
431 _VSTD::__to_raw_pointer(__first.__seg_),
432 __nw * sizeof(__storage_type));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000433 __n -= __nw * __bits_per_word;
434 __result.__seg_ += __nw;
435 // do last word
436 if (__n > 0)
437 {
438 __first.__seg_ += __nw;
439 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
440 __storage_type __b = *__first.__seg_ & __m;
441 *__result.__seg_ &= ~__m;
442 *__result.__seg_ |= __b;
443 __result.__ctz_ = static_cast<unsigned>(__n);
444 }
445 }
446 return __result;
447}
448
Howard Hinnant99968442011-11-29 18:15:50 +0000449template <class _Cp, bool _IsConst>
450__bit_iterator<_Cp, false>
451__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
452 __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000453{
Howard Hinnant99968442011-11-29 18:15:50 +0000454 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000455 typedef typename _In::difference_type difference_type;
456 typedef typename _In::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000457 static const int __bits_per_word = _In::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000458 difference_type __n = __last - __first;
459 if (__n > 0)
460 {
461 // do first word
462 if (__first.__ctz_ != 0)
463 {
464 unsigned __clz_f = __bits_per_word - __first.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000465 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000466 __n -= __dn;
467 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
468 __storage_type __b = *__first.__seg_ & __m;
469 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000470 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000471 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
472 *__result.__seg_ &= ~__m;
473 if (__result.__ctz_ > __first.__ctz_)
474 *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
475 else
476 *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
477 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
478 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
479 __dn -= __ddn;
480 if (__dn > 0)
481 {
482 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
483 *__result.__seg_ &= ~__m;
484 *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
485 __result.__ctz_ = static_cast<unsigned>(__dn);
486 }
487 ++__first.__seg_;
488 // __first.__ctz_ = 0;
489 }
490 // __first.__ctz_ == 0;
491 // do middle words
492 unsigned __clz_r = __bits_per_word - __result.__ctz_;
493 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
494 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
495 {
496 __storage_type __b = *__first.__seg_;
497 *__result.__seg_ &= ~__m;
498 *__result.__seg_ |= __b << __result.__ctz_;
499 ++__result.__seg_;
500 *__result.__seg_ &= __m;
501 *__result.__seg_ |= __b >> __clz_r;
502 }
503 // do last word
504 if (__n > 0)
505 {
506 __m = ~__storage_type(0) >> (__bits_per_word - __n);
507 __storage_type __b = *__first.__seg_ & __m;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000508 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000509 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
510 *__result.__seg_ &= ~__m;
511 *__result.__seg_ |= __b << __result.__ctz_;
512 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
513 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
514 __n -= __dn;
515 if (__n > 0)
516 {
517 __m = ~__storage_type(0) >> (__bits_per_word - __n);
518 *__result.__seg_ &= ~__m;
519 *__result.__seg_ |= __b >> __dn;
520 __result.__ctz_ = static_cast<unsigned>(__n);
521 }
522 }
523 }
524 return __result;
525}
526
Howard Hinnant99968442011-11-29 18:15:50 +0000527template <class _Cp, bool _IsConst>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000528inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000529__bit_iterator<_Cp, false>
530copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000531{
532 if (__first.__ctz_ == __result.__ctz_)
533 return __copy_aligned(__first, __last, __result);
534 return __copy_unaligned(__first, __last, __result);
535}
536
537// copy_backward
538
Howard Hinnant99968442011-11-29 18:15:50 +0000539template <class _Cp, bool _IsConst>
540__bit_iterator<_Cp, false>
541__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
542 __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000543{
Howard Hinnant99968442011-11-29 18:15:50 +0000544 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000545 typedef typename _In::difference_type difference_type;
546 typedef typename _In::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000547 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000548 difference_type __n = __last - __first;
549 if (__n > 0)
550 {
551 // do first word
552 if (__last.__ctz_ != 0)
553 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000554 difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000555 __n -= __dn;
556 unsigned __clz = __bits_per_word - __last.__ctz_;
557 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
558 __storage_type __b = *__last.__seg_ & __m;
559 *__result.__seg_ &= ~__m;
560 *__result.__seg_ |= __b;
561 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
562 __result.__ctz_) % __bits_per_word);
563 // __last.__ctz_ = 0
564 }
565 // __last.__ctz_ == 0 || __n == 0
566 // __result.__ctz_ == 0 || __n == 0
567 // do middle words
568 __storage_type __nw = __n / __bits_per_word;
569 __result.__seg_ -= __nw;
570 __last.__seg_ -= __nw;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000571 _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
572 _VSTD::__to_raw_pointer(__last.__seg_),
573 __nw * sizeof(__storage_type));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000574 __n -= __nw * __bits_per_word;
575 // do last word
576 if (__n > 0)
577 {
578 __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
579 __storage_type __b = *--__last.__seg_ & __m;
580 *--__result.__seg_ &= ~__m;
581 *__result.__seg_ |= __b;
582 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
583 }
584 }
585 return __result;
586}
587
Howard Hinnant99968442011-11-29 18:15:50 +0000588template <class _Cp, bool _IsConst>
589__bit_iterator<_Cp, false>
590__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
591 __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000592{
Howard Hinnant99968442011-11-29 18:15:50 +0000593 typedef __bit_iterator<_Cp, _IsConst> _In;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000594 typedef typename _In::difference_type difference_type;
595 typedef typename _In::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000596 const int __bits_per_word = _In::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000597 difference_type __n = __last - __first;
598 if (__n > 0)
599 {
600 // do first word
601 if (__last.__ctz_ != 0)
602 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000603 difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000604 __n -= __dn;
605 unsigned __clz_l = __bits_per_word - __last.__ctz_;
606 __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
607 __storage_type __b = *__last.__seg_ & __m;
608 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000609 __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000610 if (__ddn > 0)
611 {
612 __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
613 *__result.__seg_ &= ~__m;
614 if (__result.__ctz_ > __last.__ctz_)
615 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
616 else
617 *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
618 __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) +
619 __result.__ctz_) % __bits_per_word);
620 __dn -= __ddn;
621 }
622 if (__dn > 0)
623 {
624 // __result.__ctz_ == 0
625 --__result.__seg_;
626 __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
627 __m = ~__storage_type(0) << __result.__ctz_;
628 *__result.__seg_ &= ~__m;
629 __last.__ctz_ -= __dn + __ddn;
630 *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
631 }
632 // __last.__ctz_ = 0
633 }
634 // __last.__ctz_ == 0 || __n == 0
635 // __result.__ctz_ != 0 || __n == 0
636 // do middle words
637 unsigned __clz_r = __bits_per_word - __result.__ctz_;
638 __storage_type __m = ~__storage_type(0) >> __clz_r;
639 for (; __n >= __bits_per_word; __n -= __bits_per_word)
640 {
641 __storage_type __b = *--__last.__seg_;
642 *__result.__seg_ &= ~__m;
643 *__result.__seg_ |= __b >> __clz_r;
644 *--__result.__seg_ &= __m;
645 *__result.__seg_ |= __b << __result.__ctz_;
646 }
647 // do last word
648 if (__n > 0)
649 {
650 __m = ~__storage_type(0) << (__bits_per_word - __n);
651 __storage_type __b = *--__last.__seg_ & __m;
Howard Hinnantec3773c2011-12-01 20:21:04 +0000652 __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000653 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000654 __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
655 *__result.__seg_ &= ~__m;
656 *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
657 __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
658 __result.__ctz_) % __bits_per_word);
659 __n -= __dn;
660 if (__n > 0)
661 {
662 // __result.__ctz_ == 0
663 --__result.__seg_;
664 __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
665 __m = ~__storage_type(0) << __result.__ctz_;
666 *__result.__seg_ &= ~__m;
667 *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
668 }
669 }
670 }
671 return __result;
672}
673
Howard Hinnant99968442011-11-29 18:15:50 +0000674template <class _Cp, bool _IsConst>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000675inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000676__bit_iterator<_Cp, false>
677copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000678{
679 if (__last.__ctz_ == __result.__ctz_)
680 return __copy_backward_aligned(__first, __last, __result);
681 return __copy_backward_unaligned(__first, __last, __result);
682}
683
684// move
685
Howard Hinnant99968442011-11-29 18:15:50 +0000686template <class _Cp, bool _IsConst>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000687inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000688__bit_iterator<_Cp, false>
689move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000690{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000691 return _VSTD::copy(__first, __last, __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000692}
693
694// move_backward
695
Howard Hinnant99968442011-11-29 18:15:50 +0000696template <class _Cp, bool _IsConst>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000697inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000698__bit_iterator<_Cp, false>
699move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000700{
Marshall Clow0b16e8e2014-12-22 19:10:11 +0000701 return _VSTD::copy_backward(__first, __last, __result);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000702}
703
704// swap_ranges
705
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000706template <class __C1, class __C2>
707__bit_iterator<__C2, false>
708__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
709 __bit_iterator<__C2, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000710{
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000711 typedef __bit_iterator<__C1, false> _I1;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000712 typedef typename _I1::difference_type difference_type;
713 typedef typename _I1::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000714 const int __bits_per_word = _I1::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000715 difference_type __n = __last - __first;
716 if (__n > 0)
717 {
718 // do first word
719 if (__first.__ctz_ != 0)
720 {
721 unsigned __clz = __bits_per_word - __first.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000722 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000723 __n -= __dn;
724 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
725 __storage_type __b1 = *__first.__seg_ & __m;
726 *__first.__seg_ &= ~__m;
727 __storage_type __b2 = *__result.__seg_ & __m;
728 *__result.__seg_ &= ~__m;
729 *__result.__seg_ |= __b1;
730 *__first.__seg_ |= __b2;
731 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
732 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
733 ++__first.__seg_;
734 // __first.__ctz_ = 0;
735 }
736 // __first.__ctz_ == 0;
737 // do middle words
738 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
739 swap(*__first.__seg_, *__result.__seg_);
740 // do last word
741 if (__n > 0)
742 {
743 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
744 __storage_type __b1 = *__first.__seg_ & __m;
745 *__first.__seg_ &= ~__m;
746 __storage_type __b2 = *__result.__seg_ & __m;
747 *__result.__seg_ &= ~__m;
748 *__result.__seg_ |= __b1;
749 *__first.__seg_ |= __b2;
750 __result.__ctz_ = static_cast<unsigned>(__n);
751 }
752 }
753 return __result;
754}
755
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000756template <class __C1, class __C2>
757__bit_iterator<__C2, false>
758__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
759 __bit_iterator<__C2, false> __result)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000760{
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000761 typedef __bit_iterator<__C1, false> _I1;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000762 typedef typename _I1::difference_type difference_type;
763 typedef typename _I1::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000764 const int __bits_per_word = _I1::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000765 difference_type __n = __last - __first;
766 if (__n > 0)
767 {
768 // do first word
769 if (__first.__ctz_ != 0)
770 {
771 unsigned __clz_f = __bits_per_word - __first.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000772 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000773 __n -= __dn;
774 __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
775 __storage_type __b1 = *__first.__seg_ & __m;
776 *__first.__seg_ &= ~__m;
777 unsigned __clz_r = __bits_per_word - __result.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000778 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000779 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
780 __storage_type __b2 = *__result.__seg_ & __m;
781 *__result.__seg_ &= ~__m;
782 if (__result.__ctz_ > __first.__ctz_)
783 {
784 unsigned __s = __result.__ctz_ - __first.__ctz_;
785 *__result.__seg_ |= __b1 << __s;
786 *__first.__seg_ |= __b2 >> __s;
787 }
788 else
789 {
790 unsigned __s = __first.__ctz_ - __result.__ctz_;
791 *__result.__seg_ |= __b1 >> __s;
792 *__first.__seg_ |= __b2 << __s;
793 }
794 __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
795 __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word);
796 __dn -= __ddn;
797 if (__dn > 0)
798 {
799 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
800 __b2 = *__result.__seg_ & __m;
801 *__result.__seg_ &= ~__m;
802 unsigned __s = __first.__ctz_ + __ddn;
803 *__result.__seg_ |= __b1 >> __s;
804 *__first.__seg_ |= __b2 << __s;
805 __result.__ctz_ = static_cast<unsigned>(__dn);
806 }
807 ++__first.__seg_;
808 // __first.__ctz_ = 0;
809 }
810 // __first.__ctz_ == 0;
811 // do middle words
812 __storage_type __m = ~__storage_type(0) << __result.__ctz_;
813 unsigned __clz_r = __bits_per_word - __result.__ctz_;
814 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
815 {
816 __storage_type __b1 = *__first.__seg_;
817 __storage_type __b2 = *__result.__seg_ & __m;
818 *__result.__seg_ &= ~__m;
819 *__result.__seg_ |= __b1 << __result.__ctz_;
820 *__first.__seg_ = __b2 >> __result.__ctz_;
821 ++__result.__seg_;
822 __b2 = *__result.__seg_ & ~__m;
823 *__result.__seg_ &= __m;
824 *__result.__seg_ |= __b1 >> __clz_r;
825 *__first.__seg_ |= __b2 << __clz_r;
826 }
827 // do last word
828 if (__n > 0)
829 {
830 __m = ~__storage_type(0) >> (__bits_per_word - __n);
831 __storage_type __b1 = *__first.__seg_ & __m;
832 *__first.__seg_ &= ~__m;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000833 __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000834 __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
835 __storage_type __b2 = *__result.__seg_ & __m;
836 *__result.__seg_ &= ~__m;
837 *__result.__seg_ |= __b1 << __result.__ctz_;
838 *__first.__seg_ |= __b2 >> __result.__ctz_;
839 __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
840 __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word);
841 __n -= __dn;
842 if (__n > 0)
843 {
844 __m = ~__storage_type(0) >> (__bits_per_word - __n);
845 __b2 = *__result.__seg_ & __m;
846 *__result.__seg_ &= ~__m;
847 *__result.__seg_ |= __b1 >> __dn;
848 *__first.__seg_ |= __b2 << __dn;
849 __result.__ctz_ = static_cast<unsigned>(__n);
850 }
851 }
852 }
853 return __result;
854}
855
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000856template <class __C1, class __C2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000857inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6cd05ee2011-09-23 16:11:27 +0000858__bit_iterator<__C2, false>
859swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
860 __bit_iterator<__C2, false> __first2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000861{
862 if (__first1.__ctz_ == __first2.__ctz_)
863 return __swap_ranges_aligned(__first1, __last1, __first2);
864 return __swap_ranges_unaligned(__first1, __last1, __first2);
865}
866
867// rotate
868
Howard Hinnant99968442011-11-29 18:15:50 +0000869template <class _Cp>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000870struct __bit_array
871{
Howard Hinnant99968442011-11-29 18:15:50 +0000872 typedef typename _Cp::difference_type difference_type;
873 typedef typename _Cp::__storage_type __storage_type;
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000874 typedef typename _Cp::__storage_pointer __storage_pointer;
Howard Hinnant99968442011-11-29 18:15:50 +0000875 typedef typename _Cp::iterator iterator;
876 static const unsigned __bits_per_word = _Cp::__bits_per_word;
877 static const unsigned _Np = 4;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000878
879 difference_type __size_;
Howard Hinnant99968442011-11-29 18:15:50 +0000880 __storage_type __word_[_Np];
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000881
882 _LIBCPP_INLINE_VISIBILITY static difference_type capacity()
Howard Hinnant99968442011-11-29 18:15:50 +0000883 {return static_cast<difference_type>(_Np * __bits_per_word);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000884 _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
Howard Hinnant2c39cbe2013-06-27 19:35:32 +0000885 _LIBCPP_INLINE_VISIBILITY iterator begin()
886 {
887 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
888 }
889 _LIBCPP_INLINE_VISIBILITY iterator end()
890 {
891 return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
892 static_cast<unsigned>(__size_ % __bits_per_word));
893 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000894};
895
Howard Hinnant99968442011-11-29 18:15:50 +0000896template <class _Cp>
897__bit_iterator<_Cp, false>
898rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000899{
Howard Hinnant99968442011-11-29 18:15:50 +0000900 typedef __bit_iterator<_Cp, false> _I1;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000901 typedef typename _I1::difference_type difference_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000902 difference_type __d1 = __middle - __first;
903 difference_type __d2 = __last - __middle;
904 _I1 __r = __first + __d2;
905 while (__d1 != 0 && __d2 != 0)
906 {
907 if (__d1 <= __d2)
908 {
Howard Hinnant99968442011-11-29 18:15:50 +0000909 if (__d1 <= __bit_array<_Cp>::capacity())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000910 {
Howard Hinnant99968442011-11-29 18:15:50 +0000911 __bit_array<_Cp> __b(__d1);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000912 _VSTD::copy(__first, __middle, __b.begin());
913 _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000914 break;
915 }
916 else
917 {
Howard Hinnant99968442011-11-29 18:15:50 +0000918 __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000919 __first = __middle;
920 __middle = __mp;
921 __d2 -= __d1;
922 }
923 }
924 else
925 {
Howard Hinnant99968442011-11-29 18:15:50 +0000926 if (__d2 <= __bit_array<_Cp>::capacity())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000927 {
Howard Hinnant99968442011-11-29 18:15:50 +0000928 __bit_array<_Cp> __b(__d2);
Howard Hinnant0949eed2011-06-30 21:18:19 +0000929 _VSTD::copy(__middle, __last, __b.begin());
930 _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000931 break;
932 }
933 else
934 {
Howard Hinnant99968442011-11-29 18:15:50 +0000935 __bit_iterator<_Cp, false> __mp = __first + __d2;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000936 _VSTD::swap_ranges(__first, __mp, __middle);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000937 __first = __mp;
938 __d1 -= __d2;
939 }
940 }
941 }
942 return __r;
943}
944
945// equal
946
Howard Hinnant584db422012-08-05 21:43:11 +0000947template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000948bool
Howard Hinnant584db422012-08-05 21:43:11 +0000949__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
950 __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000951{
Howard Hinnant584db422012-08-05 21:43:11 +0000952 typedef __bit_iterator<_Cp, _IC1> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000953 typedef typename _It::difference_type difference_type;
954 typedef typename _It::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +0000955 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000956 difference_type __n = __last1 - __first1;
957 if (__n > 0)
958 {
959 // do first word
960 if (__first1.__ctz_ != 0)
961 {
962 unsigned __clz_f = __bits_per_word - __first1.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000963 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000964 __n -= __dn;
965 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
966 __storage_type __b = *__first1.__seg_ & __m;
967 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +0000968 __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000969 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
970 if (__first2.__ctz_ > __first1.__ctz_)
Howard Hinnantdbd9eac2012-05-31 23:12:03 +0000971 {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000972 if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
973 return false;
Howard Hinnantdbd9eac2012-05-31 23:12:03 +0000974 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000975 else
Howard Hinnantdbd9eac2012-05-31 23:12:03 +0000976 {
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000977 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
978 return false;
Howard Hinnantdbd9eac2012-05-31 23:12:03 +0000979 }
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000980 __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
981 __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word);
982 __dn -= __ddn;
983 if (__dn > 0)
984 {
985 __m = ~__storage_type(0) >> (__bits_per_word - __dn);
986 if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
987 return false;
988 __first2.__ctz_ = static_cast<unsigned>(__dn);
989 }
990 ++__first1.__seg_;
991 // __first1.__ctz_ = 0;
992 }
993 // __first1.__ctz_ == 0;
994 // do middle words
995 unsigned __clz_r = __bits_per_word - __first2.__ctz_;
996 __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
997 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_)
998 {
999 __storage_type __b = *__first1.__seg_;
1000 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
1001 return false;
1002 ++__first2.__seg_;
1003 if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
1004 return false;
1005 }
1006 // do last word
1007 if (__n > 0)
1008 {
1009 __m = ~__storage_type(0) >> (__bits_per_word - __n);
1010 __storage_type __b = *__first1.__seg_ & __m;
Howard Hinnant0949eed2011-06-30 21:18:19 +00001011 __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001012 __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
1013 if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
1014 return false;
1015 __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
1016 __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word);
1017 __n -= __dn;
1018 if (__n > 0)
1019 {
1020 __m = ~__storage_type(0) >> (__bits_per_word - __n);
1021 if ((*__first2.__seg_ & __m) != (__b >> __dn))
1022 return false;
1023 }
1024 }
1025 }
1026 return true;
1027}
1028
Howard Hinnant584db422012-08-05 21:43:11 +00001029template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001030bool
Howard Hinnant584db422012-08-05 21:43:11 +00001031__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
1032 __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001033{
Howard Hinnant584db422012-08-05 21:43:11 +00001034 typedef __bit_iterator<_Cp, _IC1> _It;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001035 typedef typename _It::difference_type difference_type;
1036 typedef typename _It::__storage_type __storage_type;
Eric Fiselier50f65792016-12-24 00:24:44 +00001037 static const int __bits_per_word = _It::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001038 difference_type __n = __last1 - __first1;
1039 if (__n > 0)
1040 {
1041 // do first word
1042 if (__first1.__ctz_ != 0)
1043 {
1044 unsigned __clz = __bits_per_word - __first1.__ctz_;
Howard Hinnant0949eed2011-06-30 21:18:19 +00001045 difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001046 __n -= __dn;
1047 __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
1048 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
1049 return false;
1050 ++__first2.__seg_;
1051 ++__first1.__seg_;
1052 // __first1.__ctz_ = 0;
1053 // __first2.__ctz_ = 0;
1054 }
1055 // __first1.__ctz_ == 0;
1056 // __first2.__ctz_ == 0;
1057 // do middle words
1058 for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
1059 if (*__first2.__seg_ != *__first1.__seg_)
1060 return false;
1061 // do last word
1062 if (__n > 0)
1063 {
1064 __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
1065 if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
1066 return false;
1067 }
1068 }
1069 return true;
1070}
1071
Howard Hinnant99968442011-11-29 18:15:50 +00001072template <class _Cp, bool _IC1, bool _IC2>
Howard Hinnant99acc502010-09-21 17:32:39 +00001073inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001074bool
Howard Hinnant99968442011-11-29 18:15:50 +00001075equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001076{
1077 if (__first1.__ctz_ == __first2.__ctz_)
1078 return __equal_aligned(__first1, __last1, __first2);
1079 return __equal_unaligned(__first1, __last1, __first2);
1080}
1081
Howard Hinnantf867f632012-05-07 16:50:38 +00001082template <class _Cp, bool _IsConst,
1083 typename _Cp::__storage_type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001084class __bit_iterator
1085{
1086public:
Howard Hinnant99968442011-11-29 18:15:50 +00001087 typedef typename _Cp::difference_type difference_type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001088 typedef bool value_type;
1089 typedef __bit_iterator pointer;
Howard Hinnant99968442011-11-29 18:15:50 +00001090 typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001091 typedef random_access_iterator_tag iterator_category;
1092
1093private:
Howard Hinnant99968442011-11-29 18:15:50 +00001094 typedef typename _Cp::__storage_type __storage_type;
1095 typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer,
1096 typename _Cp::__storage_pointer>::type __storage_pointer;
1097 static const unsigned __bits_per_word = _Cp::__bits_per_word;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001098
1099 __storage_pointer __seg_;
1100 unsigned __ctz_;
1101
1102public:
Marshall Clowb92ee612013-08-07 20:53:44 +00001103 _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
1104#if _LIBCPP_STD_VER > 11
1105 : __seg_(nullptr), __ctz_(0)
1106#endif
1107 {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001108
Howard Hinnant10f25d22011-05-27 20:52:28 +00001109 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +00001110 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001111 : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
1112
Howard Hinnant10f25d22011-05-27 20:52:28 +00001113 _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
1114 {return reference(__seg_, __storage_type(1) << __ctz_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001115
1116 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()
1117 {
1118 if (__ctz_ != __bits_per_word-1)
1119 ++__ctz_;
1120 else
1121 {
1122 __ctz_ = 0;
1123 ++__seg_;
1124 }
1125 return *this;
1126 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001127
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001128 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int)
1129 {
1130 __bit_iterator __tmp = *this;
1131 ++(*this);
1132 return __tmp;
1133 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001134
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001135 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--()
1136 {
1137 if (__ctz_ != 0)
1138 --__ctz_;
1139 else
1140 {
1141 __ctz_ = __bits_per_word - 1;
1142 --__seg_;
1143 }
1144 return *this;
1145 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001146
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001147 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int)
1148 {
1149 __bit_iterator __tmp = *this;
1150 --(*this);
1151 return __tmp;
1152 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001153
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001154 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n)
1155 {
1156 if (__n >= 0)
1157 __seg_ += (__n + __ctz_) / __bits_per_word;
1158 else
1159 __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1)
1160 / static_cast<difference_type>(__bits_per_word);
1161 __n &= (__bits_per_word - 1);
1162 __ctz_ = static_cast<unsigned>((__n + __ctz_) % __bits_per_word);
1163 return *this;
1164 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001165
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001166 _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n)
1167 {
1168 return *this += -__n;
1169 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001170
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001171 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const
1172 {
1173 __bit_iterator __t(*this);
1174 __t += __n;
1175 return __t;
1176 }
Howard Hinnant324bb032010-08-22 00:02:43 +00001177
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001178 _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const
1179 {
1180 __bit_iterator __t(*this);
1181 __t -= __n;
1182 return __t;
1183 }
1184
1185 _LIBCPP_INLINE_VISIBILITY
1186 friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}
1187
1188 _LIBCPP_INLINE_VISIBILITY
1189 friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)
1190 {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}
1191
1192 _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);}
1193
1194 _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
1195 {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}
1196
1197 _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
1198 {return !(__x == __y);}
1199
1200 _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
1201 {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}
1202
1203 _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
1204 {return __y < __x;}
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 !(__x < __y);}
1211
1212private:
1213 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant10f25d22011-05-27 20:52:28 +00001214 __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
1215 : __seg_(__s), __ctz_(__ctz) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001216
Howard Hinnant99968442011-11-29 18:15:50 +00001217 friend typename _Cp::__self;
Eric Fiselier5170d7d2017-01-06 21:42:58 +00001218
Howard Hinnant99968442011-11-29 18:15:50 +00001219 friend class __bit_reference<_Cp>;
1220 friend class __bit_const_reference<_Cp>;
1221 friend class __bit_iterator<_Cp, true>;
1222 template <class _Dp> friend struct __bit_array;
1223 template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1224 template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
1225 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
1226 __bit_iterator<_Dp, _IC> __last,
1227 __bit_iterator<_Dp, false> __result);
1228 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__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(__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_backward_aligned(__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_unaligned(__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(__bit_iterator<_Dp, _IC> __first,
1241 __bit_iterator<_Dp, _IC> __last,
1242 __bit_iterator<_Dp, false> __result);
Howard Hinnant6cd05ee2011-09-23 16:11:27 +00001243 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
1244 __bit_iterator<__C1, false>,
1245 __bit_iterator<__C2, false>);
1246 template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__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(__bit_iterator<__C1, false>,
1250 __bit_iterator<__C1, false>,
1251 __bit_iterator<__C2, false>);
Howard Hinnant99968442011-11-29 18:15:50 +00001252 template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
1253 __bit_iterator<_Dp, false>,
1254 __bit_iterator<_Dp, false>);
Howard Hinnant584db422012-08-05 21:43:11 +00001255 template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
1256 __bit_iterator<_Dp, _IC1>,
1257 __bit_iterator<_Dp, _IC2>);
1258 template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
1259 __bit_iterator<_Dp, _IC1>,
1260 __bit_iterator<_Dp, _IC2>);
Howard Hinnant99968442011-11-29 18:15:50 +00001261 template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>,
1262 __bit_iterator<_Dp, _IC1>,
1263 __bit_iterator<_Dp, _IC2>);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +00001264 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>,
Howard Hinnant99968442011-11-29 18:15:50 +00001265 typename _Dp::size_type);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +00001266 template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>,
Howard Hinnant99968442011-11-29 18:15:50 +00001267 typename _Dp::size_type);
Howard Hinnantffa7fbe2012-05-10 14:55:00 +00001268 template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1269 __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
1270 template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
1271 __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001272};
1273
1274_LIBCPP_END_NAMESPACE_STD
1275
1276#endif // _LIBCPP___BIT_REFERENCE